Appearance
[앱·웹] 나만의 선톡 개인화 시스템 + ON 넛지 PRD
Backlog grooming 산출물. 무엇을·왜 만들지와 기술 설계에 들어가기 전에 닫혀 있어야 하는 제품 정책을 정의한다. DB/큐/락/리트라이 등 구현 설계, 화면 디테일, 선톡 전용 프롬프트 본문은 본 PRD의 소유가 아니다 (§8 참조). 세부 정책이 충돌하면 더 상세한
draft/proactive-message-personalization/spec.md(DEE-414)를 우선한다.
Status: draft Created: 2026-06-01 Last updated: 2026-06-12 Linear Project: [앱/웹] 나만의 선톡 개인화 시스템 + ON 넛지Linear Issue: DEE-301 (PRD writing) / Spec: DEE-414 Author: agent (momo) Surface: 앱 + 웹 Chat Thread · Chat 설정 sheet · Push · 서버(선톡 생성·예약·발송 엔진)
0. 요약
나만의 선톡은 Soul이 유저에게 먼저 보내는 유료 개인화 메시지다. 기능의 본체는 push가 아니라 해당 Soul의 Chat Thread에 삽입되는 Soul 말풍선이고, push는 그 말풍선을 앱 밖에서 알리는 보조 채널일 뿐이다. 유저가 특정 Soul에 대해 선톡을 ON하면, 서버가 무응답 트리거와 자격 조건을 확인한 뒤 AI에게 “언제·무슨 말을 보낼지” 하나의 plan을 요청하고, 예약 시각에 최종 조건을 통과하면 Thread에 말풍선을 넣고 수신 성공 시점에 스타를 차감한다.
본 PRD의 스콥은 Soul별 유료 개인화 선톡 + OFF 유저 대상 ON 전환 넛지 하나다. 모든 유저에게 자동 발송되는 무료/기본 선톡, default 선톡과 개인화 선톡을 나누는 2층 발송 구조, 계정 단위 global opt-in은 본 범위에 없다. OFF 유저는 어떤 선톡도 받지 않고, ON 전환 넛지의 대상이 된다.
발송이 실제로 어떻게 일어나는지(후보 선정→트리거→pre-check→AI 생성→검증/빈도 상한→예약→취소→final check→과금/insert→push)의 단계별 정본은 spec(DEE-414) §5 「선톡 발송 로직」이다.
핵심 정책 한눈에
| 질문 | 정책 |
|---|---|
| 무엇을 만드나 | Soul이 먼저 보내는 유료 개인화 선톡 1종 + ON 전환 넛지 |
| 누가 받나 | (user, Soul) opt-in ON 이고 기존 활성 Chat Thread가 있는 유저만 |
| opt-in 단위 / 기본값 | (user, Soul) 단위 / 기본 OFF |
| 언제 생성하나 | 마지막 유저 메시지 이후 같은 Soul에게 1시간 무응답이면 선톡 생성 트리거 |
| 언제 멈추나 | 마지막 유저 메시지 이후 3일 이상 미응답이면 더 이상 생성하지 않음 |
| 무엇을 생성하나 | 선톡 전용 프롬프트(일반 Chat 즉답 프롬프트 재사용 금지)로 "보낼지·언제·무슨 말·push 문구"를 판단 |
| 언제 보내나 | AI가 보낼 실제 시각을 직접 알려준다(시각 표기는 Chat 도메인 규약을 따름). backend는 허용 window·심야 가드로 그 시각을 검증 |
| 언제 취소되나 | 같은 Soul에게 유저가 새 메시지를 보내면 취소 (앱 열기·읽기·push 열람·다른 Soul 대화는 취소 아님) |
| 빈도 상한 | (user, Soul, 유저 timezone 달력일)당 최대 2회 발송(수신). timezone 없으면 KST fallback |
| 가격 | 수신 성공 1회당 10스타 (일반 Chat 1회 성공 10스타와 동일) |
| 과금 기준 | Thread에 말풍선이 저장돼 다음 진입 시 보이는 수신 성공 시점. push 도달/open/read는 기준 아님 |
| Push와의 관계 | 선톡 ON = Thread 수신 동의. push를 꺼도 Thread엔 도착·차감될 수 있음 → ON 전 고지 필수 |
| 일일미션 | 선톡은 미션 채팅 횟수에 포함하지 않음 |
| 메인 지표 | 수신 성공 후 24시간 내 그 Soul Chat room 진입율 (답장율·차감 성공률은 보조/가드레일) |
1. 배경과 목표
1.1 문제
- 대상 세그먼트: 특정 Soul과 대화/플레이 접점이 있는 유저. 그 Soul의 선톡을 ON한 유저(수신 대상)와, 아직 OFF지만 관계 경험상 ON 전환 가능성이 있는 유저(넛지 대상)로 나뉜다.
- 상황: 유저가 앱을 나가면 Soul과의 관계 맥락이 끊긴다. 앱은 유저가 먼저 들어와야만 접점이 생기는 pull 구조다.
- 미충족 욕구: 캐릭터가 살아 있는 상대처럼 느껴지려면, 유저가 먼저 말을 거는 구조를 넘어 Soul이 자연스럽게 먼저 연락하는 순간이 필요하다.
1.2 근거
- 6월 Product Focus Goal — “가입한 유저가 다음 날 들어올 이유를 만든다.” 나만의 선톡은 Soul이 먼저 말을 거는 관계성 Chat 재진입 트리거다.
- 기존 push의 한계: 조건별/이어하기 푸시는 발신 주체가 시스템·앱이다. 나만의 선톡은 알림 채널을 쓰더라도 본질이 Soul이 맥락에 맞는 시간과 내용을 골라 먼저 보내는 Chat 메시지라는 점이 다르다.
- Chat 도메인 정합성 (Frontia-wiki Chat domain 기준):
- Chat은
(profile, soul)쌍당 1개의 영속 Thread로 동작하고, 활성 판정 권위는firstBubbleAt이다 → 선톡 대상을 “기존 활성 Thread가 있는(user, Soul)”로 정의한다. - user 설정은
ChatThreadMemberSettings(proactiveChatEnabled)에 존재한다 → opt-in을(user, Soul)단위로 둔다. ChatGenHistory.triggerType은user/proactive를 구분하고, 일일미션 채팅 횟수는 유저 트리거만 집계한다 → 선톡은 미션 횟수에서 제외된다.- Chat 진입 딥링크는
frontia://chatThread로 연결된다 → 선톡 push landing을 해당 Soul Thread로 고정한다.
- Chat은
1.3 해결 방향과 채택안
Soul이 유저에게 먼저 메시지를 보내는 유료 개인화 선톡 채널을 만든다. 채택안은 Soul별 유료 개인화 선톡 + ON 전환 넛지다.
- 무료/전체 발송 선톡 엔진, 전체 발송 정책, global opt-in은 본 범위에서 분리한다.
- OFF 유저에게는 선톡을 보내지 않고, 채팅방 햄버거 sheet와 관계 맥락이 충분한 순간의 in-app 넛지로 ON 전환을 유도한다.
- 이렇게 두는 이유: 이번 범위를 “개인화된 관계 접점 + 유료 opt-in”에 집중시키고, 신뢰·BM 리스크가 큰 “안 시킨 메시지에 과금” 문제를 사전 동의로 정면 처리하기 위해서다.
1.4 가설
- 나만의 선톡을 받은 유저는 그 선톡을 보낸 Soul의 Chat room에 진입한다 — 재진입 가설(메인).
- 맥락에 맞는 시간·내용의 선톡은 일반 푸시보다 사람이 보낸 연락처럼 느껴지고, 유저가 그 Soul에게 답장·대화를 이어간다 — 관계 engagement 가설.
- OFF 유저 일부는 관계 맥락이 충분한 시점의 ON 넛지를 보고 그 Soul의 선톡을 ON으로 전환한다 — 개인화·BM 가설.
1.5 성공 지표
| 지표 | 현재 | 목표 | 측정 |
|---|---|---|---|
| 선톡 → 발송 Soul Chat room 진입율 (메인) | 0 | baseline 대비 양(+)의 lift | 수신 성공 후 24h 내 같은 Soul Chat room 진입 비율 (건·유저 양쪽) |
| 선톡 → 답장율 (보조) | 0 | 모니터링 | Chat room 진입 후 유저 답장 말풍선 전송 비율 |
| 선톡 ON 전환율 (BM) | 0 | “0이 아님” 시그널 | ON 넛지/sheet 노출 유저 중 해당 Soul opt-in ON 전환 비율 |
| 차감 성공률 / 수신당 차감 스타 (가드레일) | 0 | 모니터링 | 수신 성공·차감 logging |
- 메인 ship/kill 지표는 발송 Soul Chat room 진입율이다. 선톡이 실제로 유저를 “그 Soul과 다시 대화할 수 있는 위치”로 데려왔는지를 본다.
- D1 retention은 보조 모니터링 지표다. 본 PRD의 메인 지표로 두지 않으며, holdout 실험 설계는 본 범위 밖이다.
- 가드레일: 앱/Chat 알림 OFF 전환율, 선톡 과금 관련 CS·환불, LLM 안전 위반/부적절 발송 비율, 기존 Chat·Episode funnel 회귀, AI 선톡 생성 비용·invalid/retry 비율.
2. 타깃 사용자와 핵심 시나리오
2.1 사용자
- 선톡 ON 유저 — 특정 Soul에 대해 명시적으로 ON한 유저. 선톡 생성·예약·발송 대상이다.
- 접점이 생긴 OFF 유저 — 해당 Soul과 Chat Thread는 있으나 선톡은 OFF인 유저. 선톡 수신 대상이 아니라 ON 넛지 대상이다.
2.2 핵심 시나리오
- 유저가 특정 Soul의 채팅방 햄버거 메뉴 또는 관계 맥락이 충분한 in-app 넛지에서 “나만의 선톡 받기”를 본다.
- ON 설정 sheet에서 **“알림을 꺼도 선톡은 채팅방에 도착할 수 있고, 도착하면 스타가 차감된다”**는 고지를 확인한 뒤 그 Soul의 선톡을 ON한다.
- 유저가 그 Soul에게 메시지를 보내고 앱을 나간다.
- 마지막 유저 메시지 이후 1시간 동안 같은 Soul에게 새 메시지가 없고, 마지막 메시지로부터 3일 미만이면 서버가 pre-check를 수행한다.
- opt-in ON · Soul 가용 · 활성 Thread 존재 · 일일 발송 상한(2회) 미도달 · pending 없음 · 잔액 ≥ 10스타를 모두 통과하면 선톡 전용 프롬프트로 선톡 생성을 요청한다.
- AI가 “보낼지·보낼 실제 시각·Thread에 들어갈 메시지·push 문구”의 의미를 담은 생성 결과를 반환하면 발송 상한 1회를 카운트하고 발송을 예약한다. 구체 output schema 는 기술 설계에서 확정한다.
- 예약된 발송 시각 전에 유저가 같은 Soul에게 새 메시지를 보내면 예약은 취소된다. 앱 열기·Thread 읽기·push 열람·다른 Soul 대화는 취소 사유가 아니다.
- 예약 시각에 final check(opt-in 유지·Soul 가용·잔액 ≥ 10스타·그 사이 유저 답신 없음)를 통과하면 Thread에 Soul 말풍선을 넣는다.
- Thread 저장 성공 = 수신 성공 → 10스타 차감 확정. push 설정이 허용되면 push도 보내고, OFF면 Thread 수신만 유지한다.
- 유저가 24시간 내 그 Soul Chat room에 진입(필요 시 답장)하면 메인/보조 지표에 반영된다.
3. 제품 정책 (PRD가 닫는 결정)
이 절은 기술 설계에 들어가기 전에 합의되어 있어야 하는 제품 정책만 다룬다. 구현 메커니즘(상태 enum, 큐/락, 트랜잭션, 리트라이)은 §8의 후속에서 다룬다.
3.1 opt-in (나만의 선톡 ON/OFF)
| 항목 | 정책 |
|---|---|
| 단위 | (user, Soul) — Soul마다 독립 |
| 기본값 | OFF |
| ON 의미 | 그 Soul이 먼저 보낸 개인화 선톡을 Chat Thread에서 수신하는 데 동의 |
| OFF 의미 | 그 Soul의 선톡 생성·예약·발송 대상에서 완전 제외. 대체 메시지 없음 |
OFF 전환 이후: 이미 예약된 선톡은 발송 전 final check에서 취소하고, 이미 수신 성공해 차감된 스타는 자동 환불하지 않는다.
3.2 생성 트리거와 장기 미응답 cutoff
| 항목 | 정책 |
|---|---|
| 트리거 기준 | 해당 (user, Soul) Thread의 마지막 유저 메시지 |
| Inactivity threshold | 1시간 — 그 사이 같은 Soul에게 유저 메시지가 없을 것 |
| Long inactivity cutoff | 마지막 유저 메시지 이후 3일 이상이면 생성 중단 |
| 1시간의 의미 | 즉시 발송 시각이 아니라 선톡 생성 후보 시점 |
선톡은 관계를 잇는 짧은 재접점이지, 장기 미응답 유저를 계속 두드리는 캠페인이 아니다. 능동 대화 중에는 1시간 무응답 조건이 성립하지 않으므로 트리거 자체가 발생하지 않는다.
Pre-check — 아래를 모두 통과할 때만 AI를 호출한다. 하나라도 실패하면 AI 호출·선톡 생성·발송 상한 소진이 없다.
(user, Soul)opt-in ON.- Soul이 Chat 가능 상태(미삭제, Chat availability ON).
- 활성 Chat Thread 존재(유저가 그 Soul과 채팅을 시작한 적 있음).
- 마지막 유저 메시지 이후 3일 미만.
- 해당
(user, Soul, 유저 timezone 달력일)의 일일 발송 상한(2회) 미도달(timezone 없으면 KST). - 동일
(user, Soul)에 pending 예약 없음. - 스타 잔액 ≥ 10.
3.3 AI 선톡 생성과 전용 프롬프트
- AI는 메시지 본문만이 아니라 발송 시각과 내용을 함께 만든다. AI는 보낼 실제 시각을 직접 알려주고, backend는 시간 최적화 주체가 아니라 validator / scheduler / safety guard다.
- 나만의 선톡은 일반 Chat 즉답 프롬프트를 재사용하지 않는다. “유저 발화에 대한 답장”이 아니라 “Soul이 먼저 말을 걸어도 되는지 / 언제 / 무엇을 말할지”를 판단하는 선톡 전용 프롬프트를 쓴다.
- 본 PRD가 소유하는 것은 선톡 전용 프롬프트가 필요하다는 정책 + 생성 결과가 담아야 할 정보 + 제품 guardrail이다. 프롬프트 실제 본문·슬롯 합성 순서·few-shot, 그리고 구체적인 payload/스키마·직렬화 형식은 별도 prompt/spec·기술 설계에서 정한다(§8).
생성 결과가 담아야 할 정보 (제품 정책) — 구체 스키마/필드명/코드 계약이 아니라, 선톡 1건을 발송 판단·예약·과금까지 진행하는 데 필요한 정보의 종류다.
- 보낼지 / 보내지 않을지 판단. 보낼 자연스러운 맥락이 없으면 보내지 않는다.
- 보낼 실제 시각. AI가 시각을 직접 알려준다. 시각 표기는 Chat 도메인이 이미 쓰는 datetime 표기 규약을 따른다(별도 형식을 새로 정의하지 않는다). 허용 window·심야 가드 검증은 backend 책임(§3.4).
- Chat Thread에 들어갈 Soul 말풍선 본문.
- push를 시도한다면 push preview/문구. Thread 본문과 같은 맥락이되 완전히 같을 필요는 없다.
생성 과정의 내부 사유(reason 등)·구체 payload 스키마·필수/옵셔널 필드 규약은 PRD가 닫는 제품 정책이 아니라 기술 설계 소유다. PRD는 “위 정보가 생성되어야 한다”까지만 닫는다.
Output guardrail (제품 정책 — 상세 hard rule 본문은 DEE-115/프롬프트 후속):
- Thread 본문·push 문구는 시스템/결제/마케팅 메타 발화를 하지 않는다(예: “앱에 들어와”, “스타를 써”, “알림 보냈어” 금지). Soul voice를 유지한다.
- Episode·과거 대화를 현재 함께 있는 장면처럼 오해시키지 않는다.
- 유저가 답하지 않은 상태에서 관계를 급격히 격상하거나 과한 고백·집착으로 압박하지 않는다.
- 보낼 자연스러운 맥락이 없으면 보내지 않는다.
- 기존 Frontia LLM safety rule을 계승한다.
3.4 예약 / 발송 상한 / 취소
| 항목 | 정책 |
|---|---|
| 빈도 상한 단위 | (user, Soul, 유저 timezone 달력일) — timezone 없으면 KST fallback |
| 상한 | 하루 최대 2회 발송(수신) — 한 Soul이 같은 유저에게 하루에 보낼 수 있는 선톡 횟수 |
| 카운트 기준 | 발송을 진행하기로 확정된 예약 건 기준으로 상한을 적용한다. 상한에 도달하면 추가 생성·발송을 하지 않는다 |
| 발송 시각 | AI가 보낼 실제 시각을 직접 알려준다. 허용 window는 생성 시점 +1h~+24h, 심야(유저 기준 00:00~06:59) 발송은 다음 07:00 이후로 미루고, 범위를 넘기면 발송하지 않는다 |
상한은 “하루에 몇 번 선톡이 가는가”라는 발송/수신 빈도 정책이다. AI 생성 비용을 통제하기 위한 생성 가드(생성·예약을 어느 시점에 카운트하고 회복하지 않는지 등)는 구현 중립적으로 두며, 정확한 카운팅/예약 메커니즘은 spec/기술 설계가 정한다. 단, 상한에 닿는 “발송 확정” 건은 이후 취소·미발송이어도 상한 카운트를 되돌리지 않는다(생성 비용이 이미 발생).
상한을 소진하지 않는 경우(발송이 확정되지 않음): pre-check skip / AI 생성 실패가 retry 후에도 미해소 / AI가 보내지 않기로 판단. 상한을 소진하고 되돌리지 않는 경우(발송 확정 이후): 유저 답신으로 예약 취소 / final check 잔액 부족·opt-in OFF·Soul unavailable로 미발송 / Thread 저장 실패.
취소 조건 — “먼저 말 걸려던 의도는 내가 그 상대에게 답하기 전까지 끊기지 않는다”를 전제로 좁게 둔다.
| 상황 | 결과 |
|---|---|
| 같은 Soul Thread에 유저가 새 메시지 전송 | 예약 취소, 미차감 |
| 나만의 선톡 OFF 전환 | 예약 취소, 미차감 |
| Soul 삭제 / Chat availability OFF | 예약 취소, 미차감 |
| 유저가 앱을 열기만 함 | 유지 |
| 유저가 Chat list를 봄 | 유지 |
| 유저가 그 Thread를 읽기만 함(미전송) | 유지 |
| 유저가 push를 봄/open | 유지 |
| 유저가 다른 Soul과 대화 | 유지 |
3.5 가격 / 잔액 / 과금 기준
- 단가는 수신 성공 1회당 10스타로 확정한다. 일반 Chat generation 1회 성공당 10스타 정책과 동일하게 둔다.
- 수신 성공 = Thread 저장 성공이다: 선톡이 해당 Chat Thread에 Soul 말풍선으로 저장돼 유저가 다음 진입 시 볼 수 있는 상태. push 도달/open/read는 과금 기준이 아니다.
- 차감은 수신 성공 시점에만 발생한다. 미수신은 미차감이 원칙이다.
- 잔액은 두 지점에서 확인한다.
- Pre-check(AI 호출 전): < 10스타면 AI를 호출하지 않는다(
insufficient_balance, 발송 상한 미소진). - Final check(Thread 저장 직전): < 10스타면 발송하지 않는다(미차감, 발송 상한은 이미 소진·미복구).
- Pre-check(AI 호출 전): < 10스타면 AI를 호출하지 않는다(
- 잔액 부족 시 무료/default 메시지로 대체하지 않는다. 미발송·미차감이 유일한 처리다.
- 과금 정합성 요구(정책): 유저에게 “보였는데 차감 여부가 불명확” 또는 “차감됐는데 안 보임” 상태가 노출되어선 안 된다. 즉 Thread 노출과 스타 차감은 원자적으로 일치해야 한다. 이 정합성을 보장하는 구현 메커니즘(reserve/insert/confirm 등)은 spec/technical design 소유다(§8).
- 수신 성공으로 차감되면
personalized_proactive_message_receivedsource로 Bond Exp를 적립한다(DEE-71/DEE-72 계승).
3.6 ON 설정 고지 (필수)
ON 설정 sheet에는 아래 두 의미가 반드시 포함되어, 유저가 ON 전에 확인할 수 있어야 한다.
- 알림(push)을 꺼도 선톡은 채팅방에 도착할 수 있다.
- 선톡이 도착(수신 성공)하면 스타가 차감된다.
권장 카피:
알림을 꺼도 선톡은 채팅방에 도착할 수 있어요. 선톡이 도착하면 10스타가 차감돼요.
3.7 Push 설정과 Thread 수신의 분리
- 나만의 선톡 ON = Thread 수신 동의. Push 설정은 앱 밖 알림 노출 여부만 제어한다.
- Push OFF + 선톡 ON: Thread에는 선톡이 도착할 수 있고, push만 suppress된다.
- Push OFF여도 Thread 수신 성공이면 과금 대상이다. 이 사실은 §3.6 고지로 사전 공지한다.
- Push 발송 실패/미발송은 수신 성공 여부와 무관하다.
- 선톡 push는 서비스성/관계성 알림으로 분류한다. 마케팅 동의는 요구하지 않으나, OS/앱 push 권한이 OFF면 push만 suppress한다.
3.8 Chat Thread / list / 일일미션 동작
선톡은 유저 입장에서 “그 Soul에게 새 메시지가 온 것”으로 처리한다.
- 도착 시 채팅방 preview 갱신, unread badge 증가, Chat list 정렬은 일반 Soul 메시지와 동일(최신 메시지 기준).
- 선톡 전용 badge/label은 MVP 필수 아님(필요 시 design 후속).
- 선톡은 일일미션 채팅 횟수에 포함하지 않는다. 미션 채팅 횟수는 유저가 직접 발생시킨 채팅만 집계한다(Chat 도메인
triggerType=user만 카운트).
3.9 ON 전환 넛지 (정책 수준)
OFF 유저를 ON으로 유도하는 in-app 안내. v1은 햄버거 sheet row 상시 진입 + contextual in-thread nudge만 사용한다.
| 항목 | 정책 |
|---|---|
| 대상 | 그 Soul과 Thread가 있고 선톡 OFF인 유저 |
| 상시 진입점 | 채팅방 햄버거 sheet의 나만의 선톡 받기 row (DEE-72 surface 재사용) |
| contextual 노출 조건 | 그 Soul에게 유저 메시지 2회 이상, 또는 최근 Episode→Chat 진입 후 OFF |
| contextual surface | Chat Thread 하단/inline nudge. push·modal 강제 노출은 v1 제외 |
| 빈도 상한 | (user, Soul) 7일 1회, 유저 전역 하루 2회 |
| dismiss | dismiss 시 해당 (user, Soul) 30일 suppress |
| 제외 | 이미 ON · Soul unavailable · 미성년/정책 제한 segment |
| 필수 고지 | §3.6과 동일(Thread 도착 + 10스타 차감)을 ON 전환 전에 확인 가능 |
권장 카피:
{Soul}이 먼저 말을 걸 수 있게 할까요? 나만의 선톡이 도착하면 10스타가 차감돼요.
넛지는 “선톡을 받아본 경험”을 전제하지 않는다(기본 선톡이 없으므로). 가치 제안은 “이 Soul이 너에게 먼저 연락할 수 있게 된다”이다.
3.10 딥링크 / 진입
- 선톡 push landing은 해당 Soul의 Chat Thread로 바로 진입한다.
- 본 PRD는 신규 path를 정의하지 않고 Frontia-wiki / DEE-72의 Chat deep link 정본(
frontia://chatThread)을 재사용한다. 구체 path·파라미터는 DEE-72를 따른다. - 앱 미설치 시 fallback은 마켓(Chat은 앱 우선, 웹 Chat surface 범위는 DEE-72). 비로그인 접근은 로그인 유도 후 해당 채팅방 복귀.
4. 에러 / 예외 처리
| 상황 | 발송 | 차감 | 발송 상한 |
|---|---|---|---|
| pre-check opt-in OFF | 없음 | — | 미소진 |
| pre-check 잔액 부족 | 없음 | — | 미소진 |
| 마지막 유저 메시지 이후 3일 이상 미응답 | 없음 | — | 미소진 |
| 능동 대화 중(트리거 불성립) | 없음 | — | 미소진 |
| 일일 발송 상한 도달 / duplicate pending | 없음 | — | (도달) |
| AI 생성 실패 (retry 후) | 없음 | — | 미소진 |
| AI가 보내지 않기로 판단 / safety 차단 | 없음 | — | 미소진 |
| 발송 확정(예약) | 예약 | — | 소진 |
| 발송 확정 후 유저가 같은 Soul에 답신 | 취소 | — | 소진 유지 |
| final check opt-in OFF / 잔액 부족 | 없음 | — | 소진 유지 |
| Soul 비공개·삭제·Chat OFF | 취소 | — | 소진 유지 |
| Thread 저장 실패 | 수신 아님 | — | 소진 유지 |
| Thread 저장 성공 + push suppress(OFF) | 수신 성공 | 차감 | 소진 |
| Thread 저장 성공 + push 발송 실패 | 수신 성공 | 차감 | 소진 |
| 유저가 앱/Chat list/Thread를 보기만 함 | 예약 유지 | — | — |
| 유저가 다른 Soul과 대화 | 예약 유지 | — | — |
5. 데이터 분석
5.1 핵심 지표와 측정 설계
- 메인: 나만의 선톡 → 발송 Soul Chat room 진입율.
- 분모: 선톡 수신 성공 건 / 수신 성공 유저(건·유저 양쪽 적재).
- 분자: 수신 성공 후 24시간 내 같은 Soul Chat room 진입(진입 경로 무관 — push click이든 Chat list든). 전체
/dm진입이 아니라 발송 Soul의 Chat room 진입만 메인 성공으로 본다. - 목표 하한: v1은 baseline 대비 양(+)의 lift를 ship 판단으로 둔다. 절대 하한은 1차 데이터 후 별도 growth 실험에서 재설정.
- 보조: 답장율, ON/OFF 전환율, D1 retention(secondary).
- 가드레일: 차감 성공률·수신당 차감 스타, AI 생성 비용·invalid/retry/skip 비율, push/Chat 알림 OFF 전환율, 선톡 관련 CS·환불, safety 위반 비율.
5.2 로깅 이벤트
컨벤션: snake_case, 동사_명사. 기존 그룹·이벤트 재사용 우선. 기존 Chat/Scene 이벤트 컨벤션(
generate_scene/generate_scene_complete,complete_chat_generation,view_chat_thread,toggle_chat_proactive_message_receive)에 정렬한다.아래는 제품·growth 분석에 쓰는 analytics 이벤트다. pre-check/cancel/fail 같은 단계 전이와 그 사유(reason)는 analytics 이벤트가 아니라 backend 내부 로그로 남긴다 — 정의는 spec §10·§11.
| 이름 | 용도 | 주요 파라미터 | 상태 |
|---|---|---|---|
generate_proactive_message_complete | 발송 조건 충족 + 선톡 생성 완료(아직 발송 전일 수 있음) | soul_id, soul_name, thread_id, message_id, user_id | 신규 |
send_proactive_message_complete | 선톡이 실제로 발송(Thread 수신 성공)된 시점 | soul_id, soul_name, thread_id, message_id, user_id | 신규 |
view_chat_thread | attribution 기준 Chat room 진입. 푸시 딥링크 유입은 source=push_notification (frontia-wiki 푸시 딥링크 convention 정렬) | soul_id, thread_id?, source(chat_menu/episode_detail/push_notification/deeplink/etc) | 기존(DEE-72) |
view_proactive_on_nudge | ON 전환 넛지 노출 | user_id, soul_id, surface | 신규 |
click_proactive_on_nudge | ON 전환 넛지 클릭 | user_id, soul_id, surface | 신규 |
toggle_chat_proactive_message_receive | opt-in 토글 (DEE-72 event name 재사용) | user_id, soul_id, to_state(on/off) | 기존(DEE-72) |
- 이벤트명은 기존 컨벤션에 맞춰 권장값을 둔 것이며, 최종 명칭·파라미터 표기는 data 컨벤션 확정 사항이지 제품 blocker가 아니다.
generate_proactive_message_complete/send_proactive_message_complete는 scenegenerate_scene_complete·chatcomplete_chat_generation컨벤션을 참고했다. soul_name은 Momo 요구 파라미터로 포함한다(기존 Chat 이벤트는soul_id위주).- Bond Exp는 실제 발송(수신 성공·차감) 시점에
personalized_proactive_message_receivedsource로 적립한다(DEE-71/DEE-72 정렬). 이는 analytics 이벤트가 아니라 Bond source 문자열이다. - 측정 설계상 생성 완료 건수와 실제 발송(차감) 건수는 분리해 집계할 수 있어야 하고, push suppressed/failed와 Thread 수신 성공도 분리해 볼 수 있어야 한다(push 부가 정보는 backend 로그).
6. Ubiquitous Language
Soul / Chat Thread / Chat Bubble / Bond Exp / LTM / User Relational Persona 등 기존 도메인 용어는 Frontia-wiki Chat domain·DEE-72/DEE-115 UL을 따른다. 선톡 전용 용어만 등재한다.
| Term | Korean | 정의 | 혼동 금지 | 상태 |
|---|---|---|---|---|
| Personalized Proactive Message | 나만의 선톡 | (user, Soul) opt-in ON일 때만 생성·예약·수신되는 유료 개인화 선톡. 본 PRD의 유일한 선톡 유형 | 무료/기본 선톡(본 scope에 없음), 유저 발화에 대한 즉답, 시스템 push | 신규 |
| AI 선톡 생성 결과 | 선톡 생성 결과 | AI가 만드는 “보낼지·보낼 실제 시각·Thread 메시지·push 문구” 한 묶음. 구체 payload/스키마는 기술 설계 소유 | 즉시 발송 메시지 | 신규 |
| AI 선톡 생성 | 선톡 생성 | 1시간 무응답 트리거 후 backend가 선톡 전용 프롬프트로 AI에게 선톡 생성을 요청하는 서버 작업 | Thread 수신, 과금 | 신규 |
| Receive success | 수신 성공 | 선톡이 Chat Thread에 Soul 말풍선으로 저장돼 다음 진입 시 보이는 상태. 과금 기준 시점 | push 도달/open/read | 신규 |
| 일일 발송 상한 | daily send cap | (user, Soul, 유저 timezone 달력일)당 선톡을 최대 2회까지만 발송(수신)한다. timezone 없으면 KST. 발송 확정 건 기준으로 카운트하며 되돌리지 않음 | 스타 차감 | 신규 |
| ON 전환 넛지 | ON nudge | OFF 유저에게 선톡 ON 전환을 유도하는 in-app 안내 | 선톡 자체, push 알림 | 신규 |
7. Closed Decisions
| # | Decision | Owner |
|---|---|---|
| 1 | 단가는 수신 성공 1회당 10스타로 확정. 일반 Chat generation 1회 성공당 10스타와 동일 | PM / pricing |
| 2 | Attribution window는 수신 성공 후 24시간, 같은 Soul Chat room 진입만 메인 지표로 인정. 목표 하한은 v1에서 baseline 대비 양(+)의 lift | PM / data |
| 3 | 과금은 수신 성공 시점에만 확정하고, Thread 노출과 스타 차감은 원자적으로 일치해야 한다(보였는데 차감 불명확/차감됐는데 안 보임 금지). 보장 메커니즘은 spec/technical design | PM(정책) / backend(구현) |
| 4 | AI가 보낼 실제 시각을 직접 알려주고(시각 표기는 Chat 도메인 규약), backend가 허용 window·심야 가드로 검증한다. 유저 기준 00:00~06:59 발송은 다음 07:00 이후로 미루고, +24h 범위를 넘으면 발송하지 않는다 | PM / backend |
| 4b | 빈도 상한은 (user, Soul, 유저 timezone 달력일)당 하루 최대 2회 발송(수신). 발송/수신 빈도 정책이며, 정확한 카운팅/생성 가드 메커니즘은 spec/기술 설계 | PM / backend |
| 5 | 선톡 push는 서비스성/관계성 알림으로 분류. 마케팅 동의 불요, OS/앱 push 권한 OFF면 push만 suppress | PM / policy |
| 6 | opt-in 토글 이벤트명은 DEE-72 기존 toggle_chat_proactive_message_receive로 단일화 | PM / data |
| 7 | ON 넛지는 v1에서 햄버거 sheet row + contextual in-thread nudge만. 조건: 유저 메시지 2회+ 또는 최근 Episode→Chat 후 OFF. 쿨다운 (user, Soul) 7일·전역 하루 2회·dismiss 30일 | design / PM |
| 8 | 시간/발송 상한 달력일 기준은 유저 최근 device/user timezone. 없으면 KST fallback하고 로그에 남김 | PM / backend |
| 9 | 선톡 발송 대상은 기존 활성 Chat Thread가 있는 (user, Soul)로 제한 | PM |
| 10 | 선톡 수신 시 Chat list preview·unread·정렬은 일반 Soul 메시지와 동일 | PM / client |
| 11 | 선톡은 일일미션 채팅 횟수에 포함하지 않음 | PM / economy |
| 12 | 선톡 push landing은 해당 Soul Chat Thread deep link로 고정 | PM / client |
| 13 | 메인 성공 기준은 수신 후 24h 내 그 Soul Chat room 진입율. 답장율은 보조, 차감 성공률은 가드레일 | PM / data |
| 14 | 마지막 유저 메시지 이후 3일 이상 미응답이면 더 이상 선톡을 생성하지 않음 | PM |
| 15 | 선톡 생성은 일반 Chat 즉답 프롬프트가 아니라 선톡 전용 프롬프트를 사용. PRD는 전용 프롬프트의 필요성·생성 결과가 담아야 할 정보(보낼지/실제 시각/Thread 메시지/push 문구)·guardrail을 소유. 구체 payload/스키마와 프롬프트 본문은 기술 설계·prompt 후속 | PM / prompt |
8. PRD가 닫는 것 vs 후속으로 넘기는 것
8.1 본 PRD가 소유(이미 닫힘)
opt-in 단위·기본값 · 발송 대상 · 생성 트리거/3일 cutoff · 선톡 전용 프롬프트 필요성과 생성 결과가 담아야 할 정보·guardrail · 발송 시각 정책(AI가 실제 시각 제시, 허용 window·심야 가드) · 일일 발송 상한(2회) · 취소 조건 · 가격(10스타)·과금 기준(수신 성공)·잔액 처리 · push 분리와 필수 고지 · Chat surface/일일미션 동작 · ON 넛지 정책 · 메인/보조/가드레일 지표와 tracking.
8.2 Spec / technical design 후속 (DEE-414 및 구현)
- 과금 정합성 보장 메커니즘(reserve/insert/confirm, idempotency key 등)과 상태 enum.
- 발송 엔진의 큐/락/리트라이/스케줄러 구현 설계.
- skip/cancel/fail reason enum 상세와 backend validation(clamp vs reject) 규칙 — spec §6·§10.
- 상세 Acceptance Criteria·QA 테스트케이스 — spec §13에서 확장.
- 마이그레이션: opt-in 상태·reservation·발송/차감 이력·일일 발송 상한 카운트 상태(초기 backfill 없음, default OFF).
8.3 Prompt / spec 후속 (별도 정본)
- 선톡 전용 프롬프트 본문, 슬롯 합성 순서, few-shot, 운영 기준.
- DEE-115는 메모리/컨텍스트 입력 소스와 공통 hard rule의 참조 기준일 뿐, 선톡 전용 프롬프트 본문의 정본이 아니다. 본문 정본은 이 후속에서 만든다.
8.4 Design 후속
- ON 설정 sheet와 ON 전환 넛지의 최종 visual/copy. 본 PRD/spec은 정책·필수 고지까지만 정의.
부록: 메타 정보
Required artifacts
- [x] Spec —
draft/proactive-message-personalization/spec.md(DEE-414). 트리거·예약·발송 상한·취소·과금·push 분리·넛지 정책 + AC. - [x] Design — ON sheet/넛지 visual·copy는 design 후속(§8.4).
- [x] QA scenarios — 정책 QA 기준은 §3~§5 / spec §13. 상세 케이스는 구현 QA에서 확장.
- [x] Migration plan — §8.2. 초기 backfill 없음(default OFF).
- [x] Tracking events — §5.2.
Size & Risks
- Size: L / Confidence: medium.
- 근거: 신규 생성·예약·발송 엔진 + AI 선톡 생성 +
(user, Soul)일일 발송 상한 + 수신 성공 차감 + push/Thread 연동 + opt-in/넛지 surface + 다수 인접 시스템(DEE-71/72/115·푸시·스타 잔액) 연동.
| 위험 | 영향 | 대응 |
|---|---|---|
| “안 시킨 메시지에 과금” 불만 | CS·환불·신뢰 하락 | Soul 단위 opt-in 사전 고지, push OFF여도 도착·차감 고지, 미수신 미차감, CS/환불 가드레일 모니터링 |
| push OFF여도 Thread 도착·차감을 유저가 이해 못 함 | 과금 신뢰 하락 | ON 설정 sheet 필수 고지(§3.6) |
| AI가 부담스러운 시간/내용 선택 | 몰입 파괴·알림 피로 | 발송 시각 허용 window·심야 guard, safety guard, 일일 발송 상한(2회), 운영 로그 튜닝 |
| Episode/과거 대화를 현재 상황처럼 오해시킴 | 몰입·신뢰 하락 | DEE-115 hard rule 계승, safety 위반 logging |
| AI 생성 비용 초과 | 비용·BM 악화 | pre-check에서 잔액/발송 상한/pending 확인 후 호출, 발송 확정 시 상한 소진 |
| 예약 후 유저가 답했는데 선톡 발송 | 대화 맥락 깨짐 | 같은 Soul 새 유저 메시지 시 예약 취소 |
의존성
- DEE-72 채팅 메신저 — Chat Thread/말풍선·과금 일반·opt-in sheet surface·딥링크 path.
- DEE-115 채팅 메모리/컨텍스트 — 개인화 입력 슬롯·공통 hard rule 참조(선톡 전용 프롬프트 본문 정본 아님).
- DEE-71 Bond 체계 —
personalized_proactive_message_receivedsource 적립. - 푸시 인프라 — 딥링크·동의 모델.
- 스타 결제/잔액 — pre-check/final check/수신 성공 차감.
References
- Linear: DEE-301(parent PRD) · DEE-414(spec) · DEE-72(채팅 메신저) · DEE-115(메모리/컨텍스트) · DEE-71(Bond).
- 식별자 메모: DEE-72/DEE-115 본문은 선톡 owner를
DEE-131로 참조하나, 현재 parent PRD는 DEE-301, spec writing은 DEE-414다.
- 식별자 메모: DEE-72/DEE-115 본문은 선톡 owner를
- Source of Truth: GitHub Frontia-wiki
wiki/domains/chat(index.md·capabilities.md). iCloud 로컬 wiki는 stale — SoT 아님. - sprint-artifacts:
draft/proactive-message-personalization/spec.md(상세 정책 정본) ·deployed/chat-messenger/(Chat surface) ·draft/chat-memory-context/PRD.md(메모리/페르소나 슬롯).
Reversal Risk Summary
| Layer | R-level | Review focus |
|---|---|---|
| Policy / Rule | R3 | 수신 성공 차감, push OFF·Thread 수신 분리, 일일 발송 상한(2회) 소진/미복구, 잔액 부족 미발송 — 신뢰·BM·비용 분기점 |
| Data / Backend | R2 | reservation/charge/발송 상한 상태 정합성. 정책 변경 시 재집계·운영 가능 |
| User-facing Surface | R1 | ON 넛지 위치·진입점·빈도는 출시 후 실험으로 조정 |
| Copy / Visual | R1 | “나만의 선톡” 라벨·고지/넛지 카피·push 문구는 출시 후 빠르게 조정 |