Skip to content

feat(editorial,web): 신규 section type quote_pull + mood_board (Track 2 of #448) #548

@cocoyoon

Description

@cocoyoon

Parent: #448
Depends on: Track 1 (multi-stage 파이프라인)

Context

현재 section type 4종 고정 (intro / curation_card / spotlight / closing) — 매거진 톤이 한 가지뿐. 운영자 피드백 기반 다양성 확보를 위해 2종 추가.

quote_pull

큰 따옴표 인용 (60-120자). 단일 source solution 의 카피를 강조. 매거진 흐름 중간에 호흡을 주는 역할.

mood_board

이미지 4-8개 grid, 카피 최소 (제목 1줄 + 30자 이내). Pinterest 톤의 매거진에 필수. pinterest-board template 의 핵심.

Scope

ai-server

  • packages/ai-server/src/editorial_article/models.py:33MagazineSection.type Field description union 에 quote_pull | mood_board 추가, image_urls: Optional[list[str]] = None 필드 추가 (mood_board 용)
  • packages/ai-server/src/editorial_article/prompts/sections/quote_pull.py — 60-120자 인용문, brand 직접 언급 금지
  • packages/ai-server/src/editorial_article/prompts/sections/mood_board.py — image_urls 4-8 고정, body 30자 이내
  • packages/ai-server/src/editorial_article/section_writers.py — 매핑에 2개 추가
  • packages/ai-server/src/editorial_article/templates.pypinterest-board 에 mood_board 필수 삽입, editorial-deep 에 quote_pull 선택적
  • packages/ai-server/src/editorial_article/nodes/validate_sections.py — quote_pull 30-120자, mood_board image_urls 4-8 길이 검증

web

  • packages/web/lib/hooks/admin/useEditorialArticles.ts:49 — TypeScript union literal 에 quote_pull | mood_board 추가, image_urls?: string[] 필드
  • packages/web/lib/components/admin/editorial/magazine/MagazineRenderer.tsx:59 — switch 에 2 case + 컴포넌트:
    • QuotePullSection — serif italic, max-w-2xl, 큰 따옴표 글리프, 옆에 단일 SolutionCard
    • MoodBoardSection — 4-col masonry (md+) / 2-col (mobile), section.image_urls 또는 section.solutions[].image_url fallback

api-server

변경 없음 (layout_json: serde_json::Value 로 passthrough).

재사용

  • MagazineRendererSolutionCard (MagazineRenderer.tsx:239) — quote_pull 에서 재사용
  • useVtonStorequote_pull 의 단일 솔루션에도 try-on 가능

DB migration

없음. layout_json jsonb. 기존 layout 은 fallthrough.

Type sync (수동, 4곳 동시 수정)

  1. packages/ai-server/src/editorial_article/models.py
  2. packages/web/lib/hooks/admin/useEditorialArticles.ts:49
  3. packages/web/lib/components/admin/editorial/magazine/MagazineRenderer.tsx:59
  4. packages/ai-server/src/editorial_article/prompts/sections/*.py

자동 생성 (pydantic→TS) 은 별도 후속 PR (out of scope).

Sub-PR 분할

PR-2a: types + renderer

models.py + Renderer 컴포넌트 2종 + TS 타입. 기존 layout_json 은 fallthrough.

PR-2b: prompts + writers

prompts + section_writers + templates.py 업데이트. multi_stage 모드 (Track 1) 에서만 자동 생성됨 — single_call 모드 영향 X.

Test

  • Unit: tests/unit/editorial_article/test_writers_quote_pull.py, test_writers_mood_board.py
  • Visual: dev manual + PR screenshot (gstack 캡처)
  • Integration: Track 1 의 graph test 에 신규 type 포함 template 로 fake LLM 응답 → assemble 검증

Risk

  1. quote_pull 카피가 광고스러울 위험 — prompt 에서 "brand 직접 언급 금지, 분위기만"
  2. mood_board 이미지 source — section.image_urls 에 직접 적재 (plan_outline 에서 source pool 에서 pick), solutions[] 는 비울 수 있게
  3. Renderer masonry — aspect ratio 다양, CSS columns 또는 grid-auto-rows + image natural size

Out of scope (후속)

  • 추가 section type (comparison, timeline, interview)
  • 동적 accent color / typography variation
  • gpt-image-2 섹션 illustration 생성

Metadata

Metadata

Assignees

No one assigned

    Labels

    aiAI/자동화enhancementNew feature or requestfrontend프론트엔드

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions