/** /benchmark 보고서의 3 파트 분할 — 1: 4-렌즈 / 2: IA + 토큰 / 3: 재구축 명세. */ export type SynthesisPart = 1 | 2 | 3; /** * scan JSON → 4-렌즈 분석 LLM 프롬프트. Datacollect 웹앱(WebBenchmarkPanel)의 * buildSynthesisPrompt를 그대로 이식 — /benchmark 결과가 웹앱과 동등하게 나오도록. */ export function buildSynthesisPrompt(scan: any, userContent: string, part: SynthesisPart): string { // 4-렌즈 분석에 필요한 핵심 데이터만 추려 LLM 입력을 가볍게. const slim = { url: scan?.url, title: scan?.meta?.title, description: scan?.meta?.description, lang: scan?.meta?.lang, // §1. 비주얼 아이덴티티 — 컬러 비율 + 다크모드 + 타이포 위계 colors: { palette: scan?.design?.colors?.palette?.slice(0, 8), composition: scan?.design?.colors?.composition, background: scan?.design?.colors?.background, primaryText: scan?.design?.colors?.primaryText, linkColor: scan?.design?.colors?.linkColor, buttonBackground: scan?.design?.colors?.buttonBackground, buttonText: scan?.design?.colors?.buttonText, darkModeHints: scan?.design?.colors?.darkModeHints, }, typography: { primaryFont: scan?.design?.typography?.primaryFont, fontStack: scan?.design?.typography?.fontStack?.slice(0, 3), topFontSizes: scan?.design?.typography?.topFontSizes?.slice(0, 6), topFontWeights: scan?.design?.typography?.topFontWeights?.slice(0, 5), body: scan?.design?.typography?.body, h1: scan?.design?.typography?.h1, h2: scan?.design?.typography?.h2, h3: scan?.design?.typography?.h3, button: scan?.design?.typography?.button, }, // §2. 레이아웃 & 공간감 — 여백 / 그리드 layout: { viewport: { w: scan?.design?.layout?.viewportWidth, h: scan?.design?.layout?.viewportHeight }, bodyMaxWidth: scan?.design?.layout?.bodyMaxWidth, sectionSpacing: scan?.design?.layout?.sectionSpacing, cardSpacing: scan?.design?.layout?.cardSpacing, borderRadiusScale: scan?.design?.layout?.borderRadiusScale, grids: scan?.design?.layout?.grids, containerSystem: scan?.design?.layout?.containerSystem, responsiveHints: scan?.design?.layout?.responsiveHints, layering: scan?.design?.layout?.layering, }, components: scan?.design?.components, mediaTreatment: scan?.design?.mediaTreatment, surfaceTreatment: scan?.design?.surfaceTreatment, // §3. 마이크로 인터랙션 — Hover / Transition interactions: { hoverRules: scan?.interactions?.hoverRules?.slice(0, 6), focusRules: scan?.interactions?.focusRules?.slice(0, 3), transitionDistribution: scan?.interactions?.transitionDistribution, cssVars: scan?.interactions?.cssVars, }, // §4. 라이팅 톤앤매너 — 마이크로카피 microcopy: { headline: scan?.microcopy?.headline, subheadline: scan?.microcopy?.subheadline, subheadlines: scan?.microcopy?.subheadlines?.slice(0, 6), ctaSamples: scan?.microcopy?.ctaSamples?.slice(0, 10), placeholders: scan?.microcopy?.placeholders, stateMessages: scan?.microcopy?.stateMessages, ariaLabels: scan?.microcopy?.ariaLabels?.slice(0, 6), bodySample: scan?.microcopy?.bodySample, voiceSignals: scan?.microcopy?.voiceSignals, }, // 구조 요약 — 역기획서 매칭을 위한 보조 정보 structure: { sections: scan?.structure?.sections?.slice(0, 10).map((s: any) => ({ role: s.role, depth: s.depth, text: s.textPreview?.slice(0, 100), btns: s.buttonCount, links: s.linkCount, imgs: s.imgCount, })), h1: scan?.structure?.h1, h2List: scan?.structure?.h2List?.slice(0, 6), navigationLinks: scan?.structure?.navigationLinks?.slice(0, 10), }, iconography: scan?.design?.iconography, // §5. 사이트맵 — 준비할 리소스 추정의 근거 (페이지별 역할 + 자산 수). sitemap: scan?.sitemap ? { totalPages: scan.sitemap.totalPages, crawlDepth: scan.sitemap.crawlDepth, asciiTree: scan.sitemap.ascii, pages: scan.sitemap.pages?.map((p: any) => ({ url: p.url, role: p.role, title: p.title?.slice(0, 80), h1: p.h1?.slice(0, 80), h2List: p.h2List?.slice(0, 5), contentType: p.primaryContentType, imageCount: p.imageCount, videoCount: p.videoCount, formFields: p.formFields?.slice(0, 6).map((f: any) => ({ name: f.name || f.label, type: f.type, required: f.required, })), ctas: p.ctaSamples?.slice(0, 4), sections: p.sectionRoles?.slice(0, 8).map((s: any) => ({ tag: s.tag, hint: s.hint, preview: (s.preview || '').slice(0, 50), })), error: p.error, })), } : null, }; const today = new Date().toISOString().slice(0, 10); const title = slim.title || 'Reference Site'; const userBlock = userContent.trim() ? userContent.trim() : '(미입력 — 원본 사이트 자체의 재현에만 집중)'; const sharedRules = ` [분석 원칙] 1. 이 보고서의 미션은 "원본 레퍼런스 사이트를 가능한 한 닮은 사이트를 처음부터 다시 만들기 위한 명세"를 작성하는 것이다. 2. 추측이나 일반론은 금지. 모든 진술은 제공된 JSON 스캔 데이터의 구체적 수치/문자열을 근거로 인용한다. 3. JSON에 없는 정보를 지어내지 말 것. 데이터에 없는 항목은 "스캔 데이터 부족"이라고 명시한다. 4. 한국어로 작성한다. 5. 모든 색상/폰트/여백/Radius는 정확한 값(rgb/px)을 그대로 인용한다.`; const commonHeader = ` # ${title} 레퍼런스 사이트 재구축 명세 > **레퍼런스 URL**: ${slim.url} > **분석 일자**: ${today} > **분석 관점**: 4-렌즈 (Visual / Layout / Interaction / Voice) + IA 및 페이지 템플릿 + 재구축 명세 > **스캔된 페이지**: ${slim.sitemap?.totalPages ?? 1}개 (crawlDepth: ${slim.sitemap?.crawlDepth ?? 0})`; const partTemplate = part === 1 ? ` ${commonHeader} ## 한 줄 요약 (One-line Impression) ## 1. 시각적 정체성 (Visual Identity) ### 1-1. 컬러 팔레트 (Color Palette) ### 1-2. 타이포그래피 (Typography) ## 2. 레이아웃 및 여백 (Layout & Whitespace) ### 2-1. 그리드 시스템 (Grid System) ### 2-2. 섹션 간 여백 (Section Spacing) ### 2-3. 카드/카드 그리드 (Card Spacing) ### 2-4. Border Radius / 컨테이너 ## 3. 마이크로 인터랙션 (Micro Interaction) ### 3-1. Hover / Focus 효과 ### 3-2. Transition 패턴 ### 3-3. 레이어링 (z-index / position) ## 4. 라이팅 톤앤매너 (Microcopy & Voice) ### 4-1. 헤드라인 / 서브헤드라인 / CTA 카피 ### 4-2. Placeholder 및 보이스 신호` : part === 2 ? ` ## 5. 정보 구조 / 사이트 맵 (Information Architecture) ### 5-1. 사이트 트리 다이어그램 (Page Tree) - \`sitemap.asciiTree\`를 코드블록으로 그대로 옮겨 적을 것. ### 5-2. 페이지 목록 (Flat View) ### 5-3. 페이지별 구성 요약 (Page Composition) ### 5-4. IA 특징 정리 ### 5-5. 재구축용 컴포넌트 명세 (Component Reconstruction Spec) ### 5-6. 미디어 처리 (Media Treatment) ## 6. 준비해야 할 리소스 (Resources You Need to Prepare) ### 6-1. 페이지별 이미지/비디오 수 ### 6-2. 카피라이팅 분량 ### 6-3. 폼/입력 필드 목록 ## 7. 디자인 토큰 (Design Tokens) - Color / Typography / Spacing / Radius / Border / Shadow / Motion 각각 표로 정리. ## 8. 페이지 템플릿 맵 (Page Template Map) 스캔된 페이지들의 \`primaryContentType\` + \`sectionRoles\` + \`h2List\`를 묶어 **반복되는 템플릿 유형**을 도출하고, 반드시 아래 표 형식으로 작성하라. **반드시 마크다운 표 문법을 쓸 것** (글머리표·산문 금지). 템플릿은 최소 3개 이상 도출하되, 페이지가 모두 다르면 그만큼만 작성. | 템플릿 ID | 적용 URL | 공통 블록 순서 (위 → 아래) | 페이지별 차이점 | 재사용 컴포넌트 | |---|---|---|---|---| | T1: Gallery Landing | / | Header → Hero(작품 1장) → 작품 그리드(3열) → Footer | (없음 / 단독 페이지) | Header, ImageCard, Footer | | T2: Category List | /shop, /paintings | Header → 카테고리 타이틀(h1) → 작품 그리드(2열) → Pagination → Footer | 카테고리명·작품 수 다름 | Header, ImageCard, Footer, Pagination | | T3: Detail | /shop/oil-painting/limited-editions | Header → Breadcrumb → 작품 이미지(좌) + 메타·CTA(우) → 관련 작품 → Footer | 상품별 이미지·가격·CTA 문구 다름 | Header, BreadcrumbBar, BuyButton, RelatedGrid, Footer | 작성 규칙: - **템플릿 ID**: \`T1: <역할>\` 형식. 역할은 한국어 또는 영어 모두 OK. - **적용 URL**: 해당 템플릿을 쓰는 페이지의 URL을 콤마로 모두 나열. 1개면 1개만. - **공통 블록 순서**: \`sectionRoles\`의 tag 순서를 기반으로 \`Header → Hero → ... → Footer\` 식으로 위→아래 흐름을 화살표(\`→\`)로 표기. - **페이지별 차이점**: 같은 템플릿을 쓰는 페이지들 사이의 변하는 부분(타이틀/이미지 수/CTA 문구 등). 단독 페이지면 \`(없음 / 단독 페이지)\`. - **재사용 컴포넌트**: 5-5에서 정의한 컴포넌트 이름을 콤마로 나열. 표 아래에 각 템플릿을 ATag/CSS 명세 수준으로 풀어 쓰는 짧은 단락을 덧붙여도 좋다 (선택).` : ` ## 9. 원본 사이트 재구축 명세 (Rebuild Spec — Same Site, Built From Scratch) > **⚠️ 이 단계의 미션 (절대 이탈 금지)** > - 이 섹션은 **원본 레퍼런스 사이트와 가능한 한 같은 사이트를 처음부터 다시 만들기 위한 개발 명세**다. > - 다른 서비스(대시보드, 분석 툴, SaaS 등)로 **재해석·확장·전환하지 말 것**. 사용자 컨텍스트가 원본과 다른 도메인이면 part 9에서는 무시한다. > - "개선 / 재설계 / 모던화 / 데이터 시각화 추가" 같은 변형 제안 금지. **원본 그대로 복원**이 유일한 목적. > - 모든 결정값(색상·폰트·여백·Radius·전환 속도)은 part 1~7에서 추출한 토큰을 그대로 인용한다. ### 9-1. 디자인 토큰 정의 (원본 값 그대로) - part 7에서 도출한 토큰을 CSS 변수 또는 Tailwind config 형식으로 코드블록에 옮긴다. 값은 절대 임의로 바꾸지 말 것. ### 9-2. 컴포넌트 명세 (원본 사이트의 카드/버튼/네비 등) - part 5-5의 컴포넌트별 props·치수·padding·radius·border·shadow를 코드블록 형태로 명세. ### 9-3. 페이지별 레이아웃 마크업 가이드 - part 8 페이지 템플릿 맵의 각 템플릿(T1, T2, ...)에 대해 HTML 골격(섹션 → 자식 컴포넌트)을 의사 JSX/HTML로 1개씩 제시. ### 9-4. 인터랙션 재현 명세 - part 3의 hover/focus/transition 값을 어느 컴포넌트에 어떻게 적용할지 명시 (예: \`.btn:hover { background: ...; transition: 0.2s ease; }\`). ### 9-5. 콘텐츠 및 자산 준비 목록 - part 6의 페이지별 이미지/비디오 수, 카피 분량, 폼 필드를 체크리스트로 정리. 사장님이 준비해야 할 자산 목록. ### 9-6. 개발 티켓 (원본 복원 기준) - 위 9-1 ~ 9-5를 구현 가능한 단위로 쪼개 \`[FE] / [BE] / [Asset]\` 태그를 붙여 티켓 형태로 나열. 모든 티켓은 "원본 사이트와 같게 만들기" 범위 안에 있어야 한다. 신규 기능 제안 금지. ## 🔍 복원 시 추정이 필요한 영역 (Buildability Gaps) - 스캔으로는 잡히지 않는 영역(다이나믹 데이터·CMS 구조·실제 폰트 라이선스·결제 연동 등)을 나열. 추측이 필요한 부분만 적고, 임의로 결정하지 말 것. > **주의**: 이 단계는 새로운 서비스 기획이 아니라 **원본 사이트 그 자체를 다시 짓기 위한 시방서**다. 9-1 ~ 9-6의 모든 값은 part 1~8에서 인용한 수치여야 한다.`; const partGoal = part === 1 ? '1/3단계: 원본 사이트의 시각·인터랙션·카피 톤을 4-렌즈로 분석한다.' : part === 2 ? '2/3단계: 원본의 IA, 페이지 템플릿, 디자인 토큰, 준비 리소스를 정리한다. 8단계 Page Template Map은 반드시 표 형식으로 작성한다.' : '3/3단계: 원본 레퍼런스 사이트를 처음부터 다시 만들기 위한 개발 명세를 작성한다. **사용자 컨텍스트는 무시하고, 다른 서비스로 재해석하지 않는다.**'; return `당신은 시니어 UX/UI 분석가 겸 프론트엔드 아키텍트다. ${sharedRules} [이번 단계 목표] ${partGoal} [레퍼런스 사이트 스캔 데이터 (JSON)] \`\`\`json ${JSON.stringify(slim, null, 2)} \`\`\` [사용자 보조 컨텍스트 — part 1·2의 톤 추정에만 참고. part 3에서는 무시할 것.] ${userBlock} [작성할 보고서 섹션 (이 구조를 그대로 따를 것)] ${partTemplate}`; }