diff --git a/docs/superpowers/specs/2026-06-02-insta-cardnews-upgrade-design.md b/docs/superpowers/specs/2026-06-02-insta-cardnews-upgrade-design.md new file mode 100644 index 0000000..a0b828e --- /dev/null +++ b/docs/superpowers/specs/2026-06-02-insta-cardnews-upgrade-design.md @@ -0,0 +1,97 @@ +# 인스타 카드뉴스 품질 고도화 + 업로드 친화 패키지 — 설계 Spec + +- **작성일**: 2026-06-02 +- **상태**: 설계 승인 (구현 plan 대기) +- **대상**: `insta-lab`(템플릿·카피·zip·web-ui) + `web-ai/services/insta-render`(렌더 워커, **별도 repo**) +- **사이클**: 스마트 에이전트 고도화 3종 중 **3번 인스타**. (1 로또·2 주식 배포 완료) + +--- + +## 1. 배경 & 목표 + +현재 insta-lab은 뉴스→키워드→Claude 카피(cover+본문8+cta+caption+hashtags)→Redis push→**Windows insta-render 워커**가 Jinja→HTML→Playwright 스크린샷(1080×1350)→텔레그램 전달 흐름이다. 그러나 카드가 "진짜 카드뉴스" 품질에 못 미치고(메모리상 렌더 known-issue), 현재 default 템플릿은 55줄짜리 기본형(accent+headline/body/footer)이다. + +CEO 목표: **진짜 카드뉴스 형식**으로 카드 품질을 끌어올리고, 완성 패키지를 **인스타에 업로드하기 쉽게** 만든다. + +### 핵심 결정 (2026-06-02 brainstorming) +1. **업로드 방식 = 반자동(현행 개선)**. Instagram Graph API/Meta 앱/IG 비즈니스 계정 미사용. 완성 카드+캡션을 사용자가 인스타 앱에서 직접 업로드하되, **마찰 없는 패키지 전달**(텔레그램 + zip 다운로드)로 개선. +2. **카드 품질 = 디자인 시스템 템플릿 고도화**. 폴리시한 HTML/CSS 디자인 시스템 + Playwright 렌더, known-issue 해결. (AI 생성 비주얼·Vision import 수리 아님) +3. **비주얼 = 모던 미니멀**. 넉넉한 여백·강한 산세리프 타이포·1~2 accent·깔끔한 그리드. 단일 강한 default 테마(멀티테마 X), accent만 카테고리별. + +### 기존 자산 (재사용) +- `insta-lab/app/card_writer.py` — Claude 카피 생성(cover_copy{headline,body,accent_color}, body_copies[8]{headline,body}, cta_copy{headline,body,cta}, suggested_caption, hashtags[]). +- `insta-lab/app/templates/default/card.html.j2` — 격상 대상(현 55줄 기본형). +- `web-ai/services/insta-render/`: `worker.py`(BLPOP `queue:insta-render` → `GET /api/insta/slates/{id}` → `render_slate` → webhook `/api/internal/insta/update`), `card_renderer.py`(`_build_pages`로 10페이지 spec 구성 cover/body8/cta, Jinja→HTML→`page.goto(file://, networkidle)`→`screenshot(full_page=False)` @viewport 1080×1350, `CARD_TEMPLATE_DIR`에서 템플릿 로드). +- nginx `/media/insta/` → `/data/insta_cards/`(카드 PNG 공개 서빙) — 패키지 다운로드에 활용. + +### known-issue 근원 (이번 작업으로 해결) +- 웹폰트(@import Google Fonts) 로딩 전 스크린샷 → fallback 폰트 렌더. +- `full_page=False` + 콘텐츠가 1350px 초과 → 하단 잘림. +- (기존 minimal 테마) Vision-import 마스킹 좌표·background-image 경로 문제 → **신규 깨끗한 디자인 시스템 템플릿으로 경로 자체를 제거(우회)**. + +--- + +## 2. 디자인 시스템 (모던 미니멀) + +`insta-lab/app/templates/default/card.html.j2`를 페이지 타입별 레이아웃을 가진 디자인 시스템으로 재작성. + +### 페이지 타입별 레이아웃 (`_build_pages`의 page_type 사용) +- **cover** (page 1): 카테고리 배지 + 대형 헤드라인(96px급) + 서브카피 + 브랜드 핸들. 시선 집중. +- **body** ×8 (page 2~9): 좌상단 번호 인덱스(02~09) + 포인트 헤드라인(72px급) + 본문(40px급, 2~4문장) + 하단 진행 인디케이터(점/바). 일관 그리드. +- **cta** (page 10): 요약 헤드라인 + 마무리 본문 + 행동유도(팔로우/저장) + 핸들. + +### 디자인 토큰 +- 타이포: Pretendard(우선) 또는 Noto Sans KR, weight 900/700/400, letter-spacing 음수, line-height 1.15~1.55. +- 레이아웃: 1080×1350 고정, safe-margin(예: 좌우/상하 ~80px), 그리드 정렬. +- 컬러: 라이트 배경(#F7F7FA 계열) + `accent_color`(카테고리별, 데이터 기존: economy #0F62FE / psychology #A66CFF / celebrity #FF5C8A 등) 포인트. +- 푸터: `{page_no} / {total_pages}` + 브랜드 핸들. body는 진행 인디케이터. + +### 제약 +- 각 페이지 = 정확히 1080×1350 고정 박스, `overflow:hidden`. 긴 본문 대비 본문 컨테이너 `max-height` + 줄수 clamp(말줄임 또는 폰트 축소). +- 단일 default 테마. accent만 카테고리 차등(추가 테마 디렉토리 안 만듦). + +--- + +## 3. 렌더 견고화 (web-ai 워커, known-issue 해결) + +`web-ai/services/insta-render/card_renderer.py` 보강: +- **폰트 보장**: `page.goto` 후 screenshot 전에 `await page.evaluate('document.fonts.ready')` 대기 추가. (가능하면 Pretendard를 워커에 self-host/번들해 네트워크 의존 제거 — 폴백으로 fonts.ready 대기.) +- **정확한 1080×1350**: 템플릿이 `.card{width:1080px;height:1350px;overflow:hidden}`을 보장. `full_page=False` + viewport 1080×1350 유지. 콘텐츠 오버플로우는 템플릿 CSS(clamp/max-height)로 차단. +- **PNG 검증**: 렌더 후 각 PNG가 1080×1350인지 + 0바이트/빈 페이지 아닌지 확인. 실패 시 webhook `failed`. +- **템플릿 sync (open item)**: 워커의 `CARD_TEMPLATE_DIR`가 신규 디자인 템플릿을 받는 경로 확인·정립. (insta-lab 템플릿 → 워커로 어떻게 전달되는지 plan에서 확인: web-ai repo 복사본인지 별도 sync인지. 신규 템플릿이 워커에 반영돼야 효과 발생.) + +--- + +## 4. 카피 정합 + 업로드 친화 패키지 + +- **카피 글자수 가이드**: `card_writer.py`의 프롬프트에 헤드라인/본문 글자수 상한 명시(디자인 박스에 맞게) → 오버플로우 예방. 시작 기준값(템플릿 박스 확정 시 ±조정): cover headline ≤ 22자 / body headline ≤ 26자 / body ≤ 120자 / cta headline ≤ 22자. CSS clamp가 2차 방어이므로 가이드는 근사치여도 안전. +- **업로드 친화 패키지 (신규)**: 기존 텔레그램 미디어그룹(10장)+캡션/해시태그 유지 + **zip 다운로드** 추가: + - 신규 API `GET /api/insta/slates/{id}/package` → 10 PNG + `caption.txt`(suggested_caption + hashtags) 묶은 zip 반환. + - web-ui 슬레이트 상세에 "패키지 다운로드" 버튼. + - 사용자가 zip 받아 인스타 앱에 캐러셀 업로드 + caption 붙여넣기. +- **승인 게이트 유지**: 키워드 후보 푸시 → 사용자 선택 → 렌더 → 전달. 자동 게시 없음(반자동). + +--- + +## 5. 에러·테스트·리스크·스코프 + +- **2 repo 배포 경로**: insta-lab = git push → Gitea webhook 자동배포. web-ai 워커 = Windows 머신에서 별도 갱신(repo: ai-trade.git). 템플릿·렌더 변경이 양쪽에 반영돼야 함. +- **테스트**: + - insta-lab: card_writer 글자수 제약, zip 패키지 구성(10 PNG + caption.txt), package API. + - web-ai: 페이지 타입별 템플릿 렌더 HTML 스냅샷, PNG 1080×1350 크기 검증, fonts.ready 대기, 오버플로우 clamp (web-ai `tests/test_worker` 확장). +- **리스크**: + - 템플릿 sync 누락 → 워커가 구 템플릿 렌더(효과 없음). plan에서 sync 경로 확정. + - 긴 카피 오버플로우 → 글자수 가이드 + CSS clamp 이중 방어. + - 폰트 로딩 타이밍 → fonts.ready 대기(+self-host). +- known-issue는 깨끗한 디자인 시스템 + 렌더 견고화로 **근본 해결**(Vision-import 경로 제거). + +--- + +## 6. 결정 로그 (2026-06-02) +1. 업로드 = 반자동(현행 개선, Graph API 미사용) +2. 카드 품질 = 디자인 시스템 템플릿 고도화 +3. 비주얼 = 모던 미니멀, 단일 default 테마 + +## 7. 스코프 밖 / 향후 +- Instagram Graph API 자동 게시, 멀티 테마, AI 생성 비주얼, Vision design_importer 수리, 카테고리별 차별 테마 — 향후. +- 9:30 자동 슬레이트(auto_select) 흐름 자체는 변경 안 함(품질·패키지만 개선).