13 KiB
13 KiB
메인 콘텐츠 추천 전체보기 구현 계획
기준 문서
- PRD:
docs/20260707_메인_콘텐츠_추천_전체보기/prd.md - 문서 정책:
docs/agent-guides/documentation-policy.md - 코드 스타일:
docs/agent-guides/code-style.md - 빌드/검증:
docs/agent-guides/build-test-verification.md
구현할 UI의 Figma URL
- New&Hot 전체보기 화면:
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=482-15105&m=dev
확정 요구사항 요약
처음부터 함께 성장!섹션과FIRST_AUDIO_CONTENT전체보기 진입은 이번 구현 범위에서 제외한다.New&Hot전체보기는 탭 외부 전환이므로AppSteproute로 추가한다.New&Hot전체보기 API는GET /api/v2/contents를 사용한다.New&Hot전체보기 기본 query는page=0,size=20,type=NEW_AND_HOT_AUDIO이다.New&Hot전체보기 UI는 Figma 기준 2열 오디오 카드 grid와 back title bar를 제공한다.새로 올라온 오디오,오직 보이스온에서만,무료 오디오,포인트 오디오전체보기는 별도 route 없이 하단콘텐츠탭 내부 상단전체탭 전환으로 처리한다.- 기존
SectionTitle(title:action:)chevron 표시 기능과AudioContentThumbnailCard를 우선 재사용한다.
TASK 체크리스트
Phase 0: 구현 전 문구 결정
- Task 0.1: 신규 전체보기 실패/빈 목록 문구 확정
- 대상 파일:
- 확인:
docs/20260707_메인_콘텐츠_추천_전체보기/prd.md - 수정 후보:
SodaLive/Sources/I18n/I18n.swift
- 확인:
- 작업 내용:
- PRD의 Open Questions에 남은 신규 API 실패 toast 문구와 empty state 문구를 확정한다.
- 기존 문구를 재사용할 경우 어떤 namespace의 문구를 재사용할지 명시한다.
- 신규 문구가 필요하면
I18n에 추가할 key와 ko/en/ja 문구를 확정한다.
- 검증 기준:
- PRD의 Open Questions가 해소되거나, 구현 계획에 사용할 문구 source가 명확히 기록된다.
- 대상 파일:
Phase 1: New&Hot 전체보기 API 모델과 repository
-
Task 1.1: ContentOverview API response 모델 추가
- 대상 파일:
- 생성:
SodaLive/Sources/V2/Main/Content/Overview/Models/ContentOverviewPageResponse.swift
- 생성:
- 작업 내용:
ContentOverviewTypeenum을 추가한다.- 이번 범위에서는
NEW_AND_HOT_AUDIO만 case로 둔다. ContentOverviewPageResponse,ContentOverviewItemResponse를 추가한다.ContentOverviewItemResponse는Identifiable을 채택하고contentId를id로 사용한다.
- 검증 기준:
- PRD의 response field가 Swift 모델에 누락 없이 반영된다.
FIRST_AUDIO_CONTENTcase는 추가하지 않는다.
- 대상 파일:
-
Task 1.2: ContentOverview API와 repository 추가
- 대상 파일:
- 생성:
SodaLive/Sources/V2/Main/Content/Overview/Repository/ContentOverviewApi.swift - 생성:
SodaLive/Sources/V2/Main/Content/Overview/Repository/ContentOverviewRepository.swift
- 생성:
- 작업 내용:
GET /api/v2/contentsendpoint를 추가한다.- query parameter
page,size,type을URLEncoding.queryString으로 전송한다. - 기존 V2 API와 동일하게 bearer token header를 사용한다.
- repository는
MoyaProvider<ContentOverviewApi>와requestPublisher패턴을 따른다.
- 검증 기준:
- 기본 호출에서
page=0,size=20,type=NEW_AND_HOT_AUDIO를 보낼 수 있다. - 기존
GET /api/v2/audio/contentsAPI 파일은 수정하지 않는다.
- 기본 호출에서
- 대상 파일:
Phase 2: New&Hot 전체보기 화면과 페이징
-
Task 2.1: ContentOverview ViewModel 구현
- 대상 파일:
- 생성:
SodaLive/Sources/V2/Main/Content/Overview/ContentOverviewViewModel.swift
- 생성:
- 작업 내용:
ContentOverviewRepository로 첫 페이지와 다음 페이지를 요청한다.- 기본값은
type = .newAndHotAudio,page = 0,pageSize = 20으로 둔다. items,page,size,hasNext,hasLoaded,isLoading,isLoadingNextPage,errorMessage,isShowPopup상태를 관리한다.- 첫 페이지 성공은 목록 교체, 다음 페이지 성공은 append로 처리한다.
- 실패 시 첫 페이지/다음 페이지 로딩 상태를 해제하고 toast 또는 empty state 문구를 표시한다.
- 검증 기준:
hasNext == true이고 마지막 item이 노출될 때 다음 page 요청이 가능하다.- 중복 next page 요청이 발생하지 않는다.
FIRST_AUDIO_CONTENTtype 분기는 없다.
- 대상 파일:
-
Task 2.2: AudioContentThumbnailCard adapter 추가
- 대상 파일:
- 수정:
SodaLive/Sources/V2/Component/AudioContent/AudioContentThumbnailCard.swift
- 수정:
- 작업 내용:
AudioContentThumbnailCardItem에init(contentOverviewItem:)adapter를 추가한다.contentId는id,coverImage는imageUrl,creatorNickname은subtitle로 매핑한다.price,isAdult,isPointAvailable,isFirstContent,isOriginalSeries는 기존 card tag 규칙에 그대로 연결한다.
- 검증 기준:
- 신규 adapter 외 기존
audioCard,mainContentAudioadapter 동작은 변경하지 않는다. - New&Hot 카드에서 original/first/point/free/adult tag 표시 조건을 재사용할 수 있다.
- 신규 adapter 외 기존
- 대상 파일:
-
Task 2.3: ContentOverviewView 구현
- 대상 파일:
- 생성:
SodaLive/Sources/V2/Main/Content/Overview/ContentOverviewView.swift
- 생성:
- 작업 내용:
- title은
New&Hot으로 표시한다. - 좌측 back chevron은
AppState.shared.back()을 호출한다. - Figma 기준 2열
LazyVGrid로AudioContentThumbnailCard를 표시한다. - 카드 tap 시
contentId를 받아 기존 오디오 상세 이동 callback으로 전달한다. - 첫 로딩, empty state, pagination loading, toast 상태를 기존 V2 콘텐츠 화면 패턴으로 표시한다.
- title은
- 검증 기준:
- 화면 진입 시 첫 페이지 요청이 발생한다.
- back chevron tap 시 이전 route로 돌아간다.
- 카드 tap 시 기존 오디오 상세 route로 이동할 수 있는 callback이 호출된다.
- 대상 파일:
Phase 3: AppStep route 연결
-
Task 3.1: New&Hot AppStep route 추가
- 대상 파일:
- 수정:
SodaLive/Sources/App/AppStep.swift - 수정:
SodaLive/Sources/ContentView.swift
- 수정:
- 작업 내용:
AppStep에case contentOverview(type: ContentOverviewType = .newAndHotAudio)route를 추가한다.ContentView의AppStepLayerViewswitch에ContentOverviewViewmapping을 추가한다.- route는 이번 범위에서
NEW_AND_HOT_AUDIO만 열 수 있게 구성한다.
- 검증 기준:
AppState.shared.setAppStep(step:)로 New&Hot 전체보기 화면을 push할 수 있다.ContentViewswitch 누락으로 인한 compile error가 없다.
- 대상 파일:
-
Task 3.2: MainView에서 New&Hot route와 오디오 상세 이동 연결
- 대상 파일:
- 수정:
SodaLive/Sources/V2/Main/MainView.swift - 수정:
SodaLive/Sources/V2/Main/Content/MainContentView.swift
- 수정:
- 작업 내용:
MainContentView에onTapNewAndHotAllcallback을 추가한다.MainView에서 해당 callback을 받아AppState.shared.setAppStep(step:)로 New&Hot 전체보기 route를 연다.ContentOverviewView의 card tap은 기존handleRecommendationContentTap(contentId:)흐름을 재사용한다.
- 검증 기준:
- 추천 탭
New&Hotchevron tap 시 하단 탭 내부 전환이 아니라 새AppSteproute로 진입한다. - New&Hot 전체보기 card tap 시 기존 오디오 상세 화면으로 진입한다.
- 추천 탭
- 대상 파일:
Phase 4: 추천 탭 섹션 action과 내부 전체 탭 전환
-
Task 4.1: 추천 섹션 컴포넌트에 action parameter 추가
- 대상 파일:
- 수정:
SodaLive/Sources/V2/Main/Content/Recommendation/Components/MainContentAudioHorizontalCardSection.swift - 수정:
SodaLive/Sources/V2/Main/Content/Recommendation/Components/MainContentAudioListCarouselSection.swift - 수정:
SodaLive/Sources/V2/Main/Content/Recommendation/Components/MainContentVoiceOnOnlySection.swift
- 수정:
- 작업 내용:
- 각 섹션에 optional
action: (() -> Void)? = nilparameter를 추가한다. SectionTitle(title:)호출을SectionTitle(title:action:)로 변경한다.- item이 비어 섹션이 숨겨질 때는 chevron도 표시하지 않는다.
- 각 섹션에 optional
- 검증 기준:
- action을 전달한 섹션만 chevron이 표시된다.
- 기존 item tap callback은 변경 없이 유지된다.
- 대상 파일:
-
Task 4.2: MainContentAllViewModel 외부 적용 API 추가
- 대상 파일:
- 수정:
SodaLive/Sources/V2/Main/Content/All/MainContentAllViewModel.swift
- 수정:
- 작업 내용:
- 추천 섹션 전체보기 진입을 위한
apply(type:sort:)method를 추가한다. - 목표 타입/정렬이 현재 상태와 다르면 items를 비우고 첫 페이지를 다시 요청한다.
- 목표 타입/정렬이 현재 상태와 같고 이미 로드된 상태라면 불필요한 중복 요청을 피한다.
FREE타입에 허용되지 않는 정렬을 넣지 않도록 기존allowedSorts규칙과 충돌하지 않게 한다.
- 추천 섹션 전체보기 진입을 위한
- 검증 기준:
.audio + .latest,.original + .latest,.free + .popular,.point + .popular적용이 가능하다.- 기존 타입 chip, sort menu, pagination 동작은 유지된다.
- 대상 파일:
-
Task 4.3: MainContentView 내부 전체 탭 전환 연결
- 대상 파일:
- 수정:
SodaLive/Sources/V2/Main/Content/MainContentView.swift - 수정:
SodaLive/Sources/V2/Main/Content/Recommendation/MainContentRecommendationView.swift
- 수정:
- 작업 내용:
MainContentRecommendationView에 섹션별 전체보기 callback을 추가한다.MainContentView에서 callback을 받아selectedTab = .all로 전환하고allViewModel에 목표 타입/정렬을 적용한다.새로 올라온 오디오:.audio,.latest오직 보이스온에서만:.original,.latest무료 오디오:.free,.popular포인트 오디오:.point,.popularNew&Hot: Phase 3의onTapNewAndHotAllcallback을 호출한다.
- 검증 기준:
- New&Hot 외 섹션 chevron tap은
AppSteproute를 추가로 push하지 않고 내부전체탭으로 전환된다. - 내부
전체탭 전환 후 타입/정렬이 PRD의 매핑과 일치한다.
- New&Hot 외 섹션 chevron tap은
- 대상 파일:
Phase 5: 문구, 접근성, 회귀 검증
-
Task 5.1: I18n 문구 반영
- 대상 파일:
- 수정 후보:
SodaLive/Sources/I18n/I18n.swift
- 수정 후보:
- 작업 내용:
- Task 0.1에서 확정한 New&Hot 전체보기 empty/failure 문구를 반영한다.
- 기존 문구 재사용으로 결정된 경우 불필요한 신규 key를 만들지 않는다.
- 검증 기준:
- 신규 화면에서 표시하는 모든 사용자 노출 문구가
I18n또는 기존 상수 정책과 일치한다.
- 신규 화면에서 표시하는 모든 사용자 노출 문구가
- 대상 파일:
-
Task 5.2: 빌드 검증
- 대상 파일:
- 확인:
SodaLive.xcworkspace - 확인:
SodaLive.xcodeproj
- 확인:
- 실행 명령:
xcodebuild -workspace "SodaLive.xcworkspace" -listxcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug -sdk iphonesimulator build
- 검증 기준:
- workspace와 scheme가 확인된다.
- Debug simulator build가 성공한다.
- 대상 파일:
-
Task 5.3: 수동 동작 검증
- 대상 파일:
- 확인:
SodaLive/Sources/V2/Main/Content/Recommendation/MainContentRecommendationView.swift - 확인:
SodaLive/Sources/V2/Main/Content/Overview/ContentOverviewView.swift - 확인:
SodaLive/Sources/V2/Main/Content/All/MainContentAllView.swift
- 확인:
- 수동 확인 항목:
새로 올라온 오디오chevron tap 시전체 > 오디오 > 최신순상태로 전환된다.오직 보이스온에서만chevron tap 시전체 > 오리지널 > 최신순상태로 전환된다.무료 오디오chevron tap 시전체 > 무료 > 인기순상태로 전환된다.포인트 오디오chevron tap 시전체 > 포인트 > 인기순상태로 전환된다.New&Hotchevron tap 시 신규AppSteproute 화면으로 이동한다.New&Hot전체보기에서 paging, back, card tap 상세 이동이 동작한다.처음부터 함께 성장!섹션과FIRST_AUDIO_CONTENT진입은 노출되지 않는다.
- 검증 기준:
- PRD의 Success Criteria가 모두 충족된다.
- 기존 추천 탭의 item tap, banner tap, series tap 동작이 회귀하지 않는다.
- 대상 파일:
검증 기록
- 2026-07-07: PRD를 기준으로 plan-task 문서를 생성했다. 구현은 아직 수행하지 않았다.