← 목록으로

[기획] 혜택 카드 — 새로 만들기·편집하기 한 판 (명세 10 §2-L)

게시 전 초안입니다. 아래 구분선부터가 GitHub 이슈 본문이고, 받는 사람은 개발(재환님)입니다.


재환님, 안녕하세요. 기획 쪽에서 정리한 혜택 카드 편집 화면 건을 공유드립니다.

바쁘신 와중에 죄송하지만, 시간 나실 때 한 번 봐 주시면 감사하겠습니다. 명세서와 목업에 화면 동작을 모두 반영해 두었습니다. 아래 「계약에 없는 것」 네 가지와 확인 질문 셋(Q-106 · Q-107 · Q-108) 은 여쭙고 싶은 부분입니다. 제안 답을 같이 적어 두었으니, 편하신 쪽으로 정해 주시면 기획 문서를 그에 맞추겠습니다.

1. 한 줄 요약

혜택 카드는 요청서 「라이브 혜택」 하나에서 만듭니다. 새로 만들기와 편집하기는 같은 모달 · 같은 순서를 씁니다 — ① 혜택 → ② 틀 → ③ 글 → ④ 꾸밈. 왼쪽에는 9:16 미리 보기가 있고, 카드 요소를 누르면 오른쪽 그 칸으로 스크롤됩니다.

2. 지금 계약과 맞춰 본 결과

대조 기준은 api-v4 feat/nlive2-implementation(2026-10-01 beac0c8)의 다음 두 파일입니다.
- apps/nlive2/src/direction/direction-card.controller.ts
- apps/nlive2/src/direction/direction-card.schema.ts

화면 계약 상태
① 혜택 고르기 sourceOptions.benefits · PATCH …/input 의 sourceBinding.benefitId ✅ 있음
② 틀 고르기(다섯 틀) templateOptions · sourceBinding.templateRef(gift · npay · cprice · cdisc · price) ✅ 있음
② 「추천」 틀 혜택 종류 → 틀 매핑 🟡 계약에 매핑이 없습니다. 아래 §4-1 처럼 프런트 상수로 두셔도 됩니다
② 「직접 올리기」(완성 그림) references.role 이 product_image · brand_logo 둘뿐 ❌ 없음 — R1 · Q-106
③ 글 칸 input.copy(키 ≤ 40자 · 값 ≤ 180자) · editableFields ✅ 있음
③ [AI로 채우기] 다시 채우는 호출 ❌ 없음 — R3
④ 로고 · 그림 references(brand_logo · product_image, 최대 2) ✅ 있음
④ 색 · 간격 · 장식 · 배경 투명 — ❌ 없음 — R2
[카드 만들기] input → render(202) → select → apply ✅ 있음(네 호출을 한 버튼으로)
생성 이력(누르면 적용) candidates · select · apply ✅ 있음
예전 값으로 돌아가기 restore(restoreInputRevision) · versions ✅ 있음
타임라인 아무 자리에 새 카드 카드 계획은 대본 cue(sourceCueRef)에서만 생깁니다 ❌ 없음 — R4

3. 요청 — 계약에 없는 것 넷 (+ 진입 상태 하나)

R1. 직접 올린 완성 그림을 카드로 받기 (Q-106)
- 제안: references.role 에 card_image 를 하나 더합니다. 이 역할이 있으면 render 는 그 그림을 1080×1920 으로 채워 후보로 만들고, 틀 렌더는 건너뜁니다.
- sourceBinding.benefitId 는 그대로 둡니다. 올린 그림도 그 혜택의 카드입니다.

R2. 꾸밈 값 (원본 배너 에디터 realform5 와 같은 다섯 개)
- 제안: input 에 style: { bg: '#RRGGBB', ac: '#RRGGBB', textSpacing: 0.7~1.4, elementSpacing: 0.7~1.4, decor: boolean, transparent: boolean } 를 둡니다.
- 렌더러 renderBannerHtml(spec) 의 bg · ac · ts · es · decor · transparent 로 그대로 넘깁니다.

R3. [AI로 채우기] — 글 칸 다시 채우기
- 제안: POST …/cards/:cardPlanId/fill-copy(expectedInputRevision). 그 혜택(benefitId 의 text · condition)과 지금 templateRef 로 LLM 이 copy 의 헤드라인 1 · 2, 서브, 라벨, 값을 채우고 inputRevision 을 1 올립니다.
- 가격 값(정가 · 최종가 · 브랜드 · 제품명)은 요청서 사실이므로 덮지 않습니다.
- 여쭙고 싶은 것: 지금 copy 의 첫 값은 카드 계획을 만들 때 누가 채우는지요?

R4. 타임라인 임의 지점에 새 카드 계획 만들기
- 제안: POST …/direction/cards({ startSec, benefitId }). 혜택 카드 길이는 기본 4초입니다(명세 10 행 2-74).
- 겹침과 빈틈 규칙은 명세 10 행 2-71 ~ 2-73 을 그대로 따릅니다.

R5. 진입 상태
- 명세 10 행 2-80: 타임라인에 처음 들어오면 소리가 꺼져 있습니다.
- 지금 /next 타임라인은 켜진 채 시작합니다.

4. 구현 상세 — 이 절은 코딩 에이전트가 그대로 따라 만들 수 있게 적었습니다

4-1. 데이터 흐름

요청서 live_benefits[] ─┐
대본 card_hint cue ─────┼→ 카드 계획(cardPlanId · sourceCueRef · benefitId)
                        └→ ② 추천 틀 = KIND_TPL[혜택 종류] (금액 단위가 % 면 cprice → cdisc)
KIND_TPL = { 첫구매 쿠폰: cprice, 멤버십 쿠폰: cprice, 추가 할인: cprice,
             무료배송: gift, 이벤트 경품: gift, 추첨: gift, 증정: gift }   // N페이는 요청서 칸이 없어 ② 에서 고를 때만
③ copy = LLM(혜택 text · condition, templateRef)   ④ style · references
[카드 만들기] = PATCH input → POST render → (완료) select → apply → 생성 이력 맨 앞 · 「적용됨」

4-2. 화면 — 모달 「혜택 카드 편집하기」 / 새로 만들기는 「어떤 혜택 카드로 할까요 (2/2)」

4-3. 우측 패널(막대를 골랐을 때)

4-4. 완료 기준 (목업 자와 같은 항목)

5. 확인 질문

번거로우시겠지만 확인 부탁드립니다. 감사합니다.

— Claude Code 정리 · 강형모 확인