Appearance
[앱] 친밀도 점수 체계 (사전작업) PRD
Backlog grooming 단계의 산출물. 무엇을 만들지·왜 만들지·핵심 비즈니스 룰을 정의한다. 화면별 디테일(컴포넌트·상태·인터랙션)은 spec.md로.
Status: draft Created: 2026-05-13 Last updated: 2026-05-13 Linear Issue: DEE-71 [앱] 친밀도 점수 체계 (사전작업)Author: agent (momo) 앱/웹/스튜디오: 앱
1. 목표 및 배경
1.1 문제
- 사용자 정의 (segment): 캐릭터 중심 콘텐츠 소비를 하는 모든 플레이어 + DM/관계형 기능을 만들려는 제품팀.
- 상황 (when, where): 플레이어가 한 캐릭터를 반복적으로 만나거나, DM에서 자주 대화함에도 그 누적이 어디에도 반영되지 않는 상황.
- 불편 / 미충족 needs: 캐릭터-유저 관계가 데이터로 존재하지 않아 (1) 플레이어가 "내가 이 캐릭터와 얼마나 가까운지" 시각적으로 확인할 수 없고, (2) DM 선톡·톤 변화·잠금해제 같은 후속 기능을 깔 데이터 기반이 없다.
1.2 근거
- 인접 grilling: 2026-05-13 모모 grilling에서 DM 메신저(DEE-72)와 에피소드 상세 캐릭터 섹션(DEE-66) ship 결정. 두 기능 모두 "이 캐릭터와 얼마나 가까운가"의 데이터 표현을 요구.
- 현재 우회: 디렉터들이 캐릭터 정보를 미리보기 이미지에 텍스트로 박는 식으로 우회 중 (DEE-66 Background) — 관계 표현 자리 자체가 없음.
1.3 아이디어 (해결 방향)
캐릭터-유저 누적 상호작용을 raw 카운트(경험치, XP) 단일 숫자로 저장하고, 단계 라벨 + 진척바 + XP 숫자(RPG 스타일)로 노출한다.
- 옵션 1 (채택): 단순 카운트 누적 + RPG 스타일 노출. 구현·이해 모두 단순, 후속 기능이 raw XP를 직접 참조할 수 있음.
- 옵션 2 (기각): 의미 가중치(긍정/부정/감정 톤)로 계산하는 복합 점수. 가설·튜닝 비용 과다.
- 옵션 3 (기각): 단계만 노출 (숫자 X). 플레이어 동기 부여 약함, RPG 메타포 핵심 빠짐.
채택 근거: foundation 단계는 데이터를 쌓는 게 1차 목표. 노출은 동기 부여 + 향후 후속 기능 신뢰도 빌딩용으로 최소 표면만.
1.4 가설 (직접 검증은 후속 PRD)
본 PRD는 foundation 성격이라 가설 1·2는 후속 PRD(DM 선톡, DEE-66 ship 후 재진입 분석 등) 시점에 검증. 본 PRD는 데이터 자산이 정확히 쌓이는 것까지 책임진다.
- 플레이어는 누적된 친밀도가 시각적으로 보이면 같은 캐릭터의 다른 에피소드/DM으로 재진입할 동기를 갖는다 → DEE-66 ship 후 측정 가능.
- 친밀도 데이터가 존재하면 DM 선톡·톤 변화·잠금해제 같은 후속 기능이 ship 가능해진다 → 각 후속 PRD에서 enablement 확인.
1.5 성공 지표
| 지표 | 현재 | 목표 | 측정 방법 |
|---|---|---|---|
| 친밀도 XP 적재 손실률 | n/a | 허용 손실률 ≤ 정책 임계 (정책·임계 spec에서 확정) | 카운트 소스 이벤트 대비 XP 증가 트랜잭션 비율 |
| 단계 분포 합리성 | n/a | 분포가 곡선 설계 의도와 ±X% 이내 일치 | 단계별 (user, character) 쌍 분포 모니터링 |
- 메인 지표: 친밀도 XP 적재 손실률 (정책 임계 안에서 손실).
- 가드레일 지표: 에피소드 상세 진입률·이탈률 (새 섹션 추가로 인한 회귀). 베이스라인·허용 회귀 폭은 spec에서 확정.
2. 타깃 사용자
2.1 주요 사용자
- 캐릭터를 중심으로 콘텐츠를 즐기는 플레이어 (특정 캐릭터가 등장하는 에피소드를 반복 플레이하거나 DM 대화를 즐기는 사용자).
- 빈도: 에피소드 상세 진입 시마다 자연스럽게 노출. 별도 진입 경로 없음.
2.2 핵심 시나리오
- 플레이어가 캐릭터 A가 등장하는 에피소드 3편을 클리어한 후, 같은 캐릭터가 등장하는 다른 에피소드 상세에 들어가 "Lv.2 · 1,240 XP" 같은 친밀도 상태를 본다.
- 플레이어가 DM에서 캐릭터 B와 20번 대화한 후, 에피소드 상세에서 진척바가 다음 단계 가까이 가 있는 걸 본다.
- 후속 PRD(DM 선톡 등)에서 친밀도 XP/단계를 조건으로 기능을 분기시킨다 (본 PRD 범위 외, foundation 사용 예시).
3. 핵심 기능 요구사항
3-1. 클라이언트 (앱)
친밀도 표시 (에피소드 상세 캐릭터 섹션)
- 주요 동작: 에피소드 상세의 캐릭터 정보 섹션(DEE-66)에서 각 캐릭터 카드에 친밀도 상태를 함께 노출한다.
- 표시 요소:
- 단계 라벨 (
Lv.N— 단계명 카피 동반 여부는 §7) - 진척바 (현 단계 시작 → 다음 단계 진입까지 비율)
- 누적 XP 숫자 (예:
1,240 XP)
- 단계 라벨 (
- 비즈니스 룰:
- 친밀도는 (user, character) 쌍 단위, 글로벌 (같은 캐릭터가 여러 에피소드에 등장해도 친밀도 하나).
- 비로그인 / XP=0: 최저 단계 + 진척바 0% +
0 XP로 표시 (잠금 처리 없음). - 단계 라벨/진척바는 누적 XP에서 매번 파생 (저장하지 않음). 곡선이 바뀌면 표시값이 자동 재계산된다.
- 노출 위치: 에피소드 상세 캐릭터 섹션 1곳. 다른 표면 확장은 §7.
Ship 순서: 본 PRD는 데이터 적재 + 컴포넌트만 정의. UI가 실제 유저에게 노출되려면 DEE-66 (에피소드 상세 캐릭터 섹션)이 함께 ship 되어야 한다 (의존성 표 참조). 본 PRD 단독 ship 시에는 데이터만 쌓이고 노출은 없는 상태가 될 수 있음.
친밀도 XP 누적 (count source)
XP가 증가하는 소스. 어디서 발화하든 동일한 (user, character) bucket에 누적.
소스 A — 에피소드 플레이 중 캐릭터 등장(멘션)
- 정의: 캐릭터가 해당 플레이 세션에서 화자 또는 화면 등장 entity로 frame에 표시될 때 +1 XP.
- 카운트 단위 (멘션 = 무엇 1개): §7 — frame당 1 / scene당 1 / turn당 1 / episode 클리어당 N 중 결정 필요. 적재 볼륨이 1~2 자릿수 차이.
소스 B — DM 대화 (DEE-72)
- 정의: DM 스레드에서 유저 메시지 1건 전송 시 +1 XP. LLM 응답 수신은 카운트 안 함 (유저 주도 행동 기준).
- 단가: 소스 A와 동일 1:1로 가정. 실데이터 보고 §7에서 조정.
누적 룰:
- 트랜잭션: 멘션·메시지 발생 시점에 동기 적재. 실패 시 retry. 최종 실패 시 손실로 집계되어 §1.5 메인 지표(허용 손실률)로 관측. 사용자에게 노출되는 동작은 없다.
- XP는 단조 증가 정수. 가중치·감소·만료는 본 PRD 범위 외 (§3-5 Out of scope).
- 단계 산출: 곡선 함수
xp_to_level(xp) -> (level, current_floor, next_floor)적용. 곡선 형태·단계 수는 §7.
3-2. 어드민
본 PRD 범위 어드민 화면 없음 (§3-5 Out of scope). 운영 incident 발생 시 DB 직접 조정.
3-3. 딥링크 / URL 구조
신규 path 없음. 노출 surface는 기존 /episode/:episodeId 안의 캐릭터 섹션.
3-4. Scope
포함 (In scope)
- (user, character) 친밀도 XP 누적 데이터 모델·적재 파이프라인.
- 에피소드 플레이 캐릭터 멘션 → XP 적재.
- DM 메시지 전송(유저 발신) → XP 적재.
- 에피소드 상세 캐릭터 섹션 내 친밀도 표시 (단계 라벨 + 진척바 + XP 숫자).
- 단계 곡선 함수 정의 (수식·단계 수는 §7).
제외 (Out of scope)
- DM 내 효과: 선톡, 톤 변화, 잠금해제 (각 후속 PRD).
- 다른 surface 노출: MY 탭, 캐릭터 카드, 홈 등.
- 어드민 수동 조정 화면.
- 가중치·XP 감소·만료 룰.
- 통계·랭킹·소셜 비교 (친구의 친밀도 노출 등).
- 캐릭터 정보 섹션 자체의 UI/정보 구조 (= DEE-66의 PRD 범위).
4. 에러 처리 및 예외 상황
| 상황 | 처리 방향 |
|---|---|
| 비로그인 상태에서 에피소드 상세 진입 | 모든 캐릭터를 0 XP / 최저 단계로 표시 (잠금 X) |
| XP 적재 이벤트 실패 (네트워크/서버 오류) | 서버 트랜잭션 retry → 최종 실패는 손실로 집계, §1.5 메인 지표로 관측. 사용자 노출 없음 |
| 단계 곡선 함수 변경 (배포 후) | 누적 XP는 그대로, 표시 단계만 자동 재계산 |
| 캐릭터가 에피소드에서 제거되거나 비공개 | 누적 XP는 보존. 노출 surface가 사라질 뿐 |
| 같은 캐릭터가 여러 에피소드에서 동일 frame에 등장 | 멘션 카운트 단위 결정에 따름 (§7) |
| user 또는 character 삭제 | 친밀도 레코드도 함께 정리 — 세부 cascade 정책은 spec |
5. 데이터 분석
5.1 핵심 지표
- 친밀도 XP 적재 손실률 (§1.5 메인) — 카운트 소스 이벤트 대비 XP 증가 트랜잭션 비율.
- 단계 분포 — 단계별 (user, character) 쌍 수. 곡선 튜닝 인풋.
- 에피소드 상세 캐릭터 섹션 view율 (DEE-66 측 지표 공유) — 친밀도가 보이는 surface에 도달하는 비율.
5.2 로깅 이벤트
컨벤션: snake_case, 동사_명사. 기존 그룹·이벤트 재사용 우선.
기존 이벤트 재사용 판단 보류: event-docs.frontia.dev는 Cloudflare Access로 보호되어 본 작성 세션에서 fetch 불가. 아래 표는 신규 추가 후보이며, PRD 확정 전 momo 세션에서
episode-player/ DM 그룹의 기존 캐릭터 멘션·메시지 전송 이벤트를 확인하여 재사용 가능 항목은 신규에서 제외한다 (§7).
| 타입 | 이름 | 용도 | 파라미터 | 그룹 | 상태 |
|---|---|---|---|---|---|
| Event | view_intimacy_indicator | 에피소드 상세에서 친밀도 UI가 노출됨 | episode_id, character_id, level, xp | intimacy | 🆕 신규 |
| Event | accumulate_intimacy_xp | XP가 적재됨 (서버 이벤트 / 디버깅용) | user_id, character_id, source(episode_play / dm_message), delta_xp, total_xp_after | intimacy | 🆕 신규 |
| Event | levelup_intimacy | 단계가 상승함 | user_id, character_id, from_level, to_level, total_xp | intimacy | 🆕 신규 |
소스 A·B를 트리거하는 멘션/메시지 이벤트 자체는 기존 이벤트 재사용을 가정 (위 노트 참조).
6. Ubiquitous Language
| Term | Korean | Definition | Do Not Confuse With | Primary Domain | 상태 |
|---|---|---|---|---|---|
| Intimacy | 친밀도 | (user, character) 쌍에 대한 누적 상호작용을 표현하는 도메인 entity. 단일 XP 카운터로 표현되며, 곡선 함수를 통해 단계 라벨로 파생된다. | 캐릭터 일반 평판·작품 인기도 | Relationship (신규 도메인) | 신규 |
| Intimacy XP | 친밀도 경험치 | Intimacy의 raw 누적 카운트. 정수, 단조 증가. | 일반 경험치(없음), Credit | Relationship | 신규 |
| Intimacy Level | 친밀도 단계 | Intimacy XP에 곡선 함수를 적용해 얻은 단계 라벨. 저장하지 않고 파생. | Intimacy XP 자체 | Relationship | 신규 |
| Mention | 멘션 | 에피소드 플레이 중 캐릭터가 frame에 등장하는 단위 이벤트. 1 멘션당 +1 XP. (카운트 단위 정의는 §7) | 일반적 "언급" | Play | 신규 |
7. Open Questions
- [ ] 단계 곡선 함수 (XP → Level) — 곡선 형태(선형/지수/수동 테이블), 단계 수. spec 진입 전 필수. — PM(momo) + 데이터 agent 시뮬.
- [ ] 에피소드 플레이 멘션 카운트 단위 — frame / scene / turn / episode 클리어당 N 중. 적재 볼륨이 1~2 자릿수 차이. spec 진입 전 필수. — 데이터 agent (현재 frame/scene/turn 이벤트 발화 패턴, 캐릭터 등장 정보가 실리는 이벤트 확인) + 엔지니어.
- [ ] DM 메시지 1건 = +1 XP 적정성 — 자연스러운 DM 빈도와 에피소드 멘션 빈도의 ratio. 1:1이 적정한가. — 데이터 agent + PM.
- [ ] 단계 라벨 카피 동반 여부 —
Lv.N만 쓸지, 의미 있는 단계명(예: 낯선 사이 → 친한 사이)을 함께 노출할지. 동반한다면 카피는 spec/카피 단계에서. — PM. - [ ] 다른 surface 노출 후속 결정 — MY 탭(내 친밀도 톱), 캐릭터 카드, 홈 추천 등. 본 PRD 범위 외지만 본 PRD ship 직전 후속 PRD 큐 점검. — PM + 디자이너.
- [ ] §1.5 메인 지표 허용 손실률 임계 + 가드레일 회귀 폭 — 정책·임계 결정. 베이스라인 수치는 출시 직전. — PM + 엔지니어.
- [ ] 로깅 이벤트 재사용 매핑 — event-docs.frontia.dev의
episode-player·DM 그룹에서 캐릭터 멘션·메시지 전송 이벤트가 이미 있다면 재사용. §5.2 신규 3개도 그룹 분류 재검토. — PM (Cloudflare Access 세션에서 확인).
부록: 메타 정보
Required artifacts
- [x] Spec (
needs-spec) — 친밀도 UI 컴포넌트 명세, 단계 곡선 함수 확정, 이벤트 발화 위치, 적재 손실률 정책·임계, DB cascade 정책. - [x] Design (
needs-design) — Figma: 단계 라벨 + 진척바 + XP 숫자 컴포넌트 + 빈/저레벨 상태. DEE-66 캐릭터 섹션에 통합. - [ ] QA scenarios (
needs-qa-scenarios) — Sprint planning에서 작성. - [x] Migration plan (
needs-migration) — 신규 (user, character, xp) 테이블. 초기값 lazy create (첫 이벤트 시), backfill 없음. - [x] Tracking events (
needs-tracking) — §5.2.
Size & Risks
- Size: M
- Confidence: medium
- 추정 근거: 신규 테이블 1개 + 이벤트 2 소스 연결 + 새 UI 1곳. 단계 곡선·멘션 카운트 단위가 결정되면 구현 자체는 단순.
주요 위험 요소
| 위험 | 영향 | 대응 |
|---|---|---|
| 멘션 카운트 단위 잘못 잡음 → 적재 속도 왜곡 | 단계 분포 왜곡 | spec 전 시뮬. ship 후 1~2주 모니터링하며 곡선만 튜닝 (raw XP는 보존). |
| 후속 기능이 단계 라벨에 강결합 | 곡선 튜닝 비용 ↑ | 후속 기능은 raw XP 임계값으로 분기. 단계 라벨은 UI 노출 전용. |
의존성
- DEE-66 (에피소드 상세 캐릭터 정보 섹션): 본 PRD의 UI 노출 surface. DEE-66 ship 전에는 데이터만 쌓이고 노출은 안 됨. design merge point 협의 필요.
- DEE-72 (DM 메신저): 카운트 소스 B 제공자. DM ship 전에도 소스 A 단독으로 본 PRD ship 가능. DM ship 시 소스 B 연동.
References
- Frontia UL wiki:
wiki/foundation/ubiquitous-language.md— Character, Episode, Play 정의 - Linear:
- DEE-66 [앱/웹] 에피소드 상세 페이지 내 캐릭터 정보 섹션 추가 — 노출 surface
- DEE-72 [앱] DM 메신저 기능 — 카운트 소스 B
prd-review 보기
Review log
2026-05-13 (auto-review, agent 단독 적용)
prd-writer 직후 prd-review 1회. momo 부재 상황이라 메인 agent가 low-risk·obvious 정리만 적용, 진짜 product decision은 §7 OQ로 남김.
채택 (PRD 본문 갱신)
- Q: 메인 지표 "적재율 100%"가 가설 검증 지표가 아니다 + 100%는 단일 PRD 도달 불가
- A: 메인 지표를 적재 손실률 ≤ 정책 임계로 정정. 가설 1·2는 foundation 성격상 후속 PRD에서 검증한다고 §1.4에 명시.
- → §1.4 가설 헤더 변경, §1.5 표·메인 지표 문장 교체.
- Q: 가설 1 검증은 노출 surface 의존(DEE-66) — ship 순서 불명
- A: §3-1에 "본 PRD 단독 ship 시 데이터만 쌓이고 노출 안 됨" 문장 + 부록 의존성에 명시.
- → §3-1, 부록 의존성.
- Q: 백엔드/시스템 §3-3은 API/저장소 설계라 PRD 범위 아님
- A: §3-3 삭제. "단계 라벨/진척바 파생" 같은 비즈니스 룰만 §3-1로 흡수.
- → §3-3 제거, §3-1 비즈니스 룰에 흡수.
- Q: Negative spec 다수 ("어드민 화면 없음", "외부 시스템 연동 없음", "다른 팀 없음" 등)
- A: §3-5 Out of scope로 통폐합. §3-2는 한 줄로 축소. 부록 의존성의 "없음" 라인 제거.
- → §3-1, §3-2, §3-5, 부록.
- Q: §🔍 검토 필요 / 🚨 / ⚠️ / ❓ 4개 메타 섹션이 §7 OQ와 중복
- A: 모두 §7 OQ로 통합 + owner 필드로 외부 agent 호출 흡수. §🔍 섹션 전체 삭제.
- → §7로 통합, 섹션 삭제.
- Q: 부록 "진행 패턴 Spec → Design"은 SKILL 정의 메타
- A: 삭제.
- → 부록 Required artifacts.
- Q: §7 OQ 중 단계명 카피(디자인/카피), retention 법무, 어드민 운영 의례는 PRD 단계 OQ 아님
- A: 단계명 카피는 "단계 라벨 카피 동반 여부"로 PRD 단계 의사결정 1줄만 남김(spec에서 카피 확정). retention·어드민 OQ 삭제.
- → §7.
- Q: §1.5 가드레일 임계·베이스라인 placeholder
- A: §7에 "허용 손실률 임계 + 가드레일 회귀 폭" OQ로 추가, 책임자 명시. 본문은 임계만 결정·수치는 출시 직전 채움 정책 명시.
- → §1.5, §7.
- Q: §5.2 로깅 이벤트 그룹·재사용 판단을 spec으로 미룸
- A: event-docs.frontia.dev는 Cloudflare Access로 sprint-prep 세션에서 fetch 불가. 노트에 그 사실 명시 + §7에 momo 세션 확인 OQ 추가. 멘션·메시지 이벤트 자체는 "기존 재사용 가정"으로 표에서 빠짐.
- → §5.2 노트, §7.
- Q: 메인 지표 단위가 engagement·후속 ship 가능성이라는 가설과 불일치
- A: 가설은 foundation 특성상 본 PRD 직접 검증 X로 §1.4 헤더에 명시. 메인 지표는 데이터 품질(적재 손실률)에 한정하는 것이 일관됨.
- → §1.4, §1.5.
Skip
- (없음 — momo 부재라 product decision은 모두 §7 OQ로 보존)
진짜 product decision으로 §7에 보존된 항목
- 단계 곡선 함수 (선형/지수/수동, 단계 수)
- 멘션 카운트 단위 (frame/scene/turn/episode 클리어당 N)
- DM 메시지 단가 1:1 적정성
- 단계 라벨 카피 동반 여부
- 다른 surface 노출 후속 결정
- 적재 손실률 임계 + 가드레일 회귀 폭
- 로깅 이벤트 재사용 매핑 (Cloudflare Access 세션 필요)
momo 인라인 피드백 (criteria 후보)
- (없음 — agent 단독 세션. criteria.md 갱신 보류, momo walk-through 시 재논의 권장.)