13 KiB
13 KiB
PRD: 메인 콘텐츠 탭 내부 추천 탭
1. Overview
메인 하단 콘텐츠 탭 안의 내부 추천 탭에서 GET /api/v2/audio/recommendations 응답을 사용해 오디오 추천 화면을 제공한다.
화면 상단 title bar와 내부 tab bar는 고정 영역으로 유지하고, Figma 기준 배너부터 하위 콘텐츠만 세로 스크롤한다. 신규 기능이므로 구현 대상 API, 모델, ViewModel, 화면, 섹션 컴포넌트는 SodaLive/Sources/V2/Main/Content/Recommendation/** 하위에 둔다.
Figma 참조:
- 전체 화면:
24:6737,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=24-6737&m=dev - title bar:
24:6738 - 배너:
24:6741 - 새로 올라온 오디오:
24:6751 - New&Hot:
24:6758 - 오직 보이스온에서만:
24:6745 - 추천 시리즈:
24:6770(이번 범위 제외) - 무료 오디오:
24:6807 - 포인트 오디오:
24:6813 - 크리에이터의 댓글 많은 오디오:
24:6820 - 키워드의 오디오:
24:6829(이번 범위 제외) - 추천 오디오:
24:6842
2. Problem
- 현재 V2
MainView의.content탭은 placeholder 상태라 메인 콘텐츠 탭에서 실제 추천 오디오 콘텐츠를 제공하지 못한다. - 기존 홈 추천 탭은 크리에이터/커뮤니티/라이브 중심이고, 콘텐츠 탭 내부 추천 화면은 오디오 추천 API와 섹션 구성이 다르다.
- Figma 화면은 카드형, 리스트형, 댓글 카드형, grid형 등 섹션마다 레이아웃이 달라 단일 컴포넌트로 단순 렌더링하면 디자인과 맞지 않는다.
- 오디오 카드에는
ONLY, original audio, first, free, point, adult 등 여러 태그가 겹쳐 표시되므로 기존 V2 컴포넌트 재사용 범위를 먼저 정해야 한다.
3. Goals
- 메인 하단
콘텐츠탭에서 내부추천탭 화면을 표시한다. GET /api/v2/audio/recommendations를 호출하고 응답 데이터로 섹션을 구성한다.- title bar와 내부 tab bar는 고정하고, 배너부터 하위 콘텐츠만 스크롤한다.
- Figma에 보이는 구현 대상 섹션을 섹션별로 분리한다.
banners,originalSeries,latestAudios,newAndHotAudios,freeAudios,pointAudios,mostCommentedAudios,recommendedAudios를 응답 모델에 반영한다.오직 보이스온에서만!섹션에는originalSeries를 사용하고,ic_series_original+img_new_only조합으로ONLY표시를 노출한다.새로 올라온 오디오,무료 오디오,포인트 오디오,추천 오디오는 기존AudioContentCard재사용 또는 최소 보완을 우선 검토한다.New&Hot,크리에이터의 댓글 많은 오디오는 기존CreatorChannelAudioContentListItem의 row/태그 표시 규칙을 참고한다.- 오디오 item 탭 시 기존 content detail 진입 guard 흐름을 재사용한다.
4. Non-Goals
추천 시리즈섹션은 이번 범위에서 구현하지 않는다.#키워드의 오디오섹션은 이번 범위에서 구현하지 않는다.- API 스펙에 없는 추천 시리즈 상세 카드, 키워드 추천 API, 키워드별 더보기 화면을 임의로 추가하지 않는다.
- 기존 홈
추천/랭킹/팔로잉탭 구조를 변경하지 않는다. - 기존 legacy
SodaLive/Sources/Content/**화면을 리팩터링하지 않는다. - Figma localhost asset URL을 앱 코드에 직접 사용하지 않는다.
- 외부 라이브러리를 추가하지 않는다.
Pods/**,generated/**,build/**는 수정하지 않는다.
5. Target Users
- 메인 콘텐츠 탭에서 새 오디오와 추천 오디오를 빠르게 탐색하려는 사용자
- 무료/포인트/신규/오리지널 여부를 보고 오디오 콘텐츠를 선택하려는 사용자
- 댓글 반응이 많은 오디오를 확인하고 상세로 이동하려는 사용자
- 보이스온 오리지널 시리즈를 별도 섹션에서 발견하려는 사용자
6. User Stories
- 사용자는 콘텐츠 탭의 추천 화면에서 최신 오디오를 가로 카드 목록으로 보고 싶다.
- 사용자는
New&Hot오디오를 리스트 형태로 빠르게 훑어보고 싶다. - 사용자는 보이스온에서만 제공되는 오리지널 시리즈를
ONLY표시로 구분하고 싶다. - 사용자는 무료 오디오와 포인트 사용 가능 오디오를 별도 섹션으로 탐색하고 싶다.
- 사용자는 크리에이터의 댓글 많은 오디오와 최신 댓글 작성자 프로필을 함께 보고 싶다.
- 사용자는 추천 오디오를 2열 grid로 탐색하고 마음에 드는 콘텐츠 상세로 이동하고 싶다.
7. Core Requirements
7.1 API
- Method:
GET - Path:
/api/v2/audio/recommendations - 인증: 기존 V2 API 인증 헤더 패턴을 따른다.
- 응답 래퍼: 기존 관례대로
ApiResponse<AudioRecommendationsResponse>디코딩을 우선한다.
7.2 Response model
data class AudioRecommendationsResponse(
val banners: List<AudioBannerResponse>,
val originalSeries: List<OriginalSeriesResponse>,
val latestAudios: List<AudioCardResponse>,
val newAndHotAudios: List<AudioCardResponse>,
val freeAudios: List<AudioCardResponse>,
val pointAudios: List<AudioCardResponse>,
val mostCommentedAudios: List<CommentedAudioResponse>,
val recommendedAudios: List<AudioCardResponse>
)
Swift 모델은 기존 V2 관례에 맞춰 Decodable 구조체로 선언한다. audioContentId, seriesId, creatorId 같은 Kotlin Long 대응 값은 프로젝트 기존 모델 관례에 맞춰 Swift Int를 우선 사용한다.
7.3 Fixed shell and scrolling
- 콘텐츠 탭 title bar는 화면 상단 고정 영역이다.
- 콘텐츠 탭 title bar 좌측은 홈 로고나 내부 탭명이 아니라 메인 탭명
콘텐츠를 고정 표시한다. - 콘텐츠 탭 title bar 우측은 Figma
24:6738기준cash,search,storage액션 아이콘을 표시하고 알림 bell 아이콘은 사용하지 않는다. - 내부 tab bar도 title bar 아래 고정 영역이다.
- Figma
24:6741배너부터 하위 콘텐츠만 세로ScrollView안에 둔다. - 하단 main tab bar와 mini player 영역은 기존
MainView구조를 유지한다.
7.4 Section visibility
- 섹션별 배열이 비어 있으면 해당 섹션은 렌더링하지 않는다.
- 모든 구현 대상 섹션이 비어 있으면 empty state를 표시한다.
- API 실패 또는 디코딩 실패 시 사용자 노출 문구를
I18n에 둔다.
7.5 구현 대상 섹션
- 배너:
banners - 오직 보이스온에서만:
originalSeries - New&Hot:
newAndHotAudios - 새로 올라온 오디오:
latestAudios - 무료 오디오:
freeAudios - 포인트 오디오:
pointAudios - 크리에이터의 댓글 많은 오디오:
mostCommentedAudios - 추천 오디오:
recommendedAudios
7.6 제외 대상 섹션
- 추천 시리즈: Figma
24:6770 - 키워드의 오디오: Figma
24:6829
originalSeries는 이번 범위에서 오직 보이스온에서만! 섹션에만 사용한다. 추천 시리즈 카드형 상세 UI는 만들지 않는다.
7.7 Tag display
isOriginalSeries == true이면 original audio/series 태그를 표시한다.isFirstContent == true이면 first 태그를 표시한다.isPointAvailable == true이면 point 태그를 표시한다.price == 0이면 free 태그를 표시한다.isAdult == true이면 adult shield 태그를 표시한다.오직 보이스온에서만!의ONLY표시는ic_series_original+img_new_onlyasset 조합을 사용한다.
7.8 Navigation
- title bar의 storage 아이콘 탭은 기존 보관함 진입 경로인
AppState.shared.setAppStep(step: .myBox(currentTab: .orderlist))를 사용한다. - 오디오 item 탭은
audioContentId로 기존 content detail 진입 흐름을 사용한다. - 배너 탭은
eventItem,creatorId,seriesId,link를 명시적으로 분기한다. eventItem은 기존 event detail 흐름이 있으면 재사용한다.creatorId는 기존 creator detail guard callback을 재사용한다.seriesId는AppStep.seriesDetail(seriesId:)route로 연결한다.AudioBannerResponse.link는 먼저AppDeepLinkHandler.handle(urlString:)로 deep link 여부를 확인한다.AudioBannerResponse.link가 deep link로 처리되지 않으면UIApplication.shared.open으로 외부 브라우저를 연다.
8. UX / UI Expectations
- 전체 배경은 기존 V2 dark UI 기준을 따른다.
- 섹션 title은 Figma 텍스트를 우선 사용하되 신규 사용자 노출 문자열은
I18n에 둔다. - 배너는 Figma
24:6741기준으로 가로 carousel과01 / 20page indicator를 표시한다. - 일반 오디오 카드 섹션은 가로 스크롤 카드 목록으로 표시한다.
New&Hot은 3개 row를 한 묶음으로 구성하고 묶음 단위로 가로 스크롤한다.크리에이터의 댓글 많은 오디오는 오디오 row와 댓글 preview bubble을 하나의 카드로 묶어 가로 스크롤한다.크리에이터의 댓글 많은 오디오의 댓글 preview bubble에는 nickname을 표시하지 않는다. Figma24:6820기준으로latestCommentWriterProfileImageUrl과latestComment댓글 텍스트 영역만 사용한다.추천 오디오는 2열 grid로 표시한다.- 텍스트가 길면 한 줄 또는 Figma 기준 line limit로 말줄임 처리한다.
- 카드/row의 루트 레이아웃은 가능한 부모 width, grid column, aspect ratio 기반으로 구성한다.
9. Technical Constraints
- 신규 기능 파일은
SodaLive/Sources/V2/Main/Content/Recommendation/**하위에 둔다. - 콘텐츠 탭 root는
SodaLive/Sources/V2/Main/Content/**하위에 둔다. - 여러 화면에서 재사용할 명확한 근거가 생긴 컴포넌트만
SodaLive/Sources/V2/Component/**로 승격한다. - 기존
MainHomeRecommendationAPI/ViewModel을 직접 확장하지 않는다. - 기존
AudioContentCard,BannerCarousel,SectionTitle,TextTabBar,HomeTitleBar재사용을 먼저 검토한다. - 신규 사용자 노출 문구는
SodaLive/Sources/I18n/I18n.swift에 ko/en/ja로 추가한다. - Figma localhost asset URL은 앱 코드에 사용하지 않는다.
- 외부 라이브러리는 추가하지 않는다.
10. Success Criteria
.content탭에서 placeholder 대신 콘텐츠 탭 root가 표시된다.- 콘텐츠 탭 내부
추천탭 진입 시GET /api/v2/audio/recommendations호출이 발생한다. - 콘텐츠 탭 title bar는 좌측 고정 title
콘텐츠와 우측cash/search/storage액션을 표시하고, storage 탭 시 보관함으로 이동한다. - title bar와 내부 tab bar는 고정되고, 배너부터 하위 섹션만 세로 스크롤된다.
- API 응답의 구현 대상 배열이 각 Figma 섹션에 매핑된다.
추천 시리즈,#키워드의 오디오섹션은 구현되지 않는다.오직 보이스온에서만!섹션은ic_series_original+img_new_only조합으로ONLY표시를 노출한다.- 오디오 item 탭 시 기존 content detail guard 흐름을 통해 상세로 이동한다.
AudioBannerResponse.seriesId와OriginalSeriesResponse.seriesId탭 시seriesDetail로 이동한다.AudioBannerResponse.link는 deep link 우선 처리 후, deep link가 아니면 외부 브라우저로 열린다.- 빈 섹션은 숨겨지고, 전체 empty/API 실패 상태는 사용자에게 안내된다.
xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build가 성공한다.
11. Open Questions
- 현재 확정된 요구사항 기준으로 미결정 사항은 없다.
12. Verification Notes
- 2026-07-05: Figma
get_design_context와get_screenshot으로24:6737,24:6741,24:6751,24:6758,24:6745,24:6770,24:6807,24:6813,24:6820,24:6829,24:6842를 확인했다. - 2026-07-05:
MainView,MainHomeView,AudioContentCard,BannerCarousel,CreatorChannelAudioContentListItem,CreatorChannelSeriesListItem을 확인해 재사용 후보를 정리했다. - 2026-07-05: 최초 문서 작성 시
plan-task.md만 작성되어 신규 기능 문서 정책과 맞지 않았다. 본 PRD를 추가해 정책 누락을 보완한다. - 2026-07-05: 사용자 확인으로 댓글 preview bubble에는 nickname을 표시하지 않고, 배너
link는 deep link 우선 후 외부 브라우저로 열며,seriesId는seriesDetailroute로 이동하도록 확정했다. - 2026-07-08: Figma
24:6738기준으로 콘텐츠 탭 title bar가 홈 탭 로고/bell 구성이 아니라 좌측 고정 title콘텐츠와 우측ic_bar_cash/ic_bar_search/ic_bar_storage구성을 사용하도록 요구사항을 보완했다. - 2026-07-12: 요청에 따라
최근 댓글이 많은 오디오섹션 타이틀을크리에이터의 댓글 많은 오디오로 변경했다.