# task-1610.1 완료 보고서

## S - Situation
네이버 블로그 이미지 생성 시스템이 `image_router.py`를 통해 용도별(photorealistic/cardnews/hybrid) 라우팅을 수행하고 있으며, `server.py`의 `_generate_blog_images()`가 모든 이미지 유형에 대해 영어 프롬프트 변환 → Gemini 생성 흐름을 사용 중이다.

## C - Complication
Gemini 이미지 생성이 인포그래픽/비교표에 부적합 — 프롬프트 텍스트를 이미지 안에 렌더링하여 한글이 깨지는 문제. infographic, comparison_table, checklist, process_flow 유형은 HTML 기반 렌더링이 필요하다.

## Q - Question
이미지 유형별 라우팅을 구현하여 photo → Gemini, infographic 유형 → Claude CLI HTML 생성 + Playwright PNG 렌더링으로 분기할 수 있는가?

## A - Answer
`ImageType.INFOGRAPHIC` enum 추가 + `_generate_infographic()` 함수 체인(Claude CLI → HTML → Playwright → PNG) 구현으로 유형별 라우팅 완료. 기존 photo/cardnews/hybrid 라우팅에 영향 없이 5개 키워드(infographic, comparison_table, checklist, process_flow, chart) 라우팅 추가. pytest 82건 전체 통과(기존 65 + 신규 17), fallback chain은 infographic 실패 시 기존 satori로 대체.

---

## 산출물 파일

### 수정 파일
- `/home/jay/workspace/tools/ai-image-gen/image_router.py`
- `/home/jay/workspace/dashboard/server.py`
- `/home/jay/workspace/tools/ai-image-gen/test_image_router.py`

## 주요 변경사항

### image_router.py
1. `ImageType.INFOGRAPHIC = "infographic"` enum 값 추가
2. `_INFOGRAPHIC_KEYWORDS` frozenset 추가 (5개 키워드)
3. `route_image_type()` — INFOGRAPHIC 키워드 라우팅 추가
4. `_prompt_to_html(description, img_type)` — Claude CLI haiku로 한국어 설명 → HTML 변환, 빈 응답 시 fallback HTML
5. `_render_html_to_png(html_content, output_path, width, height)` — Playwright로 HTML → PNG 스크린샷, 임시 .html 자동 정리
6. `_generate_infographic(prompt, output_path)` — `[type] description` 파싱 후 HTML 생성 + PNG 렌더링 체이닝
7. `_FALLBACK_CHAIN` — `ImageType.INFOGRAPHIC: ("infographic", "satori")` 추가
8. `_call_method()` dispatch dict — `"infographic"` 추가

### server.py (`_generate_blog_images()`)
- `photo` 타입: 기존 흐름 유지 (영어 프롬프트 → `purpose="광고"` → Gemini)
- 그 외 타입: `purpose=img_type`, `prompt=f"[{img_type}] {description}"` → 인포그래픽 라우터
- `brand` 계산을 분기 바깥으로 이동 (중복 제거)

### test_image_router.py
신규 테스트 클래스 6개 (17개 메서드):
- `TestImageTypeInfographic` — enum 존재/값 확인
- `TestRouteImageTypeInfographic` — 5개 키워드 라우팅
- `TestGenerateImageInfographicSuccess` — 정상 생성 경로
- `TestGenerateImageInfographicFallback` — satori fallback, 양쪽 실패
- `TestPromptToHtml` — Claude CLI 호출, 빈 결과 fallback
- `TestRenderHtmlToPng` — Playwright 성공/실패

기존 수정: `test_three_members` assertion 3 → 4

## 테스트 결과
- **pytest**: 82 passed, 0 failed (0.22s)
- **신규 테스트**: 17건 전체 통과
- **기존 테스트**: 65건 회귀 없음

## 발견 이슈 및 해결

### 자체 해결 (1건)
1. **`TestRenderHtmlToPng.test_returns_true_on_success` 실패** — mock된 `page.screenshot()`이 실제 파일을 생성하지 않아 `output_path.exists()` False 반환
   - 수정: `fake_screenshot` side_effect로 실제 파일 생성하도록 mock 보강 (`test_image_router.py:958`)

### 범위 외 미해결 (2건)
1. **pyright `reportMissingImports`** — `image_router` 모듈이 sys.path 동적 추가로 resolve 안 됨. 테스트/구현 모두 기존 이슈이며 runtime에는 정상 동작. 범위 외 사유: pyright 설정 레벨 이슈
2. **Satori 렌더러 직접 사용 불가** — ThreadAuto `satori_render.js` 미존재, `satori_cli.js`는 JSX 기반으로 임의 HTML 미지원. Playwright가 HTML→PNG 렌더링을 대체하며 한글 정확도 더 높음. 범위 외 사유: 외부 프로젝트 의존성

## 모델 사용 기록
- 팀원: 루(Lugh) / 작업: image_router.py + server.py 구현 / 사용 모델: sonnet / 정당성: -
- 팀원: 모리건(Morrigan) / 작업: test_image_router.py 테스트 작성 / 사용 모델: sonnet / 정당성: -
- 팀장: 다그다(Dagda) / 작업: 설계, 통합, QC, 테스트 수정 / 사용 모델: opus / 정당성: 팀장 역할
