31 KiB
31 KiB
PRD: 크리에이터 채널 홈 탭
1. Overview
크리에이터 채널 화면은 title bar, 크리에이터 프로필 header, tab-bar를 공통 shell로 유지하고, tab-bar 아래 콘텐츠만 선택된 탭에 따라 교체한다. 채널 최초 진입 시 기본 선택 탭은 홈이며, 홈 탭에서는 신규 API GET /api/v2/creator-channels/{creatorId}/home 응답을 사용해 현재 라이브, 최신 오디오 콘텐츠, 후원, 공지, 스케줄, 오디오, 시리즈, 커뮤니티, 팬Talk, 소개, 활동, SNS 정보를 표시한다.
API 연동을 먼저 구현하고, UI는 공통 shell과 홈 탭 콘텐츠를 분리한 뒤 API 응답 데이터를 기준으로 Figma 섹션 단위로 나누어 순차 구현한다.
Figma 전체 화면 기준 공통 shell은 아래를 따른다.
- title bar
- 크리에이터 이미지/프로필 header
- tab-bar
Figma 전체 화면 기준 홈 탭 콘텐츠 순서는 아래를 따른다.
- 대화하기 액션 영역
- 현재 라이브
- 최신 오디오 콘텐츠
- 채널 후원
- 공지
- 스케줄
- 오디오
- 시리즈
- 커뮤니티
- 팬Talk
- 소개
- 활동
- SNS
상단 tab-bar 항목은 홈, 라이브, 오디오, 시리즈, 커뮤니티, 팬Talk, 후원으로 구성한다. Figma에는 화보 탭과 활동 항목이 보이지만 이번 구현 범위에서는 제외한다.
2. Problem
- 기존 크리에이터 상세/채널 화면은 신규
creator-channels홈 API 응답 구조와 Figma의 채널 홈 구성을 그대로 반영하지 못한다. - 홈 API는 크리에이터 프로필과 여러 도메인 데이터를 한 endpoint에서 받지만, 크리에이터 프로필은 채널 공통 shell에 쓰이고 나머지 섹션은 홈 탭 콘텐츠에 쓰인다. 이를 한 View에 직접 구현하면 이후 탭별 화면 확장 시 유지보수와 검증이 어려워진다.
- 크리에이터 이미지 영역이 OS status bar 영역까지 확장되고, scroll 위치에 따라 title bar/tab-bar/status bar 상태가 함께 변해야 하므로 일반적인 정적 navigation bar로 처리하기 어렵다.
- tab-bar는 title bar와 붙는 순간 sticky 상태가 되어야 하고, sticky 이후에는 아래 콘텐츠만 스크롤되어야 한다.
isAiChatAvailable값에 따라 대화하기 버튼 노출이 달라지지만, 버튼이 없어도 액션 영역 높이는 유지해야 한다.- 선택된 tab 및 홈 섹션의
전체보기진입 화면은 전체 기능 구현 전에도 placeholder destination이 필요하다.
3. Goals
creatorId로GET /api/v2/creator-channels/{creatorId}/home을 호출하고 응답 데이터로 크리에이터 채널 공통 shell과 홈 탭 콘텐츠를 구성한다.- 신규 API, Repository, ViewModel, Response model은
SodaLive/Sources/V2/**하위에 둔다. - API 구현을 UI보다 먼저 완료해 공통 shell과 홈 탭 섹션들이 동일한 response model을 사용하도록 한다.
CreatorChannelView는 title bar, header, tab-bar, 선택된 tab 상태, 홈 API 호출 상태를 소유한다.CreatorChannelHomeView는 tab-bar 아래 홈 탭 콘텐츠만 렌더링한다.- 홈 API 응답의
creator정보는 공통 shell의 header/title/follow/notification/action 상태에 반영한다. - Figma 기준 섹션을 이후
plan-task.md에서 phase 단위로 나눌 수 있도록 요구사항을 분리한다. - 크리에이터 대표 이미지는 화면 최상단에서 OS status bar 영역까지 확장해 표시한다.
- scroll 진행도에 따라 title bar 배경색을 점진적으로 black에 가깝게 변경한다.
- tab-bar가 title bar와 맞닿으면 sticky 상태로 고정하고, sticky 이후 OS status bar 배경도 title bar와 동일하게 보이도록 처리한다.
- title bar는
isFollow,isNotify상태에 따라 Figma의 Unfollow, Follow+알림 설정, Follow+알림 해제 상태를 표시한다. - 홈 tab 외 tab-bar 항목 및 홈 섹션의 전체보기 destination은 placeholder 형태로 먼저 연결한다.
- V2 하위의 재사용 가능한 공용 컴포넌트는 우선 재사용한다.
- 빈 섹션은 section title과 empty state를 표시하지 않고 숨긴다.
4. Non-Goals
화보탭과 화보 섹션은 구현하지 않는다.- 이번 API 스펙에 없는 페이지네이션, 무한 스크롤, 섹션별 필터/정렬 기능을 추가하지 않는다.
- 후원 작성, 댓글/좋아요, 커뮤니티 구매, 콘텐츠 구매의 실제 mutation 구현은 이번 PRD의 필수 범위로 보지 않는다.
- DM 버튼 및 DM 보내기 진입은 추후 작업으로 미루고 이번 범위에서 구현하지 않는다.
- 라이브룸, 오디오 상세, 시리즈 상세, 커뮤니티 상세, 팬Talk 전체, 후원 전체의 실제 상세 기능을 새로 구현하지 않는다. 기존 진입 흐름이 있으면 연결하고, 없으면 placeholder로 둔다.
- Figma localhost asset URL을 앱 코드에 직접 사용하지 않는다.
Pods/**,generated/**,build/**는 수정하지 않는다.
5. Target Users
- 크리에이터 채널에서 라이브, 콘텐츠, 커뮤니티, 후원, 팬Talk 정보를 한 번에 확인하려는 사용자
- 크리에이터를 팔로우하거나 알림 상태를 확인하려는 사용자
- 크리에이터와 AI 대화로 이동하려는 사용자
- 특정 섹션의 전체 목록으로 이동해 더 많은 콘텐츠를 탐색하려는 사용자
6. User Stories
- 사용자는 크리에이터 채널 홈에서 크리에이터 이미지, 닉네임, 팔로워 수를 확인하고 싶다.
- 사용자는 팔로우하지 않은 크리에이터를 title bar에서 팔로우하고 싶다.
- 사용자는 팔로우한 크리에이터의 알림 설정 상태를 title bar에서 구분하고 싶다.
- 사용자는 현재 진행 중인 라이브가 있으면 홈 상단에서 바로 확인하고 싶다.
- 사용자는 최신 오디오 콘텐츠와 오디오 목록을 홈에서 빠르게 탐색하고 싶다.
- 사용자는 채널 후원 메시지와 후원 전체 목록을 확인하고 싶다.
- 사용자는 공지, 스케줄, 커뮤니티, 팬Talk를 홈에서 요약 형태로 확인하고 전체보기로 이동하고 싶다.
- 사용자는 크리에이터 소개, 활동 통계, SNS 링크를 채널 홈 하단에서 확인하고 싶다.
7. Core Requirements
7.1 크리에이터 채널 홈 데이터 조회
API
- Method:
GET - Path:
/api/v2/creator-channels/{creatorId}/home - Path parameter:
creatorId - 인증: 기존 V2 API 인증 헤더 패턴을 따른다.
- 응답 래퍼: 기존 관례대로
ApiResponse<CreatorChannelHomeResponse>디코딩을 우선한다.
Response 기준
data class CreatorChannelHomeResponse(
val creator: CreatorChannelCreatorResponse,
val currentLive: CreatorChannelLiveResponse?,
val latestAudioContent: CreatorChannelAudioContentResponse?,
val channelDonations: List<CreatorChannelDonationResponse>,
val notices: List<CreatorChannelCommunityPostResponse>,
val schedules: List<CreatorChannelScheduleResponse>,
val audioContents: List<CreatorChannelAudioContentResponse>,
val series: List<CreatorChannelSeriesResponse>,
val communities: List<CreatorChannelCommunityPostResponse>,
val fanTalk: CreatorChannelFanTalkSummaryResponse,
val introduce: String,
val activity: CreatorChannelActivityResponse,
val sns: CreatorChannelSnsResponse
)
Swift 모델 기준
struct CreatorChannelHomeResponse: Decodable {
let creator: CreatorChannelCreatorResponse
let currentLive: CreatorChannelLiveResponse?
let latestAudioContent: CreatorChannelAudioContentResponse?
let channelDonations: [CreatorChannelDonationResponse]
let notices: [CreatorChannelCommunityPostResponse]
let schedules: [CreatorChannelScheduleResponse]
let audioContents: [CreatorChannelAudioContentResponse]
let series: [CreatorChannelSeriesResponse]
let communities: [CreatorChannelCommunityPostResponse]
let fanTalk: CreatorChannelFanTalkSummaryResponse
let introduce: String
let activity: CreatorChannelActivityResponse
let sns: CreatorChannelSnsResponse
}
- Kotlin
Long으로 정의된 id/count 계열 값은 Swift에서Int로 통일한다. CreatorActivityType은 기존SodaLive/Sources/V2/Main/Home/Following/Models/HomeFollowingTabResponse.swift의 enum 재사용 또는 공용 이동 여부를 계획 단계에서 결정한다.profileImageUrl,coverImageUrl,imageUrl,audioUrl등 URL 문자열은 서버 스펙의 nullable 여부를 따른다. 빈 문자열은 이미지 없음과 동일하게 처리할지 구현 전 확인한다.
7.2 화면 상태
- 최초 진입 시 홈 API를 호출한다.
- 로딩 중에는 기존 V2 화면 패턴에 맞는 loading state를 표시한다.
- API 실패 시에는 전체 화면 error state로 전환하지 않고 placeholder 기반으로 일부 UI를 유지한다.
- API 실패 placeholder는 title bar, tab-bar, 홈 외 tab placeholder destination처럼 서버 데이터 없이 표시 가능한 공통 shell을 유지하는 방식으로 처리한다.
- 선택된 tab 상태와 홈 API 호출 상태는 공통 shell의 ViewModel에서 관리한다.
- 응답을 성공적으로 받은 뒤 각 섹션은 자신의 데이터가 비어 있으면 section title과 empty state를 표시하지 않고 섹션 전체를 숨긴다.
- 동일 화면 생명주기 안에서 불필요한 중복 호출은 피한다.
- pull-to-refresh가 기존 크리에이터 상세 화면에 있다면 같은 패턴을 검토한다. 기존 패턴이 없으면 이번 범위에서 새로 추가하지 않는다.
7.3 Header / Title Bar / Status Bar
Figma 참조:
- 전체 화면:
node-id=296:14890 - Unfollow title bar:
node-id=296:14287,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 - Follow + 알림 설정 title bar:
node-id=296:14288,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 - Follow + 알림 해제 title bar:
node-id=296:14289,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
요구사항:
- title bar, 크리에이터 프로필 header, status bar 처리는
CreatorChannelView공통 shell에서 담당한다. - 크리에이터 이미지 영역은 OS status bar 영역까지 확장한다.
- title bar는 화면 최상단에
ZStack또는overlay형태로 띄워 header view와 겹치게 배치한다. - title bar 뒤에 큰 배경 이미지가 보이도록 기본 배경은 투명이다.
- scroll 진행도에 따라
backgroundProgress가 증가할 때만 title bar 배경색을 black에 가깝게 점진적으로 표시한다. - tab-bar와 title bar가 가까워질수록 title bar 배경색은 점진적으로 black으로 변한다.
- tab-bar가 sticky 상태가 되면 OS status bar 영역도 title bar 배경색과 동일하게 보이도록 한다.
- title bar 좌측에는 back 버튼을 둔다.
- title bar 우측에는 팔로우/알림 상태 버튼과 더보기 버튼을 둔다.
- title bar 중앙에는 크리에이터 닉네임을 표시한다.
- title bar 닉네임은
backgroundProgress가 1일 때만 표시한다. - title bar 닉네임은 한 줄로 표시하고, 영역을 넘으면 말줄임 처리한다.
- title bar 닉네임이 길어도 우측 팔로우/알림/더보기 영역은 항상 먼저 보여야 한다.
- title bar 좌측 back 버튼은
ic_new_bar_backasset을 사용한다. - title bar 우측 더보기 버튼은
ic_new_moreasset을 사용한다. isFollow == false이면팔로우capsule 버튼을 표시한다.isFollow == false상태의 follow capsule에는ic_new_followasset을 사용한다.isFollow == true상태의 following capsule에는ic_new_followingasset을 사용한다.isFollow == true && isNotify == true이면 following capsule과 알림 설정 아이콘ic_bar_bell_fill을 표시한다.isFollow == true && isNotify == false이면 following capsule과 알림 해제 아이콘ic_bar_bell을 표시한다.- 더보기 버튼은 항상 표시한다.
- 팔로우/팔로우 취소/알림 설정/알림 설정 취소 mutation은 기존
UserProfile에서 사용하는UserRepository.creatorFollow(creatorId:follow:notify:)흐름을 그대로 사용한다. - 팔로우 action은
creatorFollow(follow: true, notify: true)를 호출한다. - 팔로우 취소 action은 기존
UserProfile의CreatorFollowNotifyDialog.onClickUnFollow와 동일하게creatorFollow(follow: false, notify: false)를 호출한다. ic_bar_bell터치 시 알림 설정 action으로creatorFollow(follow: true, notify: true)를 호출한다.ic_bar_bell_fill터치 시 알림 설정 취소 action으로creatorFollow(follow: true, notify: false)를 호출한다.- 알림 상태 변경용 신규 API는 만들지 않는다.
- title bar에 사용하는 아이콘은
ic_new_bar_back,ic_new_follow,ic_new_following,ic_new_more,ic_bar_bell,ic_bar_bell_fill로 고정하고, 다른 back/follow/more/bell asset으로 대체하지 않는다.
7.4 크리에이터 프로필 헤더
- 크리에이터 프로필 헤더는 홈 탭 콘텐츠가 아니라
CreatorChannelView공통 shell에 속한다. - HeaderView의 표시 내용은
CreatorChannelHomeResponse.creator를 사용해 채운다. - HeaderView에는 별도 원형/소형 프로필 이미지를 표시하지 않는다.
creator.profileImageUrl은 크리에이터 이미지 헤더의 큰 배경 이미지에만 사용한다.- 큰 배경 이미지 영역은 OS status bar까지 확장되도록 top safe area를 무시한다.
creator.nickname,creator.followerCount를 Figma 위치와 계층에 맞게 표시한다.creator.characterId가 있는 경우 캐릭터/AI 대화 연결 여부를 판단하는 데이터로 사용한다.- 이미지 로드 실패 시 기존 프로젝트의 이미지 placeholder 패턴을 따른다.
- 텍스트가 길어도 이미지/버튼/탭 영역과 겹치지 않도록 한 줄 말줄임 또는 기존 nickname 표시 관례를 따른다.
7.5 대화하기 액션 영역
- 대화하기 액션 영역은 tab-bar 아래 홈 탭 콘텐츠에 속한다.
creator.isAiChatAvailable == true이면 대화하기 버튼을 표시한다.- 대화하기 아이콘은
ic_new_talkasset을 사용한다. - 대화하기 버튼은 영역 중앙에 배치한다.
creator.isAiChatAvailable == false여도 액션 영역의 높이와 vertical spacing은 보존한다.- 대화하기 버튼 action은 기존 AI 채팅방 페이지로 이동한다.
- 기존 AI 채팅방 진입에 필요한 본인인증 guard를 동일하게 적용한다.
- 본인인증 guard에는 한국이 아닌 국가에서 다른 값으로 비교하는 기존 분기 조건도 포함한다.
creator.isDmAvailable과ic_new_dm은 response/asset 확인 대상이지만, DM 버튼 UI와 DM 진입은 추후 작업으로 미루고 이번 범위에서 구현하지 않는다.
7.6 Tab Bar
- tab-bar는
CreatorChannelView공통 shell에 속하며, 선택된 tab에 따라 tab-bar 아래 콘텐츠만 교체한다. - tab-bar 항목은
홈,라이브,오디오,시리즈,커뮤니티,팬Talk,후원순서로 표시한다. 화보탭은 표시하지 않는다.- tab-bar는 horizontal scroll 가능 구조로 구현한다.
- 선택된 탭은 Figma처럼 하단 indicator와 white text로 표시한다.
- 선택되지 않은 탭은 gray text로 표시한다.
- tab-bar가 title bar와 맞닿으면 sticky 상태가 되고, 이후에는 tab-bar 아래 콘텐츠만 스크롤된다.
- 선택된 tab이
홈이 아닐 때는 실제 목록 화면 대신 선택된 탭 제목을 표시하는 placeholder 페이지를 표시한다. - 홈 섹션의
전체보기chevron/button으로 이동해야 하는 destination도 해당 tab placeholder 또는 별도 placeholder 화면으로 연결한다.
7.7 현재 라이브 섹션
currentLive != nil이면 현재 라이브 섹션을 표시한다.liveId,title,coverImageUrl,beginDateTimeUtc,price,isAdult를 사용한다.coverImageUrl이 없으면 기존 라이브 카드의 기본 이미지 처리 패턴을 따른다.isAdult == true이면 기존 19금/성인 콘텐츠 표시 asset 또는 패턴을 따른다.- card tap 시 기존 라이브 상세/라이브룸 진입 흐름이 있으면 연결하고, 없으면 placeholder action으로 둔다.
7.8 최신 오디오 콘텐츠 섹션
latestAudioContent != nil이면 최신 오디오 콘텐츠 섹션을 표시한다.audioContentId,title,duration,imageUrl,price,isAdult,isPointAvailable,isFirstContent,seriesName,isOriginalSeries를 사용한다.- V2 공용
AudioContentCard가 요구사항과 맞으면 재사용한다. isPointAvailable,isFirstContent,isOriginalSeries표시는 기존 오디오 카드/태그 패턴을 우선 따른다.- card tap 시 기존 오디오 콘텐츠 상세 진입 흐름이 있으면 연결하고, 없으면 placeholder action으로 둔다.
7.9 채널 후원 섹션
channelDonations를 사용해 채널 후원 요약 목록을 표시한다.- 각 item은
nickname,profileImageUrl,can,message,createdAtUtc를 표시한다. channelDonations가 비어 있으면 채널 후원 섹션을 숨긴다.- 전체보기 action은 기존
AppStep.channelDonationAll(creatorId:)또는 동일한 기존 흐름이 있으면 연결한다. - 기존 흐름 연결이 어렵다면 후원 tab placeholder로 이동한다.
7.10 공지 섹션
notices를 사용해 공지 게시물을 표시한다.- 응답 모델은
CreatorChannelCommunityPostResponse를 재사용한다. - 공지 섹션은 일반 커뮤니티 섹션과 시각 구성이 다를 수 있으므로 별도 section component로 분리한다.
imageUrl,audioUrl,price,existOrdered,likeCount,commentCount처리는 기존 커뮤니티 카드 패턴을 따른다.- 공지 전체보기 또는 item tap destination은 기존 커뮤니티 상세/목록 흐름이 있으면 연결하고, 없으면 placeholder로 둔다.
7.11 스케줄 섹션
schedules를 사용해 예정 항목을 표시한다.- 각 item은
scheduledAtUtc,title,type,targetId를 사용한다. type은LIVE,AUDIO,COMMUNITY,LIVE_REPLAY등 기존CreatorActivityType처리 범위를 따른다.- schedule tap 시 기존
MainView.handleFollowingScheduleTap(type:targetId:)와 같은 분기 패턴을 검토해 재사용한다. - 지원하지 않는 type은 crash 없이 무시하거나 placeholder로 둔다.
7.12 오디오 섹션
audioContents를 사용해 오디오 콘텐츠 목록을 표시한다.- V2 공용
AudioContentCard재사용을 우선 검토한다. - 홈 섹션에서는 Figma 기준 노출 개수만 표시하고, 전체보기는 오디오 tab placeholder 또는 기존 오디오 목록으로 이동한다.
audioContents가 비어 있으면 오디오 섹션을 숨긴다.
7.13 시리즈 섹션
series를 사용해 시리즈 목록을 표시한다.- 각 item은
seriesId,title,coverImageUrl,numberOfContent,isNew,isOriginal을 표시한다. isNew,isOriginal표시는 Figma 태그와 기존 시리즈 카드 패턴을 따른다.- 전체보기는 시리즈 tab placeholder 또는 기존 시리즈 목록으로 이동한다.
- item tap 시 기존 시리즈 상세 흐름이 있으면 연결하고, 없으면 placeholder action으로 둔다.
7.14 커뮤니티 섹션
communities를 사용해 커뮤니티 게시물 목록을 표시한다.- V2 공용
CommunityPostCard가 요구사항과 맞으면 재사용한다. imageUrl,audioUrl,price,existOrdered,likeCount,commentCount를 표시 규칙에 반영한다.- 유료/잠금 게시물은 기존 커뮤니티 잠금/구매 표시 패턴을 따른다.
- 홈에서는 Figma 기준 노출 개수만 표시하고
전체보기버튼으로 커뮤니티 tab placeholder 또는 기존 커뮤니티 목록으로 이동한다.
7.15 팬Talk 섹션
fanTalk.totalCount와fanTalk.latestFanTalk를 사용한다.latestFanTalk == nil이면 팬Talk 섹션을 숨긴다.- 최신 팬Talk가 있으면
nickname,profileImageUrl,content,languageCode,createdAtUtc를 표시한다. - 전체보기 action은 크리에이터 채널의 팬Talk 탭으로 이동한다.
7.16 소개 섹션
introduce문자열을 표시한다.- 빈 문자열이면 소개 섹션을 숨긴다.
- 긴 텍스트는 Figma 기준으로 전체 표시하되, 화면 폭을 넘지 않게 줄바꿈 처리한다.
7.17 활동 섹션
activity를 사용해 아래 항목을 표시한다.debutDateUtc와dDay를 조합해2026.06.11(D+1)형식으로 표시한다.liveCount는라이브 총 진행 수로 표시한다.liveDurationHours는라이브 누적 진행 시간으로 표시한다.liveContributorCount는라이브 누적 참여자로 표시한다.audioContentCount는오디오로 표시한다.seriesCount는시리즈로 표시한다.- Figma에는
화보활동 항목이 있지만 response 초안에 필드가 없고 이번 범위에서 화보 제외이므로 표시하지 않는다. - 숫자 formatting은 기존 프로젝트의 count formatting 패턴을 따른다.
7.18 SNS 섹션
sns.instagramUrl,sns.fancimmUrl,sns.xUrl,sns.youtubeUrl,sns.kakaoOpenChatUrl을 사용한다.- 빈 URL 또는 유효하지 않은 URL은 해당 SNS 아이콘을 숨긴다.
- 표시 순서는 Figma 기준
Instagram,YouTube,X,KakaoTalk,Fancimm(팬심M)순서를 따른다. - SNS 아이콘은
ic_sns_*asset을 사용한다. - tap 시 외부 브라우저 또는 기존 in-app web 흐름을 따른다.
8. UX / UI Expectations
8.1 포함하는 UI
- OS status bar 영역까지 확장되는 크리에이터 이미지 헤더
- scroll progress에 따라 black으로 변하는 overlay title bar
- 팔로우/알림 상태별 title bar
- sticky horizontal tab-bar
- 공통 shell 아래 홈 탭의 대화하기 액션 영역
- 홈 탭의 섹션별 summary UI
- 홈 외 탭의 placeholder page
- 홈 섹션 전체보기 placeholder destination
8.2 제외하는 UI
- 화보 탭
- 화보 섹션
- 활동 섹션의 화보 count row
- DM 버튼 및 DM 보내기 진입
- 새 외부 라이브러리 추가
8.3 시각 규칙
- 전체 화면은 Figma처럼 dark background를 기준으로 한다.
- Figma의 fixed width/height 값은 참고하되, SwiftUI 구현에서는 화면 width, safe area, dynamic type에 대응 가능한 layout을 우선한다.
- card/list root container는 필요한 경우를 제외하고 고정 숫자 width/height로 제한하지 않는다.
- section title은 V2 공용
SectionTitle재사용을 우선 검토한다. - chevron이 있는 section title 또는 전체보기 버튼은 tap 가능한 영역을 충분히 확보한다.
- profile image, cover image, content image는 기존 이미지 로딩/placeholder 패턴을 따른다.
- nickname/title/content가 길어도 인접 UI와 겹치지 않도록 말줄임 또는 줄바꿈을 적용한다.
9. Technical Constraints
- 신규 View, ViewModel, Repository 및 연결 하위 코드는
SodaLive/Sources/V2/**아래에 작성한다. - 여러 페이지에서 재사용 가능한 공용 컴포넌트는
SodaLive/Sources/V2/Component/**아래에 둔다. - 크리에이터 채널 공통 shell 내부에서만 쓰는 컴포넌트는
SodaLive/Sources/V2/CreatorChannel/Components/**아래에 둔다. - 홈 탭 내부에서만 쓰는 컴포넌트는
SodaLive/Sources/V2/CreatorChannel/Home/Components/**아래에 둔다. - API/Repository/ViewModel 구성은 기존
SodaLive/Sources/V2/Main/Home/Following/**,Ranking/**,Recommendation/**패턴을 따른다. SodaLive/Sources/V2/Component/SectionTitle.swift,AudioContentCard.swift,CommunityPostCard.swift,CapsuleTabBar.swift등 기존 V2 컴포넌트 재사용 가능성을 먼저 검토한다.CreatorActivityType은 중복 선언하지 않고 기존 enum 재사용 또는 공용 위치 이동을 검토한다.- 신규 asset은 프로젝트 asset catalog에 이미 존재하는
ic_new_talk을 사용한다.ic_new_dm은 추후 DM 버튼 작업에서 사용한다. - title bar 아이콘은 프로젝트 asset catalog의
ic_new_bar_back,ic_new_follow,ic_new_following,ic_new_more,ic_bar_bell,ic_bar_bell_fill을 사용한다. - 신규 문구가 다국어 대상이면
SodaLive/Sources/I18n/I18n.swift에 추가한다. - Figma에서 제공되는 localhost asset URL은 앱 코드에 넣지 않는다.
- 프로젝트 설정 변경은 신규 파일이 Xcode project에 자동 포함되지 않는 구조일 때만 수행한다.
- Kotlin
Long으로 정의된 id/count 계열 값은 Swift에서Int로 통일한다. - SNS 섹션 아이콘은 Figma localhost asset이 아니라 프로젝트 asset catalog의
ic_sns_*아이콘을 사용한다.
10. Success Criteria
- 크리에이터 채널 진입 시
CreatorChannelView가 표시되고, 기본 선택 탭은홈이다. - 크리에이터 채널 진입 시
GET /api/v2/creator-channels/{creatorId}/home호출이 발생한다. - response model이 PRD의 API 초안 필드를 디코딩한다.
- API 실패 시 전체 화면 error state 대신 placeholder 기반으로 표시 가능한 공통 shell UI가 유지된다.
creator정보가 공통 shell의 header/title 상태와 홈 탭의 action 상태에 반영된다.- 크리에이터 이미지가 OS status bar 영역까지 표시된다.
- HeaderView는
CreatorChannelHomeResponse.creator를 기반으로 표시되고, 별도 프로필 이미지를 추가로 표시하지 않는다. - title bar의 기본 배경은 투명이고 큰 배경 이미지 위에 overlay되어 보인다.
- scroll 위치에 따라 title bar 배경이 점진적으로 black으로 변한다.
- tab-bar가 title bar와 맞닿으면 sticky 상태가 되고 아래 콘텐츠만 스크롤된다.
- sticky 상태에서 OS status bar 영역도 title bar와 동일한 black 배경으로 보인다.
isFollow,isNotify조합에 따라 title bar의 팔로우/알림 상태가 Figma 3개 상태와 일치한다.- title bar 배경 opacity가 1일 때 크리에이터 닉네임이 한 줄 말줄임으로 표시되고, 긴 닉네임이어도 우측 팔로우/알림/더보기 영역이 우선 노출된다.
- title bar는
ic_new_bar_back,ic_new_follow,ic_new_following,ic_new_more,ic_bar_bell,ic_bar_bell_fillasset만 사용한다. - 팔로우/팔로우 취소/알림 설정/알림 설정 취소 action은 기존
UserProfile과 동일하게UserRepository.creatorFollow(creatorId:follow:notify:)를 호출한다. ic_bar_bell터치 시creatorFollow(follow: true, notify: true),ic_bar_bell_fill터치 시creatorFollow(follow: true, notify: false)가 호출된다.isAiChatAvailable에 따라 대화하기 버튼이 조건부 표시된다.- 대화하기 버튼은 기존 AI 채팅방 페이지로 이동하고, 기존 본인인증 guard와 비한국 국가 분기 guard를 적용한다.
- 대화하기 버튼이 없어도 액션 영역 높이는 유지된다.
- DM 버튼은 표시되지 않는다.
- tab-bar 아래 콘텐츠는 선택된 tab에 따라 교체된다.
- 홈 tab에는 대화하기, 현재 라이브, 최신 오디오 콘텐츠, 채널 후원, 공지, 스케줄, 오디오, 시리즈, 커뮤니티, 팬Talk, 소개, 활동, SNS 섹션이 API 데이터 기반으로 표시된다.
- SNS 섹션은
ic_sns_*asset 아이콘과 유효한 SNS URL만 사용해 표시된다. - 데이터가 비어 있는 섹션은 표시되지 않는다.
화보탭, 화보 섹션, 활동의 화보 row가 표시되지 않는다.- 홈 외 tab-bar 항목 선택 시 선택한 탭 제목을 표시하는 placeholder page가 표시된다.
- 홈 섹션의 전체보기 action은 기존 화면 또는 placeholder destination으로 이동한다.
- 기존 V2 공용 컴포넌트를 재사용 가능한 곳에서 재사용하고, 채널 홈 전용 UI만 전용
Components로 분리한다.
11. Open Questions
해당 없음.
12. Verification Notes
docs/agent-guides/documentation-policy.md를 확인해 신규 PRD 경로와 필수 섹션 기준을 검증했다.docs/prd/sample-prd.md,docs/20260630_메인_홈_랭킹_탭/prd.md,docs/20260630_메인_홈_팔로잉_탭/prd.md를 확인해 저장소의 PRD 작성 스타일을 맞췄다.- Figma
node-id=296:14890의 design context와 screenshot을 확인해 홈 화면 섹션, tab-bar 항목, sticky 대상 구조를 검토했다. - Figma
node-id=296:14287,296:14288,296:14289의 design context와 screenshot을 확인해 title bar의 Unfollow, Follow+알림 설정, Follow+알림 해제 상태를 검토했다. SodaLive/Sources/V2/**구조를 확인해 기존 V2 홈 API/Repository/ViewModel/Components 배치 패턴을 검토했다.SodaLive/Sources/V2/Component/SectionTitle.swift,AudioContentCard.swift,CommunityPostCard.swift,CapsuleTabBar.swift등 재사용 후보 파일 존재를 확인했다.- 사용자 확인 사항을 반영해
creator.profileImageUrl을 헤더 큰 이미지로 사용, 빈 섹션 숨김, 기존UserProfilefollow/notify API 사용, 대화하기의 기존 AI 채팅방 및 본인인증 guard 적용, DM 버튼 추후 작업, 홈 외 탭 제목 placeholder, 팬Talk 전체보기의 팬Talk 탭 이동, SwiftInt통일 정책을 확정 요구사항으로 이동했다. - 사용자 확인 사항을 반영해 API 실패 시 placeholder 기반으로 일부 UI를 유지하고, SNS 섹션 아이콘은
ic_sns_*asset을 사용하도록 확정 요구사항으로 이동했다. - 저장소의
ic_sns_fancimm,fancimmUrl,I18n.ProfileUpdate.fancimm을 확인해 Figma의 Fansim 표기를Fancimm(팬심M)기준으로 정리했다. - 2026-07-02: 사용자 확인 사항을 반영해 title bar, 크리에이터 프로필 header, tab-bar를
CreatorChannelView공통 shell로 두고, tab-bar 아래 홈 탭 콘텐츠만CreatorChannelHomeView가 담당하도록 구조를 변경했다. - 2026-07-02: 사용자 확인 사항을 반영해 title bar Figma URL 3종과 사용할 아이콘 asset(
ic_new_bar_back,ic_new_follow,ic_new_following,ic_new_more,ic_bar_bell,ic_bar_bell_fill)을 확정 요구사항으로 추가했다. - 2026-07-02: 기존
UserProfile동작을 확인해 title bar의 팔로우/팔로우 취소/알림 설정/알림 설정 취소를UserRepository.creatorFollow(creatorId:follow:notify:)로 처리하도록 확정했다. - 2026-07-02: 사용자 확인 사항을 반영해 HeaderView는
CreatorChannelHomeResponse.creator데이터로 채우고, 별도 프로필 이미지 없이 큰 배경 이미지만 표시하며, title bar는 기본 투명 배경으로 header 위에 overlay되도록 요구사항을 정리했다.