← 미리디 아카이브

내용시각화 역할 분담 2026-08-26 코드 실측

web-2 역할 분담 — 서버 vs 브라우저 엔진

경계선은 하나다. 검색·매칭·생성은 서버, 레이아웃·대치·노드편집은 브라우저. 서버는 완성된 화면을 주지 않고 componentKey 와 시그니처 파일 URL만 돌려준다 — 큰 컬럼은 브라우저가 따로 받아 온다.

miricanvas-web-2 engine + legacy MORDOR 계열 API miricanvas-iui 순수 계산
§1

브라우저가 하는 일

사용자 입력에서 시작해 해시를 만들고, 검색을 오케스트레이션하고, 돌아온 후보로 대치와 auto-layout 을 직접 수행한 뒤 노드트리에 커밋한다. 계산은 전부 브라우저 안에서 끝난다.

사용자 입력
좌측 패널 텍스트
1comp-sign 해시 생성
textTree → hash + capacity
검색 오케스트레이션 · 랭킹
TextVisualizationService · _core/searchParallel.ts (RxJS forkJoin)
색상 · 내용 · 이미지 대치 + auto-layout
buildMappedComponentSheetJson.ts
SmartBlock …LayoutWithChildrenStrategy · DimensionPolicy
Page 빌드 → 썸네일 → 노드트리 커밋
ComponentItemReplaceCommand
IUI 계산 코어 (npm 패키지로 소비)
@miri-unicorn/miricanvas-iui-comp-sign
@miri-unicorn/miricanvas-iui-color-mapper
= miricanvas-iui 레포 (순수 계산 · DB 참조 없음)
브라우저 코드는 두 곳에 나뉘어 있다 — 검색·오케스트레이션은 miricanvas-legacy, 대치·노드 조작은 engine/editor.

검색 오케스트레이션의 실체

visualizationParts병렬 hybridSearch 로 태우고 로깅 부수효과를 합성한다. 77줄짜리 얇은 헬퍼이고, 실제 스트림은 _core/streams.ts 가 만든다.

병렬 검색 + 로그 합성 _core/searchParallel.ts
import { forkJoin, map, type Observable, tap } from 'rxjs';

/**
 * `visualizationParts` 의 병렬 hybridSearch + 각 part 결과에 대한
 * `Logger.logSummary` / `Logger.setDebugMetadata` 부수효과 합성.
 * `visualizeFromText` / `revisualize` 처럼 정상 진입점이 공유하는 패턴이라 추출.
 */
export const createSearchParallelWithLog$ = (...)
§2

서버가 하는 일 — API prefix 로 서비스가 갈린다

MORDOR 계열 엔드포인트들. prefix 만 봐도 어느 서비스 소관인지 구분된다. 아래 경로는 miricanvas-api-kit 의 route 정의에서 그대로 확인한 값이다.

엔드포인트하는 일route 정의
POST /template/api/v1/ai/text-visualization/generate 서머리 · 시멘틱쿼리 생성 PostTextVisualizationGenerateV1
POST /template/api/components/signatures/search 핵심 시그니처 후보 검색 · 매칭 (해시는 서버) PostComponentsSignatureSearch
GET /template/api/ai/presentation/component/smart-blocks smartblock 검색 getComponentAIPresentationSmartBlocks
POST /template/api/components/recallsearch Recall Search V2 — hybrid · embedding PostComponentsRecallSearch
POST /process/api/ai/chat/{serviceName} 스트리밍 아웃라인 에이전트 (application/ndjson) StartAiChatStream
/worker/api/aigeneration/* aippt 이미지 생성 · 이력 · 피드백 (비동기 워커) ai-presentation/* (다수)
POST /template/api/templates/style-metadata/query/bulk 템플릿 스타일 메타데이터 → styleMetadataFileUrl GetTemplateStyleMetadata

{storyline} 은 경로 이름이 아니다

route 정의의 path 파라미터는 {serviceName} 이고, storyline 은 그 예시 값이다 (serviceName.openapi({ example: 'storyline' })). 원본 도식의 /process/api/ai/chat/{storyline} 표기는 이 점에서 오해를 부른다.

§3

경계에서 실제로 오가는 것

"서버는 후보키 + 시그니처 파일만 반환한다"는 이 어댑터 한 곳에서 확인된다. 응답에는 URL 만 있고, textMap · textNodeRoles 는 브라우저가 따로 fetch 한다.

서버 응답 → 내부 후보 어댑터 _core/compSignSearch.ts:14
/**
 * comp-sign 검색 파이프라인의 서버 단계(POST /template/api/components/signatures/search)
 * 어댑터. 백엔드 응답을 파이프라인이 쓰는 내부 형태로 변환하고,
 * 대용량 컬럼(text_map·text_node_roles)의 파일 URL 을 fetch 한다.
 * 응답 스키마가 바뀌면 adaptSearchResponse 만 고치면 뒤쪽(랭킹·대치)은 영향 없다.
 */
2질의
structureHash + capacity
서버
시그니처 후보 검색 · 매칭
3후보키 + 파일 URL
componentKey · textMapUrl · textNodeRolesUrl · scoreFeatures
브라우저가 파일 fetch
resolveCandidates()
대용량 컬럼을 응답 본문에 싣지 않는 것이 이 설계의 요점이다 — 랭킹은 scoreFeatures 로 먼저 하고, 실제 파일은 고른 후보만 받는다.
§4

코드 지도

miricanvas-web-2

파일패키지
검색 진입·오케스트레이션TextVisualizationService.tsmiricanvas-legacy
병렬 검색_core/searchParallel.tsmiricanvas-legacy
서버 응답 어댑터_core/compSignSearch.tsmiricanvas-legacy
대치 4단계buildMappedComponentSheetJson.ts:108engine/editor
대치 커맨드CmdReplaceComponentBySignature…ts:95engine/editor
캔버스 반영ComponentItemReplaceCommand.tsengine/editor
SmartBlock auto-layoutAbstractSmartBlockLayoutWithChildrenStrategy.tsengine/editor
API route 정의miricanvas-api-kit/src/endpoints/api/miricanvas-api-kit

miricanvas-iui — npm 패키지로 소비되는 순수 계산

패키지무엇web-2 에서 쓰는 곳
comp-sign해시 · 랭킹 · 대치 페이로드 · 공간 정돈검색 파이프라인 전 구간
color-mapperrecolorComponent · buildColorProfileTemplateStyleMapper
theme-registryThemeRegistry 타입 · AIP 테마 경로style_replacement/colorMapping.ts

iui 는 DB 를 참조하지 않는다 — 외곽선 같은 데이터가 필요하면 호출자가 조회해 넘긴다 (build-replacement.tsvt2 옵션 주석).

aippt-prisonbreak

런타임 경로에는 없다. 검색의 재료인 시그니처와 RLSC 를 오프라인에서 만드는 쪽이라, "후보가 왜 이것뿐인가"를 거슬러 올라갈 때 보는 저장소다 (Eregion 전체 아키텍처).

§5

핵심 분담

서버

서머리 생성 · 시그니처/시멘틱 검색 · 해시 매칭 · aippt 생성. 결과는 componentKey + 시그니처 파일 URL만.

브라우저 엔진

comp-sign 해시·랭킹 · 색상/내용/이미지 대치 · SmartBlock auto-layout · Page 빌드 / 노드트리 커밋.

렌더러는 양쪽 어디에도 없다

텍스트 흘리기 · 폰트 오토핏 · 재레이아웃은 preview iframe 안의 렌더러가 한다. 끄는 레버는 shrinkConfigs 하나뿐이고 줄바꿈·재레이아웃은 그래도 일어난다 — 이것이 정렬 문제의 배경이다.