# 크리에이터 채널 라이브 탭 구현 계획/TASK > **For agentic workers:** 각 단계는 체크박스(`- [ ]`)로 추적하고, 완료 즉시 `- [x]`로 갱신한다. 구현 범위 변경이 생기면 이 문서를 먼저 수정한 뒤 코드에 반영한다. **Goal:** `GET /api/v2/creator-channels/{creatorId}/live` 응답을 기반으로 크리에이터 채널의 `라이브` 탭에 현재 라이브, 라이브 다시듣기 목록, 정렬, pagination, 본인 채널 전용 하단 `라이브 시작하기` CTA를 표시한다. **Architecture:** 기존 `CreatorChannelActivity`의 `ViewPager2`/`CreatorChannelPagerAdapter` 구조를 유지하고, `CreatorChannelTab.Live`의 placeholder를 신규 `CreatorChannelLiveFragment`로 교체한다. API/Repository/ViewModel/mapper/UI model은 기존 `kr.co.vividnext.sodalive.v2.creator.channel` 패키지 하위에 최소 추가하고, 홈 탭에서 이미 쓰는 `CreatorChannelLiveResponse`, `CreatorChannelAudioContentResponse`, 본인 판정, 라이브 시작 진입 흐름은 가능한 한 재사용한다. **Tech Stack:** Kotlin, Android XML Views, ViewBinding, RecyclerView, Retrofit, Gson, RxJava3, Koin, JUnit4/Robolectric local unit test. --- ## 전제와 성공 기준 - PRD: `docs/20260617_크리에이터_채널_라이브_탭/prd.md` - 기존 채널 컨테이너: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt` - 기존 탭 adapter: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelPagerAdapter.kt` - 기존 홈 API/DTO/Repository: - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/data/CreatorChannelHomeApi.kt` - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/data/CreatorChannelHomeModels.kt` - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/data/CreatorChannelHomeRepository.kt` - Figma: - 전체: `290:8945` - Sort-bar: `290:8949` - 현재 진행 중인 라이브: `290:8950` - 라이브 다시듣기 item: `290:8954`, `290:8956` - 정렬 컨텍스트 메뉴: `290:9041` - 본인 채널 하단 CTA: `665:19359`, `665:19371` - 첫 페이지 `page`는 `0`이다. - 다음 페이지는 마지막 성공 응답의 `page + 1`로 요청한다. - `ContentSort` 기본값은 `LATEST`이다. - `isOwned == true`와 `isRented == true`가 동시에 내려오면 `소장중`을 우선 표시한다. - `seriesName`은 라이브 다시듣기 item에 표시하지 않는다. - `isFirstContent`, `isOriginalSeries`는 기존 오디오 item 정책과 동일하게 매핑한다. - drawable 리소스는 기존 파일을 재사용한다. - `ic_new_sort` - `ic_new_shield_small` - `ic_new_player_play` - `ic_new_create_live` - 구현 완료 후 최소 다음 명령을 실행한다. - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.*Live*"` - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.*"` - `./gradlew :app:mergeDebugResources` - `./gradlew :app:compileDebugKotlin` - `./gradlew :app:ktlintCheck` --- ## Figma 참조 필요 Phase - Phase 1: 부분 참조 - 기존 코드 경계와 리소스 존재 여부 확인이 중심이며, Figma는 PRD 기준만 확인한다. - Phase 2: Figma 참조 불필요 - API/DTO/Repository/ViewModel 상태 모델은 서버 계약과 기존 코드 패턴을 따른다. - Phase 3: 부분 참조 - mapper와 presenter 정책은 PRD와 Figma item variant의 상태 표시를 함께 확인한다. - Phase 4: 필수 참조 - `fragment_creator_channel_live.xml`, sort-bar, current live card, replay item layout은 Figma `290:8949`, `290:8950`, `290:8954`, `290:8956`을 기준으로 구현한다. - Phase 5: 필수 참조 - 정렬 컨텍스트 메뉴는 Figma `290:9041` 기준으로 구현한다. - Phase 6: 필수 참조 - 본인 채널 하단 CTA는 Figma `665:19359`, `665:19371` 기준으로 구현한다. - Phase 7: 부분 참조 - 탭 연결, 화면 이동, pagination 동작은 기존 코드 패턴 중심으로 검증한다. - Phase 8: 필수 참조 - 최종 수동 화면 검증은 PRD의 모든 Figma 노드와 실제 화면을 대조한다. --- ## 파일 구조 - 수정: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelPagerAdapter.kt` - `CreatorChannelTab.Live`를 신규 `CreatorChannelLiveFragment`로 연결한다. - 생성: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelLiveFragment.kt` - 라이브 탭 UI, adapter, sort menu, pagination, CTA click 연결을 담당한다. - 생성 후보: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelLiveViewModel.kt` - 라이브 탭 API 호출, 정렬 변경, pagination 상태, loading/error/content 상태를 관리한다. - 수정: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/data/CreatorChannelHomeApi.kt` - `GET /api/v2/creator-channels/{creatorId}/live` endpoint를 추가하거나, 필요 시 파일명을 공용 API 역할에 맞춰 최소 변경한다. - 수정: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/data/CreatorChannelHomeRepository.kt` - 라이브 탭 API 호출 method를 추가하거나, 필요 시 공용 Repository 역할에 맞춰 최소 변경한다. - 수정: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/data/CreatorChannelHomeModels.kt` - `CreatorChannelLiveTabResponse`, `ContentSort`를 추가하고 `CreatorChannelAudioContentResponse`에 라이브 탭 전용 필드 `isAdult`, `isOwned`, `isRented`를 서버 계약에 맞춰 추가한다. - 생성 후보: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/model/CreatorChannelLiveUiModels.kt` - sort option, replay item status, pagination 상태, CTA 노출 여부를 순수 UI model로 정의한다. - 생성 후보: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/model/CreatorChannelLiveMappers.kt` - DTO를 UI model로 변환하고 소장/대여/무료/가격/포인트/19금 상태를 결정한다. - 생성: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/ui/CreatorChannelLiveReplayAdapter.kt` - 라이브 다시듣기 목록 RecyclerView adapter를 담당한다. - 생성 후보: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/ui/CreatorChannelLiveSortPopup.kt` - Sort-bar anchor 기준 컨텍스트 메뉴 표시를 담당한다. - 생성: `app/src/main/res/layout/fragment_creator_channel_live.xml` - sort-bar, current live card container, replay RecyclerView, owner CTA를 포함한다. - 생성: `app/src/main/res/layout/item_creator_channel_live_replay.xml` - 라이브 다시듣기 item layout이다. - 생성 후보: `app/src/main/res/layout/view_creator_channel_live_sort_menu.xml` - 정렬 컨텍스트 메뉴를 XML로 분리할 때만 추가한다. - 수정: `app/src/main/res/values/strings.xml` - 정렬 label, `소장중`, `대여중`, `라이브 시작하기`, empty/error 문구를 추가한다. - 수정: `app/src/main/res/values-en/strings.xml`, `app/src/main/res/values-ja/strings.xml` - 신규 문자열의 다국어 값을 추가한다. - 수정: `app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt` - 신규 ViewModel/API/Repository binding이 필요하면 추가한다. - 테스트 생성: - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelLiveMapperTest.kt` - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelLivePaginationTest.kt` - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelLiveViewModelTest.kt` - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelLiveFragmentLayoutTest.kt` - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelPagerAdapterTest.kt` --- ### Phase 1: 기존 구조 확인과 작업 경계 고정 - [ ] **Task 1.1: 크리에이터 채널 탭 구조와 본인 판정 경로 확인** - 확인: - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt` - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelPagerAdapter.kt` - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelHomeFragment.kt` - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/model/CreatorChannelHomeMappers.kt` - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/model/CreatorChannelHomeUiModels.kt` - 작업: - `CreatorChannelTab.Live`가 현재 placeholder로 연결되는 지점을 확인한다. - 본인 여부(`isOwner`)가 Activity와 탭 Fragment로 전달되는 기존 경로를 확인한다. - 라이브 시작 진입이 기존 `CreatorChannelActivity`의 `onOwnerFabLiveClicked()` 또는 `LiveRoomCreateActivity` 경로를 재사용할 수 있는지 확인한다. - 검증: - 라이브 탭 구현이 홈 탭 section adapter를 변경하지 않고 독립 Fragment로 추가 가능한지 기록한다. - [ ] **Task 1.2: 기존 오디오 item 정책과 drawable/string 리소스 확인** - 확인: - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/ui/CreatorChannelHomeAudioContentCardView.kt` - `app/src/main/res/layout/item_creator_channel_home_audio_content.xml` - `app/src/main/java/kr/co/vividnext/sodalive/v2/widget/AudioContentTag.kt` - `app/src/main/res/drawable-mdpi/ic_new_sort.png` - `app/src/main/res/drawable-mdpi/ic_new_shield_small.png` - `app/src/main/res/drawable-mdpi/ic_new_player_play.png` - `app/src/main/res/drawable-mdpi/ic_new_create_live.png` - 작업: - `isFirstContent`, `isOriginalSeries`, point/free/original tag의 기존 표시 정책을 정리한다. - 라이브 다시듣기 item에서 `seriesName`은 표시하지 않는다는 PRD 결정을 재확인한다. - 검증: - 위 4개 drawable 리소스가 존재함을 확인한다. --- ### Phase 2: API/DTO/Repository/ViewModel 계약 추가 - [ ] **Task 2.1: 라이브 탭 DTO와 `ContentSort` 추가** - 수정: - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/data/CreatorChannelHomeModels.kt` - 작업: - `CreatorChannelLiveTabResponse`를 `@Keep`, `@SerializedName` 기반 data class로 추가한다. - `ContentSort` enum에 `LATEST`, `POPULAR`, `OWNED`, `PRICE_HIGH`, `PRICE_LOW`를 추가한다. - 기존 `CreatorChannelAudioContentResponse`에 `isAdult`, `isOwned`, `isRented` 필드를 추가할 때 홈 탭 API 하위 호환성이 깨지지 않는지 확인한다. - 하위 호환이 필요하면 라이브 탭 전용 DTO 분리 또는 nullable/default 정책을 테스트로 고정한다. - 검증 명령: - `./gradlew :app:compileDebugKotlin` - 기대 결과: - DTO 추가 후 컴파일된다. - [ ] **Task 2.2: 라이브 탭 endpoint와 Repository method 추가** - 수정: - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/data/CreatorChannelHomeApi.kt` - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/data/CreatorChannelHomeRepository.kt` - 작업: - `@GET("/api/v2/creator-channels/{creatorId}/live")` endpoint를 추가한다. - query parameter `page`, `size`, `sort`를 전달한다. - `sort`는 `ContentSort.name` 또는 Retrofit enum 변환의 기존 정책을 확인해 서버 값이 `LATEST` 등 대문자로 나가도록 한다. - 검증 명령: - `./gradlew :app:compileDebugKotlin` - 기대 결과: - API/Repository가 기존 Koin graph와 충돌 없이 컴파일된다. - [ ] **Task 2.3: ViewModel RED 테스트 작성** - 생성: - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelLiveViewModelTest.kt` - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelLivePaginationTest.kt` - 작업: - 최초 로딩이 `page=0`, `sort=LATEST`로 호출되는지 검증한다. - `hasNext == true`일 때 `page + 1`로 다음 페이지를 요청하는지 검증한다. - loading 중 중복 load-more 요청이 막히는지 검증한다. - 정렬 변경 시 목록과 page가 초기화되는지 검증한다. - 선택 중인 정렬을 다시 선택하면 API를 재호출하지 않는지 검증한다. - 검증 명령: - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelLiveViewModelTest"` - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelLivePaginationTest"` - 기대 결과: - ViewModel 미구현 상태에서 RED 실패한다. - [ ] **Task 2.4: `CreatorChannelLiveViewModel` 구현** - 생성: - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelLiveViewModel.kt` - 수정: - `app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt` - 작업: - initial loading, content, empty, error, pagination loading, pagination error 상태를 정의한다. - `page=0`, `size` 기본값, `sort=LATEST` 초기값을 적용한다. - 정렬 변경과 pagination 요청 중복 방지 로직을 구현한다. - 검증 명령: - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelLiveViewModelTest"` - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelLivePaginationTest"` - 기대 결과: - ViewModel/pagination 테스트가 PASS한다. --- ### Phase 3: UI model과 상태 표시 mapper 구현 - [ ] **Task 3.1: 라이브 다시듣기 표시 정책 RED 테스트 작성** - 생성: - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelLiveMapperTest.kt` - 작업: - `isOwned && isRented` 동시 true면 `소장중` 상태가 선택되는지 검증한다. - `price == 0`이면 무료 tag와 play CTA 상태가 선택되는지 검증한다. - `isAdult == true`이면 `ic_new_shield_small` 표시 상태가 선택되는지 검증한다. - `isPointAvailable == true`이면 point tag 표시 상태가 선택되는지 검증한다. - `seriesName`은 secondary text에 포함되지 않는지 검증한다. - `isFirstContent`, `isOriginalSeries`는 기존 오디오 item 정책과 동일한 tag 상태로 매핑되는지 검증한다. - 검증 명령: - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelLiveMapperTest"` - 기대 결과: - mapper 미구현 상태에서 RED 실패한다. - [ ] **Task 3.2: UI model/mapper 구현** - 생성 후보: - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/model/CreatorChannelLiveUiModels.kt` - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/model/CreatorChannelLiveMappers.kt` - 작업: - sort label resource, replay item CTA/status, tag 상태, current live 상태를 UI model로 분리한다. - 가격/포인트/소장중/대여중/play button 상태 우선순위를 순수 함수로 고정한다. - `ContentSort`와 문자열 리소스 매핑을 구현한다. - 검증 명령: - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelLiveMapperTest"` - 기대 결과: - mapper 테스트가 PASS한다. --- ### Phase 4: 라이브 탭 Fragment와 목록 UI 구현 - [ ] **Task 4.1: Fragment layout과 replay item layout 추가** - 생성: - `app/src/main/res/layout/fragment_creator_channel_live.xml` - `app/src/main/res/layout/item_creator_channel_live_replay.xml` - 수정: - `app/src/main/res/values/strings.xml` - `app/src/main/res/values-en/strings.xml` - `app/src/main/res/values-ja/strings.xml` - 작업: - Figma 기준 sort-bar, current live card, replay list, owner CTA 영역을 배치한다. - replay item은 88dp 썸네일, title 최대 2줄, duration 1줄, 우측 price/play/status 영역을 포함한다. - `ic_new_shield_small`, `ic_new_player_play`, `ic_new_sort`, `ic_new_create_live`를 layout 또는 binding에서 사용 가능하게 준비한다. - 검증 명령: - `./gradlew :app:mergeDebugResources` - 기대 결과: - 신규 layout/string/drawable 참조가 resource merge에 성공한다. - [ ] **Task 4.2: Adapter와 Fragment 구현** - 생성: - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelLiveFragment.kt` - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/ui/CreatorChannelLiveReplayAdapter.kt` - 작업: - ViewModel 상태를 관찰해 sort-bar, current live card, replay list, loading/empty/error를 갱신한다. - replay item click은 기존 오디오 컨텐츠 상세/재생 진입 정책을 확인해 연결한다. - current live card click은 기존 홈 탭 라이브 진입 정책을 재사용한다. - RecyclerView scroll listener로 하단 접근 시 ViewModel load-more를 호출한다. - 검증 명령: - `./gradlew :app:compileDebugKotlin` - 기대 결과: - Fragment/adapter가 컴파일된다. - [ ] **Task 4.3: Fragment layout 테스트 추가** - 생성: - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelLiveFragmentLayoutTest.kt` - 작업: - `fragment_creator_channel_live.xml`에 sort-bar, RecyclerView, owner CTA가 존재하는지 검증한다. - `item_creator_channel_live_replay.xml`에 19금 badge, point/free tag container, price/play/status 영역이 존재하는지 검증한다. - `ic_new_*` 리소스 참조가 layout 또는 코드 상수로 연결되는지 검증한다. - 검증 명령: - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelLiveFragmentLayoutTest"` - 기대 결과: - layout 테스트가 PASS한다. --- ### Phase 5: 정렬 컨텍스트 메뉴 구현 - [ ] **Task 5.1: Sort popup 구현** - 생성 후보: - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/ui/CreatorChannelLiveSortPopup.kt` - `app/src/main/res/layout/view_creator_channel_live_sort_menu.xml` - 수정: - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelLiveFragment.kt` - 작업: - Sort-bar 정렬 영역 아래에 Figma `290:9041` 형태의 컨텍스트 메뉴를 표시한다. - 현재 선택 항목은 focused 배경으로 표시한다. - 메뉴 외부 터치, 같은 정렬 재선택, 새 정렬 선택 시 메뉴를 닫는다. - 새 정렬 선택 시 ViewModel에 정렬 변경을 전달한다. - 검증: - 작은 화면에서 메뉴가 화면 밖으로 벗어나지 않도록 위치 보정 기준을 코드에 남긴다. - [ ] **Task 5.2: Sort 동작 테스트 보강** - 수정: - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelLiveViewModelTest.kt` - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelLiveMapperTest.kt` - 작업: - `ContentSort`별 label resource 매핑을 검증한다. - 정렬 변경 시 첫 페이지가 다시 로딩되는지 검증한다. - 같은 정렬 재선택은 API 재호출을 하지 않는지 검증한다. - 검증 명령: - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.*Live*"` - 기대 결과: - sort 관련 테스트가 PASS한다. --- ### Phase 6: 본인 채널 하단 CTA와 라이브 시작 진입 연결 - [ ] **Task 6.1: 본인 CTA 노출과 inset 처리 구현** - 수정: - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelLiveFragment.kt` - `app/src/main/res/layout/fragment_creator_channel_live.xml` - 작업: - 본인 채널일 때만 하단 CTA를 표시한다. - 타인 채널 또는 본인 여부 로딩 전에는 CTA를 숨긴다. - CTA 표시 시 RecyclerView 하단 padding을 추가해 마지막 item이 CTA에 가려지지 않도록 한다. - navigation bar bottom inset을 CTA 영역에 반영한다. - 버튼 icon은 `ic_new_create_live`, label은 `라이브 시작하기` 문자열 리소스를 사용한다. - 검증 명령: - `./gradlew :app:mergeDebugResources` - `./gradlew :app:compileDebugKotlin` - 기대 결과: - CTA resource와 inset 코드가 컴파일된다. - [ ] **Task 6.2: 기존 라이브 시작 플로우 연결** - 확인: - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt` - `app/src/main/java/kr/co/vividnext/sodalive/live/room/create/LiveRoomCreateActivity.kt` - 수정: - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelLiveFragment.kt` - 필요 시 `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt` - 작업: - `CreatorChannelActivity`의 기존 owner FAB live action과 같은 진입 경로를 재사용한다. - 중복 터치를 방지한다. - 라이브 생성 완료 후 기존 홈 refresh/라이브룸 진입 정책과 충돌하지 않도록 처리한다. - 검증: - 라이브 시작 진입 대상 Activity/Fragment와 전달 extra를 계획 문서 해당 Task의 `검증 기록`에 남긴다. --- ### Phase 7: 탭 연결과 통합 동작 - [ ] **Task 7.1: `CreatorChannelTab.Live`를 실제 Fragment로 연결** - 수정: - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelPagerAdapter.kt` - 생성: - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelPagerAdapterTest.kt` - 작업: - Live 탭 position에서 `CreatorChannelLiveFragment.newInstance(creatorId)`를 반환한다. - 나머지 탭은 기존 placeholder 정책을 유지한다. - 검증 명령: - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelPagerAdapterTest"` - 기대 결과: - Live 탭만 실제 Fragment로 연결되고 나머지 placeholder 정책은 유지된다. - [ ] **Task 7.2: DI와 lifecycle 통합** - 수정: - `app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt` - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelLiveFragment.kt` - 작업: - 신규 ViewModel/API/Repository injection이 기존 홈 탭과 충돌하지 않는지 확인한다. - Fragment 재생성 후 정렬, page, 목록 상태가 ViewModel에 유지되는지 확인한다. - 탭 전환 시 중복 최초 API 호출이 발생하지 않도록 초기 로딩 조건을 정리한다. - 검증 명령: - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.*Live*"` - `./gradlew :app:compileDebugKotlin` - 기대 결과: - Live 탭 관련 테스트와 컴파일이 PASS한다. --- ### Phase 8: 최종 검증과 문서 기록 - [ ] **Task 8.1: 자동 검증 실행** - 실행 명령: - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.*Live*"` - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.*"` - `./gradlew :app:mergeDebugResources` - `./gradlew :app:compileDebugKotlin` - `./gradlew :app:ktlintCheck` - 기대 결과: - 모든 명령이 `BUILD SUCCESSFUL`로 통과한다. - 검증 기록: - 실행 일시, 명령, 결과, 기존 경고 여부를 이 Task 아래에 누적 기록한다. - [ ] **Task 8.2: 수동 확인** - 확인 항목: - `라이브` 탭 진입 시 `page=0`, `sort=LATEST`로 최초 조회된다. - Sort-bar에 `전체 {count}`와 현재 정렬 label, `ic_new_sort`가 표시된다. - 정렬 컨텍스트 메뉴가 Sort-bar 아래에 표시되고 선택/닫힘 동작이 정상이다. - `currentLive != null`일 때 현재 라이브 카드가 표시된다. - 라이브 다시듣기 item의 19금/포인트/무료/소장중/대여중/가격 상태가 DTO와 일치한다. - `isOwned && isRented` 동시 true item은 `소장중`으로 표시된다. - `seriesName`은 표시되지 않는다. - `hasNext == true`일 때 하단 스크롤로 다음 페이지가 append된다. - 본인 채널에서만 하단 `라이브 시작하기` CTA가 표시된다. - 타인 채널에서는 하단 CTA가 표시되지 않는다. - CTA가 마지막 item을 가리지 않는다. - 검증 기록: - 실제 확인한 시나리오와 결과를 이 Task 아래에 한국어로 누적 기록한다. --- ## Verification Log - 아직 구현 전 문서 생성 단계이므로 실행한 빌드/테스트 검증은 없다.