Appearance
[앱/웹] 내 플레이 공유 PRD
Backlog grooming 단계의 산출물. 무엇을 만들지·왜 만들지·핵심 비즈니스 룰을 정의한다.
Status: draft Created: 2026-05-13 Last updated: 2026-05-13 Linear Project: [앱/웹] 내 플레이 공유 (c95e168a2297) Linear Issue: DEE-69Author: prd-writer (agent) 앱/웹/스튜디오: 앱 + 웹
1. 목표 및 배경
1.1 문제
플레이어가 자기 플레이를 "남에게 보여주고 싶다"는 욕구가 분명히 존재하지만, 플레이 결과를 외부로 꺼낼 공식 단위가 없다. 현재는 본인 앱 화면에 머무르고, 스크린샷 외에는 외부 공유 수단이 없다.
- 사용자 정의 (segment): 에피소드 플레이를 1회 이상 의미 있는 지점까지 진행한 플레이어. 특히 인상적인 씬을 만난 플레이어와 콘텐츠 큐레이션 성향의 헤비 플레이어.
- 상황 (when, where): 플레이 도중·직후 "이 장면 누구한테 보여주고 싶다"는 충동이 생긴 순간. 카톡·DM·SNS 등 외부 채널로 옮겨가려는 순간.
- 불편 / 미충족 needs:
- 공식 공유 수단 부재 → 스크린샷·녹화로 우회 → 작품 출처(에피소드/디렉터)가 끊기고 재플레이 동선이 사라진다.
- 수신자가 링크를 받아도 "이게 뭔지, 어디서 보는지" 알 수 없다.
- 작품 입장에서는 가장 강력한 바이럴 자산(플레이어가 만든 ‘내 플레이’)이 외부로 새지 않는다.
1.2 근거
- issue seed (DEE-69): "‘공유’는 source. 단위(링크/카드)·수신자 동선은 추론." — 사내 첫 외부 공유 단위 정의.
- 인접 시그널: Notification 도메인에 이미 "플레이 이어하기 push"가 정의돼 있을 만큼, 플레이는 재진입 동선이 핵심 자산. (
wiki/domains/notification/capabilities.md) - Play 도메인:
EpisodePlayaggregate가 publish snapshot + local play config를 결합. 공유 단위 후보(전체 플레이 / 특정 씬 / 엔딩)가 모두 이 aggregate 안에서 식별 가능. (wiki/domains/play/capabilities.md) - 사내 선례: Linear에서 "공유 / share / 캡쳐 / 딥링크" 키워드로 active project 검색 결과 본 프로젝트 외 hit 0건.
- 외부 유입·VOC 실측: 데이터 agent 호출 필요 (§7).
1.3 아이디어 (해결 방향)
플레이를 "공유 가능한 단위(Shared Play Snapshot)"로 패키징하고, 공유 링크를 통해 수신자가 미리보기 → 원본 에피소드로의 재플레이 동선을 타도록 만든다.
- 옵션 1 — Replay Link: 플레이 전체를 read-only로 외부 노출. "내가 만든 이야기"의 양감이 강하지만 viewer UI·spoiler·노이즈 노출 부담 큼.
- 옵션 2 — Moment Link: 한 씬을 카드형으로 외부 공유. OG 카드+한 화면 미리보기. 구현 부담 작고 캡쳐 대체재로 자연스러움.
- 옵션 3 — Ending Card: 엔딩·미션 클리어만 공유. 자랑·인증 동기와 매칭. "엔딩" 정의 필요·발화 빈도 낮음.
추천: 옵션 2 (Moment Link)를 첫 출시로 채택. 옵션 1·3는 후속 사이클. 사내 첫 외부 공유 단위라 수신자 동선·OG·권한 정책 변수가 많다. 가장 가벼운 단위로 한 사이클 먼저 돌리고 시그널 확인 후 확장한다. 옵션 2 산출물(공유 record, OG, 수신자 viewer, 재플레이 CTA)이 옵션 1·3 토대로 그대로 재사용된다.
1.4 가설
- 공식 공유 버튼이 생기면 플레이어는 스크린샷 대신 그것을 쓴다 — 플레이 공유 진입 클릭이 의미 있는 수준으로 발생한다.
- 공유 링크 수신자의 비-자명한 비율이 원본 에피소드 페이지로 진입한다 — viewer → 에피소드 CTR 시그널 확인.
- (보조) 공유 링크 유입 중 일정 비율이 신규 가입/플레이 시작으로 전환된다 — 신규 외부 유입 채널로 기능.
- 보조 위치 이유: 비프론티아 수신자 비율 base rate 미확보. 본 출시로는 funnel 끝까지 따라가 추정만 한다.
1.5 성공 지표
본 출시는 funnel 두 단계 모두 본다.
| 지표 | 현재 | 목표 | 측정 방법 |
|---|---|---|---|
| (메인 A) 공유 발행 수 / 플레이 완료 수 | 0 (기능 없음) | 정량 목표는 출시 직전 데이터 agent로 확정 — 책임: 모모 + 데이터 | submit_share_play / 플레이 완료 |
| (메인 B) 공유 viewer → 원본 에피소드 진입 CTR | - | 정량 목표는 출시 직전 데이터 agent로 확정 — 책임: 모모 + 데이터 | click_share_viewer_cta / view_share_viewer |
| (보조) 공유 viewer PV / 발행 수 | - | 출시 직전 확정 | viewer PV / 공유 record 수 |
| (보조) 공유 유입 신규 가입·플레이 시작 | - | 출시 직전 확정 | share_id 부착된 가입·플레이 시작 |
- 메인 지표를 두 개로 두는 이유: 발행이 0에 수렴하면 CTR 100%여도 outcome은 실패. 발행량(채택)과 전환(바이럴)을 동시에 본다.
- 가드레일:
- 플레이 화면 체류 시간 / 진행률 (공유 UI가 방해 안 되는지)
- 콘텐츠 신고 수 (공유로 부적절 콘텐츠가 외부 노출)
- 디렉터 이의/만족도 시그널
2. 타깃 사용자
2.1 주요 사용자
- 공유자(발신자): 플레이 도중·직후의 플레이어. 인상적인 씬을 만난 순간에 공유 충동을 느끼는 사람.
- 수신자: 공유자의 외부 채널(카톡/DM/SNS) 친구. 비로그인 가능성 높음.
- 2차 수익자: 해당 에피소드의 디렉터. 자기 작품이 외부로 알려지는 채널이 생김.
2.2 핵심 시나리오
- 플레이 중 인상적 씬 → 공유: 플레이어가 한 씬에서 멈칫하고, 플레이 화면의 공유 버튼을 눌러 그 씬을 외부 채널로 공유한다. 수신자가 OG 카드를 클릭해 viewer 페이지에서 미리보기를 본 뒤 "에피소드 보러가기"로 진입한다.
- 플레이 직후 회고형 공유: 플레이를 끝낸 직후 마지막 씬을 공유한다. 친구가 받아보고 "나도 해볼까?" → 신규 가입 → 동일 에피소드 플레이 시작.
- 수신자가 이미 프론티아 유저: viewer를 거치고 (또는 곧장 딥링크로) 앱 안의 에피소드 상세 화면으로 진입한다.
3. 핵심 기능 요구사항
3-1. 클라이언트 (앱/웹)
A. 플레이 화면 공유 진입 (Share Entry)
- 주요 동작: 플레이 중 플레이어가 현재 씬을 외부로 공유한다.
- 비즈니스 룰:
- 공유 단위: 씬(Scene). 한 씬 = LLM main call 1회의 narrative 응답.
- 공유 가능 시점: 프롤로그 이후의
completed씬 (현재 씬 포함). 진행 중(in_progress) 씬은 공유 불가. - 공유 단위 1개 = 공유 record 1개: 동일 씬 재공유 시에도
share_id는 새로 발급(통계 단순화). - 공유 발행 차단: 본문에 운영 정책 ruleset 위반(금지 키워드/이미지)이 있으면 공유 발행 차단 + 안내. ruleset connect는 §7.
- 상태별 동작:
- 본인 플레이: 가능 (플레이는 로그인 필수)
B. 공유 채널 시트 (Channel Sheet)
- 주요 동작: 공유 발행 시 OS 네이티브 share sheet로 외부 채널 전송. 웹은 Web Share API + 클립보드 복사 fallback.
- 공유 페이로드: 공유 URL + 공유 텍스트(에피소드명 + 한 줄 hook + 출처) + OG 미리보기 이미지(서버 렌더링).
- URL 포맷:
https://<web 도메인>/<prefix>/<share_id>— prefix 컨벤션은 §7.
C. 수신자 viewer 페이지 (Web)
- 주요 동작: 수신자가 공유 URL을 열면 웹 viewer가 (a) 공유된 씬의 narrative 텍스트, (b) 해당 씬의 대표 frame 1장의 시각 요소(배경/캐릭터/상황), (c) 메타(에피소드명·디렉터·간단 설명), (d) CTA "에피소드 보러가기"를 보여준다.
- 공유 단위 노출 범위: 해당 씬 1개의 narrative + 그 씬의 첫 frame을 대표 frame으로 사용(자동). 이전·이후 씬은 미노출.
- 수신자 권한:
- 비로그인: viewer 노출 OK. CTA 클릭 시 가입/로그인 게이트로 이동, 완료 후 에피소드 상세로 복귀.
- 로그인: viewer 노출 OK + CTA 활성.
- 재플레이 동선: CTA "에피소드 보러가기" 클릭 →
/episode/:episodeId로 진입. 거기서 기존 "이어보기" 룰을 그대로 따른다. ("이 씬부터 플레이하기" CTA는 본 출시 미포함 — §3-5 OOS.) - 상태별 동작:
- 공유 record
active+ 에피소드 정상: 정상 표시 - 공유 record 만료/비활성화: "더 이상 볼 수 없는 페이지" 안내 + 홈 CTA
- 에피소드 비공개/삭제: "이 작품은 더 이상 공개되어 있지 않습니다" 안내 + 홈 CTA
- 공유 record
D. OG / 미리보기 카드
- 주요 동작: 카톡·SNS·메신저에서 미리보기 카드가 자동 렌더링되어야 한다.
- OG title: 에피소드명 (디렉터명 부기 가능)
- OG description: 공유 씬의 첫 narrative line 또는 줄여서 80자 (카카오톡 호환). 추출 룰은 §7.
- OG image: 서버 사이드 렌더링된 카드 이미지. 에피소드 썸네일 + 핵심 카피 + 프론티아 로고. 비율 1.91:1.
3-2. 어드민
- CRUD 범위: 공유 record 조회 + 강제 비활성화 (abuse/신고 대응)
- 권한: 운영팀 전반
- 운영 흐름: 신고 접수 → 어드민이 공유 record 비활성화 → viewer 페이지가 차단 안내로 전환.
3-4. 딥링크 / URL 구조
기존 path 재사용:
| 경로 | 동작 | 본 PRD 사용 |
|---|---|---|
/episode/:episodeId | 에피소드 상세 | viewer "에피소드 보러가기" CTA |
/episode-play/:episodeId | 에피소드 플레이 (이어보기) | CTA 이후 자연 진입 (기존 룰) |
신규 path 필요 (개발자 확정 게이트):
- 웹 공유 viewer 페이지 1개 — prefix 컨벤션 미정 (§7)
- 앱 딥링크 1개 — viewer를 앱에서 그릴지 / 에피소드 상세로 바이패스할지 미정 (§7)
앱 미설치 fallback: 웹 viewer가 기본. 카톡 inApp browser에서도 그대로 렌더. 비로그인 접근 정책: viewer 자체는 노출 OK, 재플레이 CTA만 게이트.
3-5. Scope
포함 (In scope)
- 플레이 중 "씬" 단위 외부 공유 발행
- 공유 record entity 신규 추가
- 웹 viewer 페이지 (한 씬 미리보기 + "에피소드 보러가기" CTA)
- 서버 사이드 OG 카드 렌더링
- 어드민: 공유 record 강제 비활성화
- 로깅 이벤트 (§5.2)
제외 (Out of scope)
- 플레이 전체 공유 (옵션 1 Replay Link)
- 엔딩/마일스톤 카드 (옵션 3)
- 프레임 단위 공유
- 수신자에게 "이 씬부터 플레이하기" CTA (fork 플레이 생성)
- 공유 viewer 내 댓글·좋아요 등 인터랙션
- 수신자/공유자에게 보내는 알림·푸시
- 디렉터별 공유 허용/차단 toggle
- 남의 플레이 공유 / 임베드(iframe)
- 내 플레이 화면에 공유 이력 노출
4. 에러 처리 및 예외 상황
| 상황 | 처리 방향 |
|---|---|
| 공유 발행 시 네트워크 오류 | 재시도 가능. 발행 실패해도 플레이 진행에는 영향 없음 |
| 공유 record 만료/비활성화 후 viewer 접근 | "더 이상 볼 수 없는 페이지" 안내 + 홈 CTA |
| 에피소드 비공개/삭제 후 viewer 접근 | "이 작품은 더 이상 공개되어 있지 않습니다" 안내 + 홈 CTA |
| OG crawler가 OG image 캐시 미스 | on-demand 생성. 실패 시 에피소드 썸네일 default 카드로 fallback |
| 비로그인 수신자가 CTA 클릭 | 가입/로그인 게이트 → 완료 후 해당 에피소드로 복귀 |
| 본문이 운영 정책 ruleset 위반 | 공유 발행 차단 + 안내 |
| 부적절/신고 콘텐츠 | 어드민 강제 비활성화 → viewer 차단 안내 |
5. 데이터 분석
5.1 핵심 지표
§1.5와 동일. 메인 A(발행률), 메인 B(viewer→에피소드 CTR), 보조(viewer PV/발행 수, 신규 가입·플레이 시작).
5.2 로깅 이벤트
컨벤션: https://event-docs.frontia.dev/ (Cloudflare Access 보호). 기존 그룹 재사용 → 없을 때만 신규.
본 PRD에서 그룹 확정에 필요한 event-docs는 모모 세션에서만 접근 가능 → 재사용 vs 신규 그룹 판단 §7에서 모모가 확정. 아래는 컨벤션(snake_case, 동사_명사) 기반 초안.
| 타입 | 이름 | 용도 | 파라미터 | 그룹 |
|---|---|---|---|---|
| Event | click_share_play | 플레이 화면 공유 버튼 클릭 | episode_id, episode_play_id, scene_id, view_mode | episode-player 재사용 후보 |
| Event | submit_share_play | 공유 채널 시트에서 채널 선택해 발송 완료 | share_id, episode_id, scene_id, channel | episode-player 재사용 후보 |
| Event | view_share_viewer | 수신자가 공유 viewer 진입 | share_id, episode_id, is_logged_in, referrer | 신규 play-share 후보 |
| Event | click_share_viewer_cta | viewer에서 에피소드 CTA 클릭 | share_id, episode_id, is_logged_in | 신규 play-share 후보 |
| Event | block_share_play | 정책 ruleset 위반으로 공유 발행 차단 | episode_id, scene_id, reason | 신규 play-share 후보 |
6. Ubiquitous Language
| Term | Korean | Definition | Do Not Confuse With | Primary Domain | 상태 |
|---|---|---|---|---|---|
| Shared Play Snapshot | 공유 플레이 스냅샷 | 한 EpisodePlay의 특정 EpisodeScene을 외부 공유 가능한 read-only 단위로 묶은 record. share_id로 식별 | EpisodePlay 자체 / 단순 스크린샷 | Play | 신규 |
| Share Viewer | 공유 viewer | 공유 URL을 받은 수신자가 한 씬 미리보기 + 재플레이 CTA를 보는 웹 페이지 | 에피소드 상세 페이지 | Play | 신규 |
기존 용어(Episode, EpisodePlay, EpisodeScene, EpisodeFrame)는 Frontia UL 기존 정의 그대로 사용.
7. Open Questions
- [ ] 정량 목표 채움 — §1.5 4개 지표의 목표치를 출시 직전에 누가 어떤 데이터로 채우는가. 책임: 모모 + 데이터 agent.
- [ ] 재플레이 CTA 동작 정밀화 —
/episode/:episodeId→ 기존 이어보기 룰을 그대로 쓰는 게 수신자 의도("지금 이 씬을 보고 싶다")와 맞는가, 아니면 "처음부터" 강제할지. — 엔지니어 + PM - [ ] 디렉터 공유 toggle 권한 — 디렉터가 자기 에피소드 단위로 공유 on/off를 갖는가. 본 출시는 "전체 가능 + 어드민 강제 비활성화" 가정 — 디렉터 의견 / 운영
- [ ] 공유 record 만료 정책 — 무기한 / 30일 / 디렉터 비공개 전환 시 자동 만료 등 — 운영 + 엔지니어
- [ ] OG description 추출 룰 — narrative 첫 N자 / 핵심 line / 디렉터 작성 hook 중 무엇 — PM + 디렉터
- [ ] OG image 카드 디자인 — 컨셉(에피소드 썸네일 우선 / 씬 비주얼 우선 / 추상 카드) — 디자이너
- [ ] 공유 URL prefix 컨벤션 —
/p/:share_idvs/share/play/:share_idvs/play/:share_id. 향후 다른 공유 단위(에피소드·디렉터 프로필)와의 정합성 — 엔지니어 - [ ] 앱 딥링크 동작 —
frontia://share/play/:share_id진입 시 viewer를 앱에서 그릴지, 에피소드 상세로 바이패스할지 — 엔지니어 + 디자이너 - [ ] 카카오톡 OG description 80자 제한 실측 — 엔지니어
- [ ] 로깅 이벤트 그룹 재사용 vs 신규 확정 — event-docs(모모 세션)에서
episode-player그룹의 기존 share-류 이벤트 유무 확인 후 §5.2 그룹·이름 확정 — 모모 + 엔지니어 - [ ] 부적절 콘텐츠 발행 차단 ruleset connect — 기존 운영 정책 ruleset 재사용 — 운영
부록: 메타 정보
Required artifacts
- [x] Spec (
needs-spec) — 플레이 화면 공유 entry, 공유 viewer 페이지, 어드민 화면 명세 - [x] Design (
needs-design) — 공유 entry / viewer / OG card 시안 - [x] QA scenarios (
needs-qa-scenarios) — 공유 발행 → 수신자 동선 / 비활성화 / 만료 / 비공개 에피소드 케이스 - [x] Tracking events (
needs-tracking) — §5.2 5개 이벤트 - [x] 기타: BE 설계 문서 (공유 record entity / viewer endpoint / OG 렌더링 캐시 정책)
Size & Risks
- T-shirt Size: M
- Confidence: medium
주요 위험:
- 카카오톡 OG 호환 미스 → QA에 OG crawler 시뮬레이션 케이스 포함
- 디렉터 거부감 → 디렉터 커뮤니티 사전 공유, 옵트아웃 채널 마련
- 부적절 콘텐츠 외부 노출 → 어드민 강제 비활성화 + 운영 ruleset connect
- 비로그인 수신자 → 가입 funnel 데이터 부재 → share_id를 가입까지 끝까지 따라가는 분석 spec 명세 필수
References
- 관련 위키 문서:
- Play 도메인:
wiki/domains/play/index.md,wiki/domains/play/capabilities.md - Ubiquitous Language:
wiki/foundation/ubiquitous-language.md - DeepLink 노션 doc: https://www.notion.so/frontia-privacy/Frontia-App-DeepLink-2b5996f9506680aa9cb8d7579b412f6a
- Play 도메인:
- 관련 Linear 이슈: DEE-69
- 외부 레퍼런스: Open Graph Protocol (https://ogp.me), Web Share API, KakaoTalk OG 메타데이터 규칙
prd-review 보기
Review log
2026-05-13
사용자 부재 walk-through. criteria 기반 mechanical fix는 직접 반영, 정책·데이터 결정은 §7로 일괄 흡수.
채택
Q (D1): 메인 지표가 funnel 한 단만 측정. 발신자 발행 0이면 CTR 100%여도 실패.
- A: 메인 지표를 두 개(메인 A 발행률, 메인 B viewer→에피소드 CTR)로 분리.
- → §1.5 표 재구성 + 보조 지표는 viewer PV/발행 수, 신규 가입·플레이 시작으로 강등.
Q (D2): 정량 목표 모두 비어 있음. 채움 책임·시점 부재.
- A: 임계는 출시 직전 데이터 agent로 채우고 책임자(모모 + 데이터)를 §1.5와 §7에 명시.
- → §1.5 "목표" 열에 책임·시점 명시, §7에 채움 책임 OQ로 등재.
Q (D3): 가설 3(신규 가입 전환)이 base rate 없는데 메인급으로 등재.
- A: 가설 3을 "보조" 등급으로 강등하고 사유(base rate 미확보) 본문에 명시.
- → §1.4 가설 3에 "(보조)" + 사유 한 줄.
Q (D4): "이 씬부터 플레이하기" CTA가 OOS인데 §3-1·§7에 살아있어 정책 모순.
- A: §3-1 viewer CTA를 "에피소드 보러가기" 단일로 고정. "이 씬부터"는 §3-5 OOS로 명시, §7에서도 제거.
- → §3-1 C, §3-5, §7 동기화.
Q (Op1): §3-3 백엔드/시스템 섹션이 criteria reject 패턴.
- A: §3-3 섹션 통째 삭제. "공유 record 신규 entity 필요" 한 줄만 §3-5 In scope에 남김. OG 서버 렌더링은 §3-1 D 비즈니스 룰로 흡수, 어드민 비활성화는 §3-2로 흡수.
- → §3-3 제거.
Q (Op2): §🔍 검토 필요 메타 블록 — criteria가 "메타 섹션 만들지 말 것" 명시.
- A: 통째 삭제. 외부 agent 의존은 §1.2 근거·§1.5 책임자·§7 OQ로 흡수.
- → 섹션 제거.
Q (Op3): Negative spec 다수 (
⚠️ MVP는 전자만,프레임 단위는 후속등).- A: inline ⚠️ 부연 제거, OOS는 §3-5 한 곳에만 집결.
- → 본문 inline 제거 + §3-5 OOS 보강.
Q (Op4): 부록 위험 표·진행 패턴·추정 근거 산문.
- A: 위험 표는 의례적 표 형식 대신 bullet 4개로 축약(실 위험만). 진행 패턴 블록 제거. 추정 근거 산문 제거.
- → 부록 단순화.
Q (Op5): viewer 노출 단위가 "씬"인지 "씬+대표 frame"인지 spec 작업자 결정 불가.
- A: "공유된 씬의 narrative + 그 씬의 첫 frame을 대표 frame으로 자동 사용" 단정. (디렉터/유저 선택은 후속.)
- → §3-1 C에 단정문 추가.
Q (Op7): 딥링크 §3-4 항목이 §3-4·§7·§🚨 삼중 중복.
- A: §🚨 메타 블록 삭제(Op2)에 묶여 자연 해소. §3-4는 "신규 path 2개 미정 — §7"로 1줄 압축.
- → §3-4 단순화.
Q (Op8): §3-1 E "공유 이력 노출(선택, MVP 검토)"는 미정·미포함 후보를 본문에 둠.
- A: 섹션 삭제. §3-5 OOS로 흡수 + §7에 이미 등재된 OQ 유지.
- → §3-1 E 제거.
Skip
- Q (Op6): 로깅 이벤트 그룹 재사용 vs 신규를 PRD §5.2에서 확정해야 한다.
- 사유: agent가 event-docs(Cloudflare Access)에 접근 불가. 모모 세션에서만 가능 → 본 PRD §7에 OQ로 명시하고 spec 진입 전 모모가 확정하도록 위임. (Walk-through에서 모모가 직접 답할 때 본문 §5.2 그룹 fix.)
- → §5.2는 "재사용 후보 / 신규 후보" 표기로 두고 §7 OQ로 미룸.
모모 인라인 피드백 (criteria 후보)
(이번 세션은 walk-through 부재. 인라인 피드백 없음.)