# PRD: 크리에이터 채널 신규 페이지 ## 1. Overview 크리에이터의 대표 이미지, 팔로우/알림 상태, 대화/DM 진입 버튼, 탭 바, 홈 탭 컨텐츠를 포함한 크리에이터 채널 신규 페이지의 1차 범위를 Figma `296:14890` 기준으로 구현한다. --- ## 2. Problem - 크리에이터 상세 채널을 표시할 신규 페이지가 필요하다. - 크리에이터 채널 상단은 OS status bar 영역까지 이미지가 확장되어야 하며, 기존 일반 화면의 title bar/inset 처리와 다를 수 있다. - 팔로우 상태와 알림 수신 상태에 따라 title bar 우측 액션 구성이 달라져야 한다. - `대화하기`, `DM 보내기` 버튼은 권한 또는 서버 상태에 따라 없을 수 있어, 버튼 노출 조합별 배치 규칙이 필요하다. - 스크롤 시 tab-bar가 title-bar 아래에 고정되고, title-bar 배경색이 black으로 전환되는 상단 collapsing 동작이 필요하다. - 이번 범위는 크리에이터 채널의 전체 상단 구성과 `홈` 탭에 해당하는 컨텐츠만 포함하며, 나머지 탭의 상세 화면은 후속 범위로 분리해야 한다. - 홈 탭 진입 즉시 사용할 API와 서버 DTO가 확정되어 Android 구현 요구사항에 반영해야 한다. --- ## 3. Goals - Figma `296:14890`의 크리에이터 채널 신규 페이지 상단 구조를 정의한다. - 크리에이터 이미지 영역은 화면 최상단부터 OS status bar 영역까지 표시한다. - title bar에는 좌측 뒤로가기와 우측 더보기/팔로우/알림 상태 액션을 표시한다. - 팔로우하지 않은 상태, 팔로우 중이면서 알림 받기 중인 상태, 팔로우 중이지만 알림 받기 중이 아닌 상태를 구분해 아이콘을 표시한다. - 크리에이터 이미지 영역 내 `대화하기`, `DM 보내기` 버튼 노출 조합과 정렬 규칙을 정의한다. - tab-bar는 스크롤 중 title-bar 영역까지만 이동한 뒤 고정되며, 이후 아래 컨텐츠만 스크롤되도록 한다. - tab-bar와 title-bar가 가까워지는 스크롤 구간에서 title-bar 배경색을 black으로 변경한다. - tab-bar에는 `홈`, `라이브`, `오디오`, `시리즈`, `커뮤니티`, `팬Talk`, `후원`을 표시한다. - 크리에이터 채널 진입 시 `GET /api/v2/creator-channels/{creatorId}/home`을 호출해 상단 구성과 홈 탭 컨텐츠에 필요한 데이터를 표시한다. - 서버 DTO의 `CreatorActivityType`과 기존 홈 추천 API의 `RecommendedActivityType` 내용이 동일하므로, 홈 추천 전용 타입명을 공용 `CreatorActivityType`으로 변경하고 공용 패키지로 이동하는 요구사항을 정의한다. --- ## 4. Non-Goals - `라이브`, `오디오`, `시리즈`, `커뮤니티`, `팬Talk`, `후원` 탭을 선택했을 때의 탭별 상세 페이지와 pagination은 이번 범위에서 제외한다. - `Frame 1707482896`과 그 하위 레이어 중 `홈` 탭 첫 화면 구성에 필요한 데이터 표시 외 세부 상호작용은 이번 범위에서 제외한다. - 팔로우/언팔로우, 알림 켜기/끄기 API는 신규 API를 만들지 않고 기존 크리에이터 팔로우 API를 사용한다. - `대화하기`는 기존 `TalkApi.createChatRoom`으로 채팅방을 생성/조회한 뒤 반환된 `chatRoomId`로 `ChatRoomActivity`에 진입하고, `DM 보내기`는 신규 `DmChatRoomActivity`로 이동한다. 각 화면 내부 동작 변경은 이번 범위에서 제외한다. - 기존 크리에이터 랭킹 페이지, 채팅 탭, DM 채팅방 상세 화면의 동작을 변경하지 않는다. - Figma에 표시된 iOS status bar 컴포넌트 자체를 Android에 그대로 구현하지 않는다. Android system bar/inset 정책에 맞춰 이미지 확장 요구만 반영한다. --- ## 5. Target Users - 크리에이터 채널에서 크리에이터 정보와 컨텐츠 탭을 확인하려는 앱 사용자. - 크리에이터를 팔로우하거나 알림을 설정하려는 앱 사용자. - 크리에이터와 대화 또는 DM을 시작하려는 앱 사용자. - `kr.co.vividnext.sodalive.v2` 하위 신규 페이지를 구현/유지보수하는 Android 개발자. --- ## 6. User Stories - 사용자는 크리에이터 채널에 진입했을 때 대표 이미지와 크리에이터 정보를 먼저 보고 싶다. - 사용자는 상단에서 이전 화면으로 돌아가거나 더보기 메뉴를 열 수 있어야 한다. - 사용자는 팔로우하지 않은 크리에이터를 바로 팔로우할 수 있어야 한다. - 사용자는 팔로우 중인 크리에이터의 알림 수신 상태를 상단에서 확인하고 변경할 수 있어야 한다. - 사용자는 가능한 경우 크리에이터와 대화하거나 DM을 보낼 수 있어야 한다. - 사용자는 페이지를 스크롤해도 현재 선택 가능한 tab-bar가 상단에 고정되어 계속 접근 가능하길 기대한다. --- ## 7. Core Features ### Creator Channel Page Structure 크리에이터 채널 신규 페이지는 상단 이미지 영역, title bar, tab-bar, tab 하단 컨텐츠 영역으로 구성한다. #### Requirements - 전체 페이지 기준 Figma 노드는 `296:14890`이다. - 크리에이터 이미지 영역은 Figma `296:14892`의 `banner-creater`를 기준으로 한다. - title bar는 Figma `296:14893`의 `title-bar`를 기준으로 한다. - tab-bar는 Figma `296:14894`의 `tab-bar`를 기준으로 한다. - 크리에이터 이미지 영역은 OS status bar 영역까지 확장되어 표시되어야 한다. - title bar는 이미지 위에 overlay되는 형태로 배치한다. - tab-bar는 크리에이터 이미지 영역 하단에 배치한다. - tab-bar 하단 컨텐츠 영역 중 이번 구현 범위는 `홈` 탭 컨텐츠로 한정한다. - 크리에이터 채널 신규 페이지 진입 시 `creatorId`를 기준으로 홈 API를 즉시 호출한다. - 홈 API 응답의 `creator` 정보로 상단 이미지 영역, 팔로우/알림 상태, 대화/DM 버튼 노출 여부를 표시한다. - 홈 API 응답의 홈 탭 데이터로 현재 라이브, 최신 오디오, 후원, 공지, 일정, 오디오 컨텐츠, 시리즈, 커뮤니티, 팬Talk 요약, 소개, 활동, SNS 영역을 표시한다. #### Edge Cases - 크리에이터 이미지 URL이 비어 있거나 로딩 실패하면 기존 이미지 로딩/placeholder 정책을 따른다. - status bar 높이가 기기별로 달라도 이미지가 화면 최상단까지 자연스럽게 확장되어야 한다. - display cutout, gesture navigation, status bar inset 환경에서 title bar의 터치 영역이 status bar와 겹쳐 조작 불가능해지면 안 된다. ### Creator Channel Home API 크리에이터 채널 신규 페이지 진입 시 홈 탭과 상단 구성에 필요한 데이터를 조회한다. #### API Endpoint - `GET /api/v2/creator-channels/{creatorId}/home` #### Response Contract ```kotlin data class CreatorChannelHomeResponse( val creator: CreatorChannelCreatorResponse, val currentLive: CreatorChannelLiveResponse?, val latestAudioContent: CreatorChannelAudioContentResponse?, val channelDonations: List, val notices: List, val schedules: List, val audioContents: List, val series: List, val communities: List, val fanTalk: CreatorChannelFanTalkSummaryResponse, val introduce: String, val activity: CreatorChannelActivityResponse, val sns: CreatorChannelSnsResponse ) data class CreatorChannelCreatorResponse( val creatorId: Long, val characterId: Long?, val nickname: String, val profileImageUrl: String, val followerCount: Int, val isAiChatAvailable: Boolean, val isDmAvailable: Boolean, val isFollow: Boolean, val isNotify: Boolean ) data class CreatorChannelLiveResponse( val liveId: Long, val title: String, val coverImageUrl: String?, val beginDateTimeUtc: String, val price: Int, val isAdult: Boolean ) data class CreatorChannelAudioContentResponse( val audioContentId: Long, val title: String, val duration: String?, val imageUrl: String?, val price: Int, val isPointAvailable: Boolean, val isFirstContent: Boolean, val seriesName: String?, val isOriginalSeries: Boolean? ) data class CreatorChannelDonationResponse( val donationId: Long, val memberId: Long, val nickname: String, val profileImageUrl: String, val can: Int, val isSecret: Boolean, val message: String, val createdAtUtc: String ) data class CreatorChannelScheduleResponse( val scheduledAtUtc: String, val title: String, val type: CreatorActivityType, val targetId: Long ) data class CreatorChannelSeriesResponse( val seriesId: Long, val title: String, val coverImageUrl: String, val publishedDaysOfWeek: String, val isComplete: Boolean, val numberOfContent: Int, val isNew: Boolean, val isPopular: Boolean, val isOriginal: Boolean ) data class CreatorChannelCommunityPostResponse( val postId: Long, val creatorId: Long, val creatorNickname: String, val creatorProfileUrl: String, val imageUrl: String?, val audioUrl: String?, val content: String, val price: Int, val dateUtc: String, val existOrdered: Boolean, val likeCount: Int, val commentCount: Int ) data class CreatorChannelFanTalkSummaryResponse( val totalCount: Int, val latestFanTalk: CreatorChannelFanTalkResponse? ) data class CreatorChannelFanTalkResponse( val fanTalkId: Long, val memberId: Long, val nickname: String, val profileImageUrl: String, val content: String, val languageCode: String?, val createdAtUtc: String ) data class CreatorChannelActivityResponse( val debutDateUtc: String?, val dDay: String, val liveCount: Long, val liveDurationHours: Long, val liveContributorCount: Long, val audioContentCount: Long, val seriesCount: Long ) data class CreatorChannelSnsResponse( val instagramUrl: String, val fancimmUrl: String, val xUrl: String, val youtubeUrl: String, val kakaoOpenChatUrl: String ) enum class CreatorActivityType(val code: String) { LIVE("LIVE"), AUDIO("AUDIO"), COMMUNITY("COMMUNITY"), LIVE_REPLAY("LIVE_REPLAY") } ``` - 백엔드 `CreatorActivityType` 원본 enum은 `LIVE`, `AUDIO`, `COMMUNITY`, `LIVE_REPLAY` 대문자 상수와 동일한 `code`를 내려준다. - Android DTO의 `CreatorChannelScheduleResponse.type`은 위 서버 계약을 전제로 공용 `CreatorActivityType` enum을 직접 사용한다. - 홈 추천 등 클라이언트 내부 helper에서 대소문자 무시 파싱을 지원하더라도, 크리에이터 채널 홈 API DTO 리뷰에서는 서버가 소문자/혼합 대소문자 값을 내려주는 경우를 별도 전제로 문제 제기하지 않는다. #### Requirements - `creatorId`는 페이지 진입 인자로 전달받고, `creatorId > 0`일 때만 홈 API를 호출한다. - `creator.nickname`, `creator.profileImageUrl`, `creator.followerCount`를 크리에이터 이미지 영역의 기본 정보로 사용한다. - `creator.characterId`는 `대화하기` 버튼 터치 시 `TalkApi.createChatRoom` 요청의 `characterId`로 사용한다. - `creator.isFollow`, `creator.isNotify`를 title bar 팔로우/알림 상태 표시의 기준으로 사용한다. - `creator.isAiChatAvailable`이 `true`이고 `creator.characterId`가 null이 아닐 때만 `대화하기` 버튼을 표시한다. - `creator.isDmAvailable`이 `true`일 때만 `DM 보내기` 버튼을 표시한다. - 홈 탭 영역은 `CreatorChannelHomeResponse`의 top-level 필드를 사용해 Figma 홈 구성에 맞춰 표시한다. - nullable 필드인 `currentLive`, `latestAudioContent`, `coverImageUrl`, `imageUrl`, `audioUrl`, `latestFanTalk`, `debutDateUtc`, `languageCode`, `duration`, `seriesName`, `isOriginalSeries`는 null 가능성을 전제로 UI 표시 여부를 결정한다. #### Edge Cases - 홈 API 실패 시 기존 네트워크 오류 처리 정책에 맞춰 crash 없이 처리한다. - list 필드가 빈 배열이면 해당 홈 섹션은 기존 Figma/앱 empty 정책에 맞춰 숨기거나 비어 있는 상태로 표시한다. - `creatorId <= 0`이면 API를 호출하지 않고 기존 잘못된 진입 처리 정책을 따른다. ### Title Bar 상단 title bar는 뒤로가기, 팔로우/알림 상태 액션, 더보기 액션을 제공한다. #### Requirements - 좌측 상단 뒤로가기 아이콘은 `ic_new_bar_back`을 사용한다. - 우측 상단 더보기 아이콘은 `ic_new_more`를 사용한다. - 팔로우 상태가 아닐 때는 `ic_new_follow`를 표시한다. - 팔로우 중이고 알림 받기 중일 때는 `ic_new_following`, `ic_bar_bell_colored`를 표시한다. - 팔로우 중이고 알림 받기 중이 아닐 때는 `ic_new_following`, `ic_bar_bell`을 표시한다. - title bar 액션은 Figma 상태별 노드를 기준으로 시각 배치를 맞춘다. - 뒤로가기 터치 시 이전 화면으로 이동한다. - 더보기 터치 시 기존 앱의 크리에이터/프로필 더보기 메뉴 패턴을 따른다. - 팔로우/알림 상태 변경은 기존에 사용하던 크리에이터 팔로우 API를 재사용한다. - 팔로우/알림 상태 변경 성공 후 title bar의 `isFollow`, `isNotify` 표시 상태를 갱신한다. #### State References | State | Figma Node | Icons | | --- | --- | --- | | 팔로우 상태가 아님 | `296:14287` | `ic_new_follow` | | 팔로우 중 + 알림 받기 중 | `296:14288` | `ic_new_following`, `ic_bar_bell_colored` | | 팔로우 중 + 알림 받기 중이 아님 | `296:14289` | `ic_new_following`, `ic_bar_bell` | #### Edge Cases - 팔로우 상태 데이터가 아직 로딩 중이면 잘못된 상태 전환이 보이지 않도록 기존 로딩 정책에 맞춰 처리한다. - 팔로우/알림 상태 변경 요청 중 중복 탭으로 동일 요청이 여러 번 전송되지 않도록 한다. - title bar 배경이 투명한 상태에서도 아이콘이 이미지 위에서 식별 가능해야 한다. ### Creator Image Area Actions 크리에이터 이미지 영역에는 `대화하기`, `DM 보내기` 액션 버튼을 표시할 수 있다. #### Requirements - `대화하기` 아이콘은 `ic_new_talk`를 사용한다. - `DM 보내기` 아이콘은 `ic_new_dm`을 사용한다. - `대화하기`, `DM 보내기` 버튼은 둘 다 없을 수 있다. - 두 버튼이 모두 보일 때는 Figma `296:14892`의 버튼 영역 배치를 따른다. - 두 버튼 중 하나만 보일 때는 해당 버튼을 가운데 표시한다. - 두 버튼이 모두 보이지 않더라도 버튼 영역의 높이와 여백은 보존한다. - `대화하기` 버튼은 `creator.isAiChatAvailable=true`이고 `creator.characterId`가 null이 아닐 때 표시한다. - `DM 보내기` 버튼은 `creator.isDmAvailable=true`일 때 표시한다. - `대화하기` 버튼 터치 시 `TalkApi.createChatRoom`에 `CreateChatRoomRequest(characterId)`를 전달하고, 성공 응답의 `chatRoomId`를 사용해 `ChatRoomActivity.newIntent(context, roomId)`로 이동한다. - `DM 보내기` 버튼 터치 시 신규 `DmChatRoomActivity`로 이동한다. #### Edge Cases - 버튼 문구가 현지화 또는 서버 문구로 길어져도 버튼 내부 텍스트가 잘리거나 겹치면 안 된다. - 하나의 버튼만 표시될 때 좌우 여백 불균형이 보이지 않도록 중앙 정렬한다. - 두 버튼이 모두 숨김이어도 크리에이터 이미지 영역의 하단 정보와 tab-bar 위치가 갑자기 위로 당겨지면 안 된다. ### Tab Bar And Scroll Behavior tab-bar는 스크롤 중 title-bar 하단에 고정되는 sticky 영역으로 동작한다. #### Requirements - tab-bar 목록은 `홈`, `라이브`, `오디오`, `시리즈`, `커뮤니티`, `팬Talk`, `후원` 순서로 표시한다. - 이번 범위에서 기본 선택 탭은 `홈`이다. - 이번 범위에서는 `홈` 탭 컨텐츠만 구현한다. - `라이브`, `오디오`, `시리즈`, `커뮤니티`, `팬Talk`, `후원` 탭의 상세 컨텐츠 구현은 후속 범위로 둔다. - tab-bar는 탭 개수가 7개인 상태에서 가로 스크롤 또는 동적 item 폭 등 기존 tab 컴포넌트 정책에 맞춰 표시되어야 한다. - 사용자가 페이지를 위로 스크롤하면 크리에이터 이미지 영역은 스크롤되어 사라질 수 있다. - tab-bar는 완전히 화면 밖으로 사라지지 않고 title-bar 영역까지만 이동한 뒤 고정된다. - tab-bar가 고정된 이후에는 tab-bar 아래 컨텐츠만 세로 스크롤된다. - 스크롤 시 title-bar와 tab-bar의 실제 거리, 그리고 프로필 이미지가 절반 이상 사라졌는지를 함께 기준으로 title bar의 배경색을 black으로 변경한다. - 스크롤이 다시 상단으로 돌아오면 title-bar 배경은 Figma 초기 상태에 맞게 이미지 overlay 상태로 복귀한다. #### Edge Cases - 빠른 fling 중에도 tab-bar 고정 위치가 흔들리거나 title-bar와 겹치면 안 된다. - tab-bar 고정 상태에서 탭을 변경해도 스크롤/고정 상태가 깨지면 안 된다. - 7개 탭이 가로 폭을 초과해도 탭 선택과 스크롤 동작이 유지되어야 한다. - status bar 높이와 title bar 높이를 고려해 sticky 기준 위치를 계산해야 한다. ### Home Tab Content `홈` 탭은 크리에이터 채널 홈 API 응답을 사용해 Figma 전체 페이지의 홈 컨텐츠를 표시한다. #### Requirements - `currentLive`가 있으면 현재 라이브 영역에 표시한다. - `latestAudioContent`가 있으면 최신 오디오 컨텐츠 영역에 표시한다. - `channelDonations`는 후원 요약/목록 영역에 표시한다. - `notices`는 공지 영역에 표시한다. - `schedules`는 크리에이터 일정 영역에 표시한다. - `audioContents`는 오디오 컨텐츠 섹션에 표시한다. - `series`는 시리즈 섹션에 표시한다. - `communities`는 커뮤니티 게시글 섹션에 표시한다. - `fanTalk`는 팬Talk 요약 영역에 표시한다. - `introduce`는 소개 영역에 표시한다. - `activity`는 활동 정보 영역에 표시한다. - `sns`는 SNS 링크 영역에 표시한다. - 홈 탭의 각 섹션은 Figma `296:14890`의 홈 화면 순서와 기존 위젯/목록 패턴을 우선 따른다. #### Edge Cases - `currentLive` 또는 `latestAudioContent`가 null이면 해당 단일 컨텐츠 영역은 표시하지 않거나 기존 empty 정책을 따른다. - list 필드가 빈 배열이면 섹션 자체를 숨길지 빈 상태를 표시할지는 기존 홈/크리에이터 화면 정책을 우선 따른다. - SNS URL 문자열이 빈 값이면 해당 SNS 진입 아이콘 또는 버튼은 비활성/숨김 처리한다. ### CreatorActivityType Commonization 홈 추천 API에서 사용 중인 `RecommendedActivityType`은 크리에이터 채널 홈 API의 `CreatorActivityType`과 동일한 의미를 가지므로 공용 타입으로 정리한다. #### Requirements - 기존 `RecommendedActivityType`의 enum/value 내용은 서버의 `CreatorActivityType`과 동일하게 유지한다. - `RecommendedActivityType`이 홈 추천 전용으로만 쓰이는 이름이 아니므로 `CreatorActivityType`으로 변경한다. - 변경한 `CreatorActivityType`은 홈 추천 패키지가 아닌 공용 패키지로 이동한다. - 기존 홈 추천 API DTO와 신규 크리에이터 채널 홈 API DTO는 동일한 `CreatorActivityType`을 참조한다. - 타입명 변경으로 기존 홈 추천 화면의 동작이 달라지면 안 된다. --- ## 8. UX / UI Expectations - 전체 배경은 Figma `296:14890`과 동일한 black 계열을 유지한다. - 크리에이터 대표 이미지는 첫 화면에서 가장 큰 시각 요소로 노출한다. - title bar 초기 상태는 이미지 위 overlay로 보이며, 스크롤 임계점 이후 black 배경으로 전환된다. - title bar 아이콘은 Figma에 지정된 신규 아이콘 리소스를 사용한다. - 팔로우/알림 상태별 아이콘 조합은 사용자가 현재 상태를 즉시 구분할 수 있어야 한다. - `대화하기`, `DM 보내기` 버튼은 노출 여부와 무관하게 이미지 영역 내 레이아웃 안정성을 유지한다. - tab-bar는 화면 상단에 고정된 뒤에도 title bar와 시각적으로 충돌하지 않아야 한다. - tab-bar는 `홈`, `라이브`, `오디오`, `시리즈`, `커뮤니티`, `팬Talk`, `후원` 7개 탭을 자연스럽게 표시해야 한다. - `홈` 탭은 크리에이터 채널 진입 직후 바로 표시되는 기본 화면이다. - Android 기기별 status bar/inset 차이로 인해 상단 이미지, title bar, tab-bar의 수직 위치가 어긋나면 안 된다. --- ## 9. Technical Constraints - Android XML Views, ViewBinding, RecyclerView/NestedScroll 계열의 기존 프로젝트 구조를 우선 확인해 따른다. - 신규 `Activity`, `Fragment`, `ViewModel` 및 연결 하위 코드는 `kr.co.vividnext.sodalive.v2` 패키지 하위에 작성한다. - 구현 전 `docs/20260611_크리에이터_채널_홈_탭/plan-task.md`를 작성한 뒤 해당 계획에 따라 최소 구현한다. - 기존에 존재하는 icon drawable 리소스가 있으면 재사용하고, 없는 경우 제공된 리소스명으로 추가한다. - system bar 영역 확장은 Android edge-to-edge/inset 처리와 기존 앱의 status bar 정책을 확인한 뒤 적용한다. - tab-bar sticky 동작은 기존 화면의 app bar/collapsing/header scroll 구현 패턴이 있으면 우선 재사용한다. - 홈 API는 `GET /api/v2/creator-channels/{creatorId}/home` 계약을 따른다. - 홈 API의 schedule `type`은 백엔드 `CreatorActivityType` 원본 enum과 동일하게 `LIVE`, `AUDIO`, `COMMUNITY`, `LIVE_REPLAY` 중 하나로 내려오므로 Android DTO에서 공용 enum을 직접 사용한다. - 팔로우/알림 변경은 기존 크리에이터 팔로우 API 사용 패턴을 재사용한다. - `대화하기` 이동은 `CharacterDetailViewModel.createChatRoom`과 동일하게 `TalkApi.createChatRoom` 호출 후 `ChatRoomActivity`로 이동하는 패턴을 따른다. - `DM 보내기` 이동은 신규 `DmChatRoomActivity` 사용 패턴을 따른다. - `RecommendedActivityType`을 `CreatorActivityType`으로 변경하고 공용 패키지로 이동할 때, 홈 추천 API의 기존 참조도 함께 갱신한다. - navigation extra 이름, analytics/logging은 근거 파일이나 별도 요구가 확인되기 전까지 임의로 추가하지 않는다. --- ## 10. Metrics - 크리에이터 이미지 영역이 OS status bar 영역까지 표시된다. - title bar 좌측에는 `ic_new_bar_back`, 우측에는 `ic_new_more`가 표시된다. - 팔로우하지 않은 상태에서 `ic_new_follow`가 표시된다. - 팔로우 중 + 알림 받기 중 상태에서 `ic_new_following`, `ic_bar_bell_colored`가 표시된다. - 팔로우 중 + 알림 받기 중이 아닌 상태에서 `ic_new_following`, `ic_bar_bell`이 표시된다. - `대화하기`, `DM 보내기` 버튼이 모두 보일 때 Figma 기준 배치를 따른다. - `대화하기`, `DM 보내기` 버튼 중 하나만 보일 때 해당 버튼이 가운데 표시된다. - `대화하기`, `DM 보내기` 버튼이 모두 보이지 않아도 버튼 영역 높이와 여백이 보존된다. - `creator.isAiChatAvailable=true`이고 `creator.characterId`가 null이 아닐 때만 `대화하기` 버튼이 표시된다. - `creator.isDmAvailable=true`일 때만 `DM 보내기` 버튼이 표시된다. - `대화하기` 버튼 터치 시 `TalkApi.createChatRoom`을 호출하고, 성공 응답의 `chatRoomId`로 `ChatRoomActivity`에 이동한다. - `DM 보내기` 버튼 터치 시 `DmChatRoomActivity`로 이동한다. - tab-bar에 `홈`, `라이브`, `오디오`, `시리즈`, `커뮤니티`, `팬Talk`, `후원`이 표시된다. - 크리에이터 채널 진입 시 `GET /api/v2/creator-channels/{creatorId}/home`이 호출된다. - 홈 API 응답의 `creator.isFollow`, `creator.isNotify`가 title bar 상태 표시 기준으로 사용된다. - 홈 API 응답의 `currentLive`, `latestAudioContent`, `channelDonations`, `notices`, `schedules`, `audioContents`, `series`, `communities`, `fanTalk`, `introduce`, `activity`, `sns`가 홈 탭 표시 데이터로 사용된다. - 스크롤 시 tab-bar가 title-bar 영역까지 이동한 뒤 고정된다. - tab-bar 고정 이후 하단 컨텐츠만 스크롤된다. - title-bar와 tab-bar의 실제 거리 및 프로필 이미지가 절반 이상 사라진 상태를 기준으로 title-bar 배경색이 black으로 변경된다. - `RecommendedActivityType`은 공용 `CreatorActivityType`으로 변경되고, 홈 추천 API와 크리에이터 채널 홈 API가 같은 타입을 참조한다. - `라이브`, `오디오`, `시리즈`, `커뮤니티`, `팬Talk`, `후원` 탭 상세 화면은 이번 구현 범위로 사용되지 않는다. --- ## 11. Open Questions - 크리에이터 채널 신규 페이지의 진입점과 전달받을 Android extra 또는 navigation argument 이름은 구현 계획에서 기존 이동 패턴을 확인해 확정한다. - 홈 탭 각 섹션의 empty 상태를 섹션 숨김으로 처리할지, 빈 상태 UI로 처리할지는 기존 크리에이터/홈 화면 패턴 확인이 필요하다. - 팔로우/알림 변경 성공 후 홈 API를 재조회할지, 로컬 상태만 갱신할지는 기존 크리에이터 팔로우 API 사용 패턴 확인이 필요하다. --- ## 12. References - 전체 페이지 Figma: https://www.figma.com/design/HmN1yNdJ3EIpqknFL0Hkab/-%EA%B3%B5%EC%9C%A0%EC%9A%A9-%EB%B3%B4%EC%9D%B4%EC%8A%A4%EC%98%A8-UI-UX-%EA%B8%B0%ED%9A%8D%EB%AC%B8%EC%84%9C?node-id=296-14890&m=dev - 팔로우 상태가 아닐 때 Figma: https://www.figma.com/design/HmN1yNdJ3EIpqknFL0Hkab/-%EA%B3%B5%EC%9C%A0%EC%9A%A9-%EB%B3%B4%EC%9D%B4%EC%8A%A4%EC%98%A8-UI-UX-%EA%B8%B0%ED%9A%8D%EB%AC%B8%EC%84%9C?node-id=296-14287&m=dev - 팔로우 중 + 알림 받기 중 Figma: https://www.figma.com/design/HmN1yNdJ3EIpqknFL0Hkab/-%EA%B3%B5%EC%9C%A0%EC%9A%A9-%EB%B3%B4%EC%9D%B4%EC%8A%A4%EC%98%A8-UI-UX-%EA%B8%B0%ED%9A%8D%EB%AC%B8%EC%84%9C?node-id=296-14288&m=dev - 팔로우 중 + 알림 받기 중이 아닐 때 Figma: https://www.figma.com/design/HmN1yNdJ3EIpqknFL0Hkab/-%EA%B3%B5%EC%9C%A0%EC%9A%A9-%EB%B3%B4%EC%9D%B4%EC%8A%A4%EC%98%A8-UI-UX-%EA%B8%B0%ED%9A%8D%EB%AC%B8%EC%84%9C?node-id=296-14289&m=dev - 크리에이터 이미지 영역 Figma: https://www.figma.com/design/HmN1yNdJ3EIpqknFL0Hkab/-%EA%B3%B5%EC%9C%A0%EC%9A%A9-%EB%B3%B4%EC%9D%B4%EC%8A%A4%EC%98%A8-UI-UX-%EA%B8%B0%ED%9A%8D%EB%AC%B8%EC%84%9C?node-id=296-14892&m=dev - 사용자 제공 홈 API Endpoint: `GET /api/v2/creator-channels/{creatorId}/home` - PRD 샘플: `docs/prd/sample-prd.md` - 문서 작성 규칙: `docs/agent-guides/work-plan-docs.md` --- ## 13. Verification Log - 2026-06-11: `AGENTS.md`, `docs/agent-guides/work-plan-docs.md`, `docs/prd/sample-prd.md`를 확인해 신규 문서 경로와 PRD 구성 규칙을 확인했다. - 2026-06-11: Figma `296:14890` metadata와 screenshot을 확인해 `banner-creater`, `title-bar`, `tab-bar`, `StatusBar / iPhone 13`, 제외 대상 `Frame 1707482896` 구조를 확인했다. - 2026-06-11: 사용자 제공 요구사항에 따라 title bar 아이콘, 팔로우/알림 상태별 아이콘, 크리에이터 이미지 영역 버튼 노출 규칙, status bar 영역 이미지 표시, sticky tab-bar 및 title-bar black 전환 요구사항을 PRD에 반영했다. - 2026-06-11: 이번 단계는 PRD 작성만 수행했으며 구현/빌드/테스트는 실행하지 않았다. - 2026-06-12: 사용자 추가 제공 요구사항에 따라 이번 범위를 크리에이터 채널 전체 구성과 `홈` 탭으로 한정하고, tab-bar 7개 항목, 홈 API Endpoint, 서버 DTO, 기존 크리에이터 팔로우 API 재사용, `대화하기`/`DM 보내기` 이동 대상, `CreatorActivityType` 공용화, title bar black 전환 기준을 PRD에 반영했다. - 2026-06-12: 이번 단계는 PRD 문서 보완만 수행했으며 구현/빌드/테스트는 실행하지 않았다. - 2026-06-12: 문서 범위가 크리에이터 채널 신규 페이지 전체가 아니라 홈 탭 1차 범위임을 명확히 하기 위해 문서 폴더명을 `docs/20260611_크리에이터_채널_신규_페이지/`에서 `docs/20260611_크리에이터_채널_홈_탭/`으로 변경했다. - 2026-06-12: 사용자 추가 요구사항에 따라 `CreatorChannelCreatorResponse.characterId: Long?`를 추가하고, `대화하기` 이동을 `TalkApi.createChatRoom` 호출 후 반환된 `chatRoomId`로 `ChatRoomActivity`에 진입하는 흐름으로 변경했다. - 2026-06-13: Phase 2/3 구현으로 `RecommendedActivityType`을 공용 `CreatorActivityType`으로 이동하고 홈 추천 참조를 갱신했으며, 크리에이터 채널 홈 API/DTO/Repository와 Koin API/Repository 등록을 추가했다. - 2026-06-13: `CreatorChannelCreatorResponse.characterId: Long?`, `CreatorChannelScheduleResponse.type: CreatorActivityType`, `GET /api/v2/creator-channels/{creatorId}/home` 계약이 구현 DTO/API에 반영됨을 테스트와 컴파일로 확인했다. - 2026-06-13: 검증으로 `v2.common.*`, `v2.creatorchannel.*`, `compileDebugKotlin`, `mergeDebugResources`, `ktlintCheck`는 성공했다. `v2.main.home.*` 전체 실행은 기존 source-path 테스트의 `FileNotFoundException`으로 일부 실패했으며, 타입 공용화 관련 focused 홈 테스트는 성공했다. - 2026-06-13: 백엔드 `CreatorActivityType` 원본 enum이 `LIVE`, `AUDIO`, `COMMUNITY`, `LIVE_REPLAY` 대문자 상수와 동일한 `code`를 사용함을 확인해 Android Gson enum 파싱용 별도 TypeAdapter는 추가하지 않기로 판단했다. - 2026-06-13: 사용자 추가 요청에 따라 신규 크리에이터 채널 홈 패키지를 `kr.co.vividnext.sodalive.v2.creatorchannel`에서 `kr.co.vividnext.sodalive.v2.creator.channel`로 변경했다. - 2026-06-13: 사용자 확인에 따라 백엔드 `CreatorActivityType` 원본 enum과 동일한 대문자 code 계약을 API 계약/기술 제약에 명시했다. 이후 코드리뷰에서는 별도 서버 계약 변경 근거가 없는 한 크리에이터 채널 홈 DTO의 `CreatorActivityType` 직접 사용과 Gson enum TypeAdapter 부재를 대소문자 대응 문제로 제기하지 않는다. 이번 단계는 문서 수정만 수행했으며 빌드/테스트는 실행하지 않았다.