## IMPROVEMENT (Phase A~D) - A-1: 4단계 Sonnet 디자인 조정 (_adjust_design) — CSS 변수 cascade - A-2: 5단계 HTML 전문 프롬프트 전달 - A-3: shrink/expand 하드코딩 제거 → Sonnet target_ratio 기반 - A-4: rewrite action 구현 - A-5: overflow: visible (area 레벨 텍스트 잘림 방지) - A-6: object-fit cover → contain (이미지 crop 방지) - A-7: table-layout: fixed - A-8: container query 폰트 스케일링 - B-1: details-block 템플릿 신규 (CSS 변수만 사용) - B-2: 인쇄 시 details 자동 펼침 JS - B-3: catalog에 details-block 등록 - B-4/B-5: images[]/tables[] 상세 판단 + fallback 3곳 동기화 - B-8: fallback card-grid → topic-header + char_guide 제거 - C-1: CLAUDE.md gradient 원칙 완화 - C-3: border-radius 9개 파일 var(--radius) 통일 - C-4: box-shadow 2레벨 → 1레벨 - D-0: 이미지 경로 입력 UI + API base_path - D-1: Pillow 의존성 + image_utils.py - D-2~D-4: 이미지 비율/축소방지 프롬프트 전달 - D-5: HTML에 이미지 base64 삽입 ## Phase 2 (다른 Claude 작업) - P2-A: FAISS 블록 검색 (bge-m3, 46개 블록) - P2-B: SVG N개 자동 배치 (svg_calculator.py) - P2-C: Opus 블록 추천 (Kei API 경유) - P2-D: 5단계 재검토 루프 강화 (MAX_REVIEW_ROUNDS=2) - P2-E: details-block fallback 연동 ## 버그 수정 (BF-8~10) - BF-8: 컨테이너 예산 기반 블록 배치 - BF-9: grid와 Sonnet 역할 분리 - BF-10: catalog mtime 캐시 자동 갱신 ## 블록 라이브러리 - 46개 블록 (6 카테고리), catalog/BLOCK_SLOTS/INDEX 동기화 - 구 블록 제거 (quote-block, card-grid, comparison) - 13개 _legacy 블록 보존 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
13 KiB
13 KiB
Design Agent — 진행 상황
현재 상태 요약
| 상태 | 개수 |
|---|---|
| done | 23 |
| in-progress | 0 |
| todo | 0 |
| bug-fix | 7 (BF-4~10) |
| blocked | 0 |
| 전체 | 30 |
Phase 2 완료 (2026-03-25): P2-A~E 전체 done.
Phase 1: 기반 구축
| 태스크 | 상태 | 담당 | 시작 | 완료 | 메모 |
|---|---|---|---|---|---|
| DA-1: 프로젝트 셋업 | done | - | - | - | pyproject.toml, .env |
| DA-2: FastAPI 서버 | done | - | - | - | DA-1 이후 |
| DA-3: 디자인 토큰 + 기본 CSS | done | - | - | - | 독립 작업 가능 |
Phase 2: 블록 템플릿 제작
| 태스크 | 상태 | 담당 | 시작 | 완료 | 메모 |
|---|---|---|---|---|---|
| DA-4: 비교 블록 | done | - | - | - | DA-3 이후 |
| DA-5: 카드 그리드 | done | - | - | - | DA-3 이후 |
| DA-6: 관계도 | done | - | - | - | DA-3 이후 |
| DA-7: 프로세스 | done | - | - | - | DA-3 이후 |
| DA-8: 강조 인용 | done | - | - | - | DA-3 이후 |
| DA-9: 결론 바 | done | - | - | - | DA-3 이후 |
| DA-10: 비교 테이블 | done | - | - | - | DA-3 이후 |
| DA-11: 슬라이드 조합 렌더러 | done | - | - | - | DA-4~10 이후 |
Phase 3: AI 파이프라인 연결
| 태스크 | 상태 | 담당 | 시작 | 완료 | 메모 |
|---|---|---|---|---|---|
| DA-12: 1단계 Kei 실장 (꼭지+정보구조+role) | done | - | - | - | Kei API 연동. info_structure + role(flow/reference) |
| DA-13a: 2단계A 프리셋 선택 (규칙 기반) | todo | - | - | - | reference→sidebar-right, 비교→two-column 등 자동 |
| DA-13b: 2단계B 블록 매핑 (Sonnet) | todo | - | - | - | 프리셋 CSS 포함 프롬프트. zone별 블록 배정 |
| DA-13c: 3단계 텍스트 편집자 (Kei 역할) | todo | - | - | - | 의미 우선 편집 + 표 편집 + 자세히보기(요약+상세) |
| DA-14: 4단계 실무자 + 5단계 재검토 | todo | - | - | - | 디자인 조정 + HTML 조립 + 팀장 균형 재검토 |
Phase 4: UI + 출력
| 태스크 | 상태 | 담당 | 시작 | 완료 | 메모 |
|---|---|---|---|---|---|
| DA-15: 프론트엔드 | done | - | - | - | DA-14 이후. HTML 다운로드만 |
| DA-16: 통합 테스트 | done | - | - | - | DA-15 이후 |
버그 수정 이력
BF-1: 프론트엔드 SSE 파싱 실패 [발견: DA-15 이후]
- 현상: 서버는 정상 응답하지만 브라우저에서 결과 미표시. "시작 중..." 고정.
- 원인: main.py Python 문자열 안에 HTML/JS를 넣어서
\n이 실제 줄바꿈으로 변환 → JSsplit('\n\n')깨짐. 또한 Windows SSE가\r\n\r\n(CRLF)로 구분. - 해결: static/index.html 별도 파일로 분리. FileResponse로 서빙. SSE split을
/\r?\n\r?\n/정규식으로 변경. - 기술: FileResponse (FastAPI 내장), 추가 의존성 0
- 충돌 검토: API 경로와 충돌 없음. 기존 코드 변경 없음. Kei persona 무관.
- 상태: done
BF-2: 블록 내용이 비어있음 (Jinja2 include 변수 전달 실패) [발견: BF-1 이후]
- 현상: 슬라이드 HTML은 생성되지만 모든 블록 텍스트가 비어있음. 레이아웃 구조만 있고 내용 없음.
- 원인: renderer.py에서 Jinja2
include로 블록 템플릿을 삽입하는데,include는 블록별 변수를 개별 전달하지 못함. Sonnet이 채운 data가 템플릿에 도달 안 함. - 해결:
include대신 각 블록 템플릿을env.get_template().render(**data)로 개별 렌더링 후 완성된 HTML을 삽입.render_standalone_block()이 이미 이 방식으로 동작 중 → 통일. - 기술: Jinja2
get_template().render()(내장), 추가 의존성 0 - 수정 파일: renderer.py, templates/slide-base.html
- 충돌 검토: 블록 템플릿 7개 변경 없음. pipeline.py 호출 시그니처 동일. Kei persona 무관.
- 상태: done
BF-3: 한글 깨짐 (다운로드 HTML 파일) [발견: BF-1 이후]
- 현상: 다운로드한 HTML 파일에서 한글이
ê±´ì¤ì°ì같은 깨진 문자로 표시. - 원인: Blob 다운로드 시 UTF-8 BOM 미포함. 일부 에디터/브라우저가 인코딩 자동 감지 실패.
- 해결: download() 함수에서 Blob 생성 시 UTF-8 BOM(
'\uFEFF') 접두사 추가. - 기술: JavaScript BOM 1줄, 추가 의존성 0
- 수정 파일: static/index.html
- 충돌 검토: 미리보기(iframe)에 영향 없음. SSE 파싱에 영향 없음.
- 상태: done
BF-4: body 블록 겹침 [발견: 프리셋 도입 후]
- 현상: body area에 4개 블록이 겹쳐서 하나만 보임
- 원인: renderer가 같은 area에 별도 div 생성 → CSS Grid 겹침
- 해결: OrderedDict로 같은 area 그룹핑 → 하나의 div에 flex-column
- 기술: Python OrderedDict (내장)
- 수정 파일: renderer.py
- 상태: 코드 수정 완료, 테스트 필요
BF-5: 제목 안 보임 [발견: 프리셋 도입 후]
- 현상: 슬라이드 제목이 표시 안 됨
- 원인: 프리셋 area명
titlevs slide-base.htmlheader불일치 - 해결: 프리셋 4개에서
title→header교체 - 기술: 문자열 교체
- 수정 파일: design_director.py LAYOUT_PRESETS
- 상태: sidebar-right 수정 완료, 나머지 3개 확인 필요
BF-6: sidebar 카드 3열 찢어짐 [발견: sidebar-right 테스트]
- 현상: sidebar 35% 너비에 카드 3열 → 각 카드 폭 극히 좁아 찢어짐
- 원인: 팀장이 sidebar 공간 고려 없이 배치
- 해결: Step B 프롬프트에 sidebar 공간 안내 추가
- 기술: 프롬프트 엔지니어링
- 수정 파일: design_director.py STEP_B_PROMPT
- 상태: 미수정
BF-7: body 블록 텍스트 비어있음 [발견: 편집자 출력 확인]
- 현상: body의 4개 블록 중 1개만 텍스트 있고 3개 비어있음
- 원인: content_editor 매칭에서 같은 area 첫 번째만 매칭 (break)
- 해결: area + topic_id로 정확 매칭. 편집자 프롬프트에 topic_id 출력 추가
- 기술: Python 조건문 수정
- 수정 파일: content_editor.py
- 상태: 미수정
BF-8: 컨테이너 예산 기반 블록 배치 [발견: 파이프라인 실행 후 프레임 넘침]
- 현상: body에 4개 블록(quote+card+venn+comparison) 쌓아서 총 ~810px → 490px 예산 초과 → 잘림
- 원인: 팀장 프롬프트가 콘텐츠 중심 블록 선택 (높이 제약 없음). 큰 SVG(380px)를 다른 블록과 함께 배치
- 해결:
- LAYOUT_PRESETS: zone별 budget_px + width_pct 추가
- STEP_B_PROMPT: "컨테이너 예산 확인 → 배정 → 블록+높이 계산 → 검증" 4단계 사고
- catalog.yaml: 블록별 height_cost (compact/medium/large/xlarge) + 높이 참고표
- base.css: area div에 overflow:hidden + min-height:0 안전망
- 시각화 블록: flex-shrink + responsive SVG
- 수정 파일: design_director.py, catalog.yaml, base.css, venn-diagram.html, circle-gradient.html
- 상태: done (2026-03-25)
- 한계: 프롬프트만으로는 Sonnet이 grid를 무시하는 문제를 방지 불가 → BF-9 필요
- 충돌 해소 (2026-03-25): 다른 에이전트가 구 블록(quote-block, card-grid, comparison)을 BLOCK_SLOTS/defaults에서 의도적 제거. BF-8에서 catalog에 복원했던 것을 다시 제거하여 정합성 확보. 구 블록 → 신규 블록 대체 방향 확정.
BF-9: grid와 Sonnet의 역할 분리 [발견: 파이프라인 실행 결과 분석]
- 현상: Sonnet이 프리셋 grid 대신 자기만의 5행 all-auto grid 생성. zone명도 불일치(main, definitions 등)
- 원인: 설계 오류 — Sonnet에게 grid 값을 출력하라고 요구한 것 자체가 잘못. grid는 코드(Step A)가 결정, Sonnet이 건드릴 대상 아님
- 해결:
- Step B 프롬프트: grid 출력 요구 제거, blocks 배열만 출력하도록 변경
- create_layout_concept(): grid 값은 프리셋에서 직접 가져옴 (Sonnet 출력 무시)
- Sonnet이 출력한 area명이 프리셋 zone에 없으면 코드에서 자동 매핑
- 원칙: 코드가 결정한 것은 코드가 유지한다. Sonnet은 콘텐츠 판단만.
- 수정 파일: design_director.py (STEP_B_PROMPT + create_layout_concept)
- 상태: done (2026-03-25)
BF-10: _CATALOG_MAP 캐시 갱신 문제 [발견: 파이프라인 실행 결과 분석]
- 현상: relationship 블록이 _legacy CSS 원형으로 렌더링됨 (SVG premium이 아님). catalog.yaml 매핑이 적용 안 됨.
- 원인: _CATALOG_MAP이 모듈 레벨 global로 한 번만 로드. 서버가 구 catalog를 캐시.
- 해결: 파일 mtime 확인 후 자동 reload, 또는 매 렌더링 시 강제 reload
- 기술: Python pathlib stat()
- 수정 파일: renderer.py
- 상태: done (2026-03-25)
Phase 5: 블록 라이브러리 확장
| 태스크 | 상태 | 담당 | 시작 | 완료 | 메모 |
|---|---|---|---|---|---|
| DA-17: Figma 에셋 추출 + 블록 템플릿 | done | - | 2026-03-25 | 2026-03-25 | 스크린샷 16장, 에셋 15개+, 신규 블록 6종 |
| DA-18: 카테고리 폴더 재편 | done | - | 2026-03-25 | 2026-03-25 | 6개 카테고리 + INDEX.md |
| DA-19: 변형 확장 | done | - | 2026-03-25 | 2026-03-25 | 46개 달성. catalog/BLOCK_SLOTS/INDEX 전체 동기화 완료 |
Phase 2: 파이프라인 고도화
| 태스크 | 상태 | 담당 | 시작 | 완료 | 메모 |
|---|---|---|---|---|---|
| P2-A: FAISS 블록 검색 | done | - | 2026-03-25 | 2026-03-25 | bge-m3 1024d, 46벡터. block_search.py 신규. director 연동 완료 |
| P2-B: SVG N개 자동 배치 | done | - | 2026-03-25 | 2026-03-25 | svg_calculator.py 신규. N=2~7 테스트 통과. Phase 1 fallback 유지 |
| P2-C: Step A Opus+FAISS | done | - | 2026-03-25 | 2026-03-25 | _opus_block_recommendation(). Kei API 경유. Anthropic 직접 0회 |
| P2-D: 5단계 재검토 강화 | done | - | 2026-03-25 | 2026-03-25 | MAX_REVIEW_ROUNDS=2. expand/shrink/rewrite 3개 action. 다른쪽 구현+루프 추가 |
| P2-E-1: Pillow 이미지 크기 | done | - | 2026-03-25 | 2026-03-25 | 다른쪽에서 image_utils.py 구현 완료 |
| P2-E-2: details-block 연결 | done | - | 2026-03-25 | 2026-03-25 | "생략"→details-block 배치. fallback에도 반영 |
| DA-21: renderer 카테고리 경로 지원 | todo | - | - | - | DA-18 이후 |
| DA-22: catalog.yaml 경로 업데이트 | todo | - | - | - | DA-21 이후 |
블로킹 이슈
없음
DA-17 상세 기록
Figma 추출 결과
- 파일: 바론컨설턴트 홈페이지_기획팀공유 (uw7Z2hZGv9k6ygwrgYaAnF)
- 접근: Figma REST API (유료 계정 토큰)
- 스크린샷: 16장 (메인 3 + 자세히보기 13)
- 에셋: bg_header, card_img x3, compare_box x2, dx_bim_table, circle_label, mountain_viz, image_grid x2 등
- 노드 분석: 2-1_01 (건설산업), 2-1_02 (BIM) depth=4 상세 구조
신규 블록 템플릿 6종
| 블록 | 카테고리 | 검증 결과 |
|---|---|---|
| section-title-with-bg | headers/ | ✅ 렌더링 OK |
| topic-left-right | headers/ | ✅ 렌더링 OK, 사용자 확인 |
| compare-pill-pair | visuals/ | ✅ 색상 2차 수정 후 OK |
| circle-gradient | visuals/ | ✅ 사용자 확인 OK |
| card-image-3col | cards/ | ✅ 사용자 확인 OK |
| image-row-2col | media/ | ✅ 렌더링 OK |
기존 블록 수정
| 블록 | 수정 내용 |
|---|---|
| comparison-table → compare-3col-badge | Figma 톤으로 재디자인 (중앙 VS 배지, 좌우 중앙정렬) |
| conclusion-bar → conclusion-accent-bar | Figma 톤으로 재디자인 (좌측 파란 라인 + 밝은 배경) |
| compare-box → compare-pill-pair | Figma 톤으로 재디자인 (하늘색 둥근 테두리 + 시안 텍스트) |
시각화 방식 검증 이력
- CSS 원형 벤 다이어그램 → 실패 (클로드스러운 플랫 디자인, 20점)
- AntV infographic-cli → 제한적 (일부 SSR 타임아웃, 관계도 용도 안 맞음)
- AI 이미지(Gemini) + HTML 텍스트 오버레이 → 실패 (이미지 내 원 위치가 매번 달라 텍스트 위치 맞출 수 없음)
- SVG premium (radialGradient + filter + 수학적 좌표 계산) → 성공! 최종 확정
- 텍스트가 SVG 안에 있어 위치 100% 정확
- 그라데이션/글로우/하이라이트로 Figma 수준 품질
- N개 원소 자동 배치 (360/N 간격, cos/sin)
Phase 1 완료 요약 (2026-03-25)
- 블록 라이브러리: 6개 카테고리, 18개 블록 변형
- 시각화 방식: SVG premium 확정
- Figma 에셋: 스크린샷 16장, 에셋 15개+
- 블록 검증: 독립 렌더링 테스트 전체 통과
- 노하우: 텍스트=HTML/CSS, 시각화=SVG, 실사=이미지, AI이미지=배경전용
완료된 준비 사항
| 항목 | 파일 | 상태 |
|---|---|---|
| 프로젝트 규칙 | CLAUDE.md | 완료 (블록 라이브러리 구조 반영) |
| 실행 계획 | PLAN.md | 완료 (Phase 5 추가) |
| 진행 추적 | PROGRESS.md | 완료 (이 파일) |
| 기술 조사 | docs/RESEARCH.md | 완료 |
| Figma 분석 | docs/figma-analysis/DESIGN-ANALYSIS.md | 완료 |
| Figma 추출 계획 | docs/FIGMA-COMPONENT-EXTRACTION-PLAN.md | 완료 |
| 블록 라이브러리 | templates/blocks/ (6개 카테고리) | 구축 완료, 변형 확장 중 |
| 블록 인덱스 | templates/blocks/INDEX.md | 완료 |
| 블록 카탈로그 | templates/catalog.yaml | 완료 (경로 업데이트 필요) |
| MCP 설정 | .mcp.json (Framelink Figma MCP) | 완료 |