# 크리에이터 채널 공유 PRD ## 문서 정보 | 항목 | 내용 | |---|---| | 문서 상태 | 구현 기준 확정 | | 작성일 | `2026-09-14` | | 최종 수정일 | `2026-09-15` | | 대상 제품 | 크리에이터 채널 공유 | | 작성자·결정권자 | 사용자 요청 기준 | | 관련 API Contract | 없음 | | 관련 구현 계획 | `docs/20260914_크리에이터_채널_공유/plan-task.md` | | 관련 review | `docs/20260914_크리에이터_채널_공유/reviews/phase1-creator-channel-share-review.md` | ### 요구사항 상태 | 상태 | 의미 | 구현 처리 | |---|---|---| | 확정 | 제품·기술 결정이 완료되어 구현 기준으로 사용 | `plan-task.md`의 Task와 완료 증거로 추적 | | 제외 | 현재 릴리스에서 구현하지 않기로 결정 | Non-Goals와 Decision Log에 기록 | ## 1. Overview 크리에이터 채널 화면에서 사용자가 현재 보고 있는 채널을 Android 공유 시트로 공유할 수 있게 한다. 내 채널은 우측 상단에 공유 버튼을 바로 노출하고, 다른 사람 채널은 우측 상단 더보기 BottomSheet 안에 `채널 공유` 항목을 추가한다. ## 2. Problem Statement 현재 크리에이터 채널 화면에는 채널 공유 진입점이 없다. 사용자는 크리에이터 채널을 외부 앱으로 공유하려면 기존 프로필 화면 같은 다른 경로를 찾아야 한다. 이 기능이 완료되면 크리에이터 채널 화면에서 소유자와 방문자 모두 같은 채널 공유 메시지를 Android 공유 시트로 보낼 수 있다. ## 3. Goals ### 3.1 제품 목표 - 내 채널 사용자는 크리에이터 채널 우측 상단 공유 버튼을 눌러 즉시 채널을 공유한다. - 다른 사람 채널 사용자는 우측 상단 더보기 버튼을 누른 뒤 `채널 공유`를 선택해 채널을 공유한다. - 공유 메시지와 링크 생성 방식은 `UserProfileActivity`의 기존 채널 공유 흐름과 동일하게 유지한다. ### 3.2 UX 목표 - 내 채널에서는 기존에 숨겨지던 우측 상단 영역에 공유 버튼만 표시한다. - 다른 사람 채널에서는 기존 follow, 알림, 더보기 동작을 유지하고 더보기 BottomSheet에 공유 항목을 추가한다. - 우측 상단 공유 버튼 아이콘은 `@drawable/ic_audio_content_share`를 사용한다. ## 4. Non-Goals - 신규 공유 API, 서버 계약, analytics event를 추가하지 않는다. - `UserProfileActivity`, `UserProfileViewModel` 같은 레거시 파일은 수정하지 않는다. - 공유 메시지 문구, OneLink 파라미터, chooser 제목을 새로 정의하지 않는다. - `app/src/androidTest`, 기기·에뮬레이터 UI 조작, 스크린샷 QA는 이번 범위에서 제외한다. ## 5. Target Users and Permissions | 사용자 | 목표 | 주요 작업 | 사용 환경 | |---|---|---|---| | 내 채널 소유자 | 내 채널 링크를 빠르게 외부 앱으로 공유 | 우측 상단 공유 버튼 탭 | Android 앱 | | 다른 사람 채널 방문자 | 방문 중인 채널 링크를 외부 앱으로 공유 | 더보기 BottomSheet에서 `채널 공유` 탭 | Android 앱 | ### 권한 - 인증 주체: 현재 앱 사용자. - 허용 역할: 내 채널 소유자와 다른 사람 채널 방문자 모두 허용. - 리소스 소유권: `CreatorChannelHeaderUiModel.isOwner`로 UI 진입점을 분기한다. - 거부 조건: `currentHeader`가 없거나 `creatorId <= 0`인 상태에서는 공유 액션을 실행하지 않는다. ## 6. 핵심 사용자 흐름 1. 사용자가 `CreatorChannelActivity`에 진입한다. 2. Activity가 채널 header를 로드하고 `currentHeader`를 갱신한다. 3. 내 채널이면 우측 상단 `ic_audio_content_share` 버튼이 표시되고, 기존 더보기 버튼은 계속 숨긴다. 4. 다른 사람 채널이면 기존 더보기 버튼이 표시되고, BottomSheet에 `채널 공유` 항목이 추가된다. 5. 공유 액션은 `Intent.ACTION_SEND`, `text/plain`, `Intent.EXTRA_TEXT`를 사용하고 chooser 제목은 `R.string.screen_user_profile_share_channel`을 사용한다. ## 7. 정보 구조와 라우팅 ```text CreatorChannelActivity 내 채널: title_action_container > iv_share 다른 사람 채널: iv_more > CreatorChannelMoreBottomSheet > tv_channel_share 공유 실행: Android ACTION_SEND chooser ``` - 딥링크 payload는 기존 프로필 공유와 동일하게 `deep_link_value=channel`, `deep_link_sub5={creatorId}`를 사용한다. - 공유 메시지는 기존 `소다라이브 ${nickname}님의 채널입니다.\n{shareUrl}` 형식을 유지한다. ## 8. 기능 요구사항 ### 8.1 채널 공유 진입점 | ID | 상태 | 요구사항 | 수용 기준 | 계약/Goal 연결 | |---|---|---|---|---| | `SHARE-001` | 확정 | 내 채널은 우측 상단에 공유 버튼을 바로 표시한다. | `header.isOwner == true`일 때 `iv_share`가 보이고 `iv_more`, follow, bell은 숨겨진다. | `P1-T1` | | `SHARE-002` | 확정 | 내 채널 우측 상단 공유 버튼은 `ic_audio_content_share`를 사용한다. | `activity_creator_channel.xml`의 공유 버튼 source가 `@drawable/ic_audio_content_share`다. | `P1-T1` | | `SHARE-003` | 확정 | 다른 사람 채널은 더보기 BottomSheet에 `채널 공유` 항목을 표시한다. | `header.isOwner == false`일 때 기존 더보기 진입 후 `tv_channel_share` 항목이 표시된다. | `P1-T2` | | `SHARE-004` | 확정 | 공유 실행은 기존 프로필 공유와 같은 Android chooser 흐름을 사용한다. | `Intent.ACTION_SEND`, `text/plain`, `Intent.EXTRA_TEXT`, `Intent.createChooser(..., screen_user_profile_share_channel)`가 사용된다. | `P1-T3` | ### 8.2 기존 동작 보존 | ID | 상태 | 요구사항 | 수용 기준 | 계약/Goal 연결 | |---|---|---|---|---| | `REG-001` | 확정 | 다른 사람 채널의 follow, bell, 더보기 표시 정책은 유지한다. | `bindTitleBar()`의 non-owner follow/bell/more 조건이 기존과 동일하다. | `P1-GATE` | | `REG-002` | 확정 | 더보기 BottomSheet의 차단, 유저 신고, 프로필 신고 동작은 유지한다. | 기존 callback 3개가 dismiss 후 동일하게 호출된다. | `P1-GATE` | ## 9. 반응형 기능 범위 | 기능 | Android Phone | 비고 | |---|---:|---| | 내 채널 공유 버튼 | 전체 | 기존 title bar 안에 24dp 아이콘으로 배치 | | 다른 사람 채널 공유 항목 | 전체 | 기존 BottomSheet vertical menu에 항목 추가 | ## 10. UI/UX Expectations - 내 채널 공유 버튼은 기존 우측 title action container 안에서 `iv_more`와 같은 크기·정렬 정책을 따른다. - 다른 사람 채널 BottomSheet의 `채널 공유` 항목은 기존 block/report 항목과 같은 typography, padding, 색상을 따른다. - contentDescription은 기존 title action button 관례가 없으므로 기능 label을 연결할 수 있으면 `screen_user_profile_share_channel`을 사용한다. ## 11. API 계약 - 신규 API 없음. - OneLink 생성은 기존 `Utils.createOneLinkUrl(params = mapOf("af_dp" to "voiceon://", "deep_link_value" to "channel", "deep_link_sub5" to "$creatorId"))` 흐름과 동일하다. ## 12. 보안과 데이터 취급 - 공유 텍스트에는 채널 닉네임과 공개 채널 링크만 포함한다. - `BuildConfig` 값, token, signed URL, 개인정보성 내부 ID를 log, Toast, crash message에 노출하지 않는다. - 내부 `creatorId`는 기존 공유 딥링크의 `deep_link_sub5` 값으로만 사용한다. ## 13. 성능과 품질 요구사항 - 네트워크 요청 없이 로컬 OneLink URL 생성과 Android chooser 실행만 수행한다. - 신규 dependency를 추가하지 않는다. - 자동 테스트는 `app/src/test`의 source/local unit test만 계획한다. - 전체 UI 계측 테스트와 스크린샷 QA는 사용자 명시 요청 전까지 실행하지 않는다. ## 14. 성공 기준 ### 14.1 기능 수용 기준 - [x] 내 채널에서 우측 상단 공유 버튼이 표시된다. (`SHARE-001`, `P1-T1`) - [x] 내 채널 공유 버튼이 `ic_audio_content_share`를 사용한다. (`SHARE-002`, `P1-T1`) - [x] 다른 사람 채널 더보기 BottomSheet에 `채널 공유`가 표시된다. (`SHARE-003`, `P1-T2`) - [x] 두 진입점 모두 기존 프로필 공유와 같은 chooser payload를 사용한다. (`SHARE-004`, `P1-T3`) ### 14.2 회귀 수용 기준 - [x] non-owner follow, bell, more 표시 정책이 유지된다. - [x] 기존 block/report/profile report BottomSheet callback이 유지된다. - [x] `UserProfileActivity`, `UserProfileViewModel`은 수정되지 않는다. 검증 기록: 2026-09-14 `CreatorChannelShareSourceTest`, `:app:mergeDebugResources`, `:app:assembleDebug`, `git diff --check`, review PASS 기준으로 체크했다. 2026-09-15 `ISSUE-001` 후속으로 `SharedPreferenceManager.can` 테스트 격리를 수정했고 `SharedPreferenceManagerTest`, `creator.channel.*`, `CreatorChannelShareSourceTest`, `git diff --check` PASS를 확인했다. 실제 앱 수동 테스트는 `plan-task.md`의 Phase 1 Gate 수동 검증에 별도 대기 항목으로 남긴다. ## 15. Open Questions | ID | 상태 | 결정 필요 사항 | 현재 권고 | 결정 주체 | 결정 기한/시점 | 영향 Goal | |---|---|---|---|---|---|---| | 없음 | 확정 | 추가 인터뷰 필요 항목 없음 | 현재 요구사항 그대로 구현 | 사용자 | 문서 작성 시점 | 없음 | ## 16. 요구사항 추적표 | 요구사항 범위 | API Contract | 계획 Phase | Goal | 자동 검증 | 수동 검증 | |---|---|---:|---|---|---| | `SHARE-001~002` | 없음 | 1 | `P1-T1` | `CreatorChannelShareSourceTest` | 내 채널 title bar 확인 | | `SHARE-003` | 없음 | 1 | `P1-T2` | `CreatorChannelShareSourceTest` | 타인 채널 BottomSheet 확인 | | `SHARE-004`, `REG-001~002` | 없음 | 1 | `P1-T3`, `P1-GATE` | `CreatorChannelShareSourceTest` | Android chooser 실행 확인 | ## 17. Decision Log | 날짜 | ID | 상태 | 결정 | 근거 | 영향 요구사항·계약·Goal | |---|---|---|---|---|---| | `2026-09-14` | `DEC-001` | 확정 | 내 채널은 우측 상단 직접 공유 버튼, 타인 채널은 더보기 BottomSheet 공유 항목으로 분기한다. | 사용자 요청 | `SHARE-001~003`, `P1-T1~T2` | | `2026-09-14` | `DEC-002` | 확정 | 공유 실행은 `UserProfileActivity` 887~902줄의 Android chooser 흐름과 동일하게 사용한다. | 사용자 요청 및 기존 코드 확인 | `SHARE-004`, `P1-T3` | | `2026-09-14` | `DEC-003` | 확정 | 레거시 프로필 파일은 수정하지 않고, 크리에이터 채널 v2 범위에서 기존 공유 방식만 재현한다. | 저장소 레거시 코드 사용 원칙 | `REG-002`, `P1-GATE` | ## 18. 변경 관리 - 요구사항 변경 시 Decision Log에 정정 행을 추가한다. - 구현 범위가 바뀌면 `plan-task.md` 체크리스트를 먼저 갱신한다. - 기존 완료 체크박스와 검증 기록은 삭제하거나 덮어쓰지 않는다.