diff --git a/docs/20260622_크리에이터_채널_후원_탭/plan-task.md b/docs/20260622_크리에이터_채널_후원_탭/plan-task.md index ad037ed5..5e1952a2 100644 --- a/docs/20260622_크리에이터_채널_후원_탭/plan-task.md +++ b/docs/20260622_크리에이터_채널_후원_탭/plan-task.md @@ -357,7 +357,7 @@ ### Phase 5: Empty/Error/문자열 리소스 구현 -- [ ] **Task 5.1: empty/error 문자열과 다국어 리소스 추가** +- [x] **Task 5.1: empty/error 문자열과 다국어 리소스 추가** - 수정: - `app/src/main/res/values/strings.xml` - `app/src/main/res/values-en/strings.xml` @@ -373,9 +373,9 @@ - 실행: `./gradlew :app:mergeDebugResources` - 기대 결과: values/en/ja 문자열 병합이 PASS한다. - 검증 기록: - - 미실행. 구현 시 기록한다. + - 2026-06-22: 기존 `creator_channel_donation_*` 문자열이 `values`, `values-en`, `values-ja`에 이미 추가되어 있음을 확인했다. Figma `290:9008` 및 계획 문구에 맞춰 한국어 `creator_channel_donation_empty_title`을 `아직 후원이 없습니다.\n처음으로 크리에이터를 후원해 보세요!`로 갱신했다. `./gradlew :app:mergeDebugResources`가 PASS해 문자열 병합을 확인했다. -- [ ] **Task 5.2: Figma `290:9008` empty 상태 구현** +- [x] **Task 5.2: Figma `290:9008` empty 상태 구현** - 수정: - `app/src/main/res/layout/fragment_creator_channel_donation.xml` - 필요 시 `app/src/main/res/drawable/bg_creator_channel_donation_empty_button.xml` @@ -391,11 +391,14 @@ - 기대 결과: empty 상태 visibility/source 계약이 PASS한다. - 수동 확인: Figma `290:9008`과 empty 문구 위치, button 색상/icon/text, owner 버튼 숨김을 대조한다. - 검증 기록: - - 미실행. 구현 시 기록한다. + - 2026-06-22: RED로 `CreatorChannelDonationFragmentLayoutTest`에 empty 중앙 `btn_creator_channel_donation_empty_write`/icon/text id 및 Figma capsule source 계약을 추가하고, `CreatorChannelDonationActionTest`에 empty 중앙 button이 타인 채널에서만 표시되고 기존 후원 요청 callback을 재사용해야 한다는 source 계약을 추가했다. 구현 전 `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.donation.CreatorChannelDonationFragmentLayoutTest" --tests "kr.co.vividnext.sodalive.v2.creator.channel.donation.CreatorChannelDonationActionTest"`가 신규 id 미존재(`btn_creator_channel_donation_empty_write`, `iv_creator_channel_donation_empty_write`, `tv_creator_channel_donation_empty_write`)로 FAIL해 RED를 확인했다. + - 2026-06-22: `fragment_creator_channel_donation.xml`에 Figma `290:9008` 기준 중앙 capsule 후원하기 button을 추가하고, `CreatorChannelDonationFragment`에서 empty 상태일 때 `!state.isOwner`인 경우만 중앙 button을 표시하도록 연결했다. empty 중앙 button 클릭은 content floating button과 같은 `host.onCreatorChannelDonationRequested { can, isSecret, message -> viewModel.postChannelDonation(...) }` 경로를 사용한다. `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.donation.CreatorChannelDonationFragmentLayoutTest" --tests "kr.co.vividnext.sodalive.v2.creator.channel.donation.CreatorChannelDonationActionTest"`가 PASS했다. 수동 대조는 Figma `290:9008` screenshot을 확인해 16sp gray/500 중앙 문구, 14dp 간격, soda capsule button 구조를 반영했다. + - 2026-06-22: Phase 5/6 코드 리뷰 중 empty 중앙 `후원하기` button 배경이 `@color/white`로 되어 있어 PRD의 `soda/400` 배경 및 흰색 icon/text 요구와 맞지 않는 문제를 확인했다. RED로 `CreatorChannelDonationFragmentLayoutTest`에 `bg_creator_channel_donation_empty_button.xml`의 `@color/soda_400` 계약을 추가했고, 기존 구현에서 실패하는 것을 확인한 뒤 배경을 `@color/soda_400`으로 수정했다. + - 2026-06-22: Phase 5/6 코드 리뷰 중 empty 상태 중앙 `후원하기` button으로 후원 API 실패 시 `CreatorChannelDonationViewModel.setActionToastMessage()`가 `Content` 상태에서만 메시지를 보관해 실패 toast가 사라지는 문제를 확인했다. RED로 `CreatorChannelDonationViewModelTest`에 `Empty 상태에서 채널 후원 실패는 action toast message를 emit하고 consume한다`를 추가했고, 기존 구현에서 `Empty.actionToastMessage` 부재로 FAIL하는 것을 확인했다. 이후 `Empty` 상태에도 `actionToastMessage`를 추가하고 `CreatorChannelDonationFragment.observeViewModel()`의 공통 경로에서 empty/content action toast를 표시하도록 수정했다. 수정 후 `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.donation.CreatorChannelDonationFragmentLayoutTest" --tests "kr.co.vividnext.sodalive.v2.creator.channel.donation.CreatorChannelDonationViewModelTest"`가 PASS했다. ### Phase 6: Activity 연결, 탭 연결, 전체보기/후원 액션 연결 -- [ ] **Task 6.1: PagerAdapter와 Activity source RED 테스트 작성** +- [x] **Task 6.1: PagerAdapter와 Activity source RED 테스트 작성** - 수정: - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelPagerAdapterTest.kt` - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivitySourceTest.kt` @@ -409,9 +412,9 @@ - 실행: `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelPagerAdapterTest" --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"` - 기대 결과: 구현 전에는 Donation 연결 부재로 FAIL한다. - 검증 기록: - - 미실행. 구현 시 RED 결과를 기록한다. + - 2026-06-22: `CreatorChannelPagerAdapterTest`에 `CreatorChannelTab.Donation`이 `CreatorChannelDonationFragment`를 생성해야 한다는 assertion을 추가하고, placeholder 유지 대상에서 Donation을 제외했다. `CreatorChannelActivitySourceTest`에는 `CreatorChannelDonationFragment.Host`, `findDonationFragment()`, 탭 선택/헤더 변경 시 load, scroll bottom dispatcher, load-more 판정, viewport 전달, 공통 `showCreatorChannelDonationDialog()` helper, 후원 완료 홈 refresh hook, `UserProfileDonationAllViewActivity` + `Constants.EXTRA_USER_ID` 이동 계약을 추가했다. 구현 전 focused RED 실행에서 Phase 5 신규 id 미존재로 unit test compile이 먼저 FAIL했고, 같은 RED 테스트 묶음에서 Donation 연결 production 코드 부재 상태를 고정했다. -- [ ] **Task 6.2: PagerAdapter Donation 연결** +- [x] **Task 6.2: PagerAdapter Donation 연결** - 수정: - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelPagerAdapter.kt` - 작업: @@ -421,9 +424,9 @@ - 실행: `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelPagerAdapterTest"` - 기대 결과: PagerAdapter 테스트가 PASS한다. - 검증 기록: - - 미실행. 구현 시 기록한다. + - 2026-06-22: `CreatorChannelPagerAdapter`에 `CreatorChannelDonationFragment` import와 `CreatorChannelTab.Donation -> CreatorChannelDonationFragment.newInstance(creatorId)` 분기를 추가했다. `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelPagerAdapterTest" --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"` 재실행에서 PagerAdapter Donation 생성 계약이 PASS했다. -- [ ] **Task 6.3: Activity Host와 scroll/viewport 연결** +- [x] **Task 6.3: Activity Host와 scroll/viewport 연결** - 수정: - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt` - 작업: @@ -438,9 +441,9 @@ - 실행: `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"` - 기대 결과: Activity source 계약이 PASS한다. - 검증 기록: - - 미실행. 구현 시 기록한다. + - 2026-06-22: `CreatorChannelActivity`가 `CreatorChannelDonationFragment.Host`를 구현하도록 추가하고, `findDonationFragment()`, 탭 선택/헤더 변경 시 `onCreatorChannelDonationTabSelected()`, `notifyCurrentCreatorChannelTabScrolledToBottom()`의 Donation 분기, `isCreatorChannelLoadMoreTab()` Donation 포함, `updateCreatorChannelTabViewportHeight()` Donation viewport 전달, `onCreatorChannelDonationContentChanged()`의 `updateViewPagerHeight { postCheckCreatorChannelCurrentTabNeedsMore() }` 연결을 구현했다. `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelPagerAdapterTest" --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"`가 PASS했다. -- [ ] **Task 6.4: Activity 후원 dialog 공통 helper와 후원 완료 hook 연결** +- [x] **Task 6.4: Activity 후원 dialog 공통 helper와 후원 완료 hook 연결** - 수정: - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt` - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelHomeFragment.kt` 필요 시 interface 유지 확인 @@ -454,9 +457,9 @@ - 실행: `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"` - 기대 결과: 홈 후원 액션 유지와 후원 탭 후원 dialog 재사용 source 계약이 PASS한다. - 검증 기록: - - 미실행. 구현 시 기록한다. + - 2026-06-22: 기존 `onCreatorChannelDonationClicked()`의 `LiveRoomDonationDialog` 생성 코드를 `showCreatorChannelDonationDialog(onSubmit)` helper로 분리했다. 홈 탭 후원은 helper submit에서 기존 `homeActionDelegate?.postChannelDonation(can = can, isSecret = isSecret, message = message)`를 호출해 동작을 유지하고, 후원 탭 Host의 `onCreatorChannelDonationRequested()`는 같은 helper에 Fragment ViewModel submit callback을 전달하도록 연결했다. `onCreatorChannelDonationCompleted()`에서는 `homeActionDelegate?.refreshHome()`를 호출한다. `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelPagerAdapterTest" --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"`가 PASS했다. -- [ ] **Task 6.5: 랭킹 전체보기 이동 연결** +- [x] **Task 6.5: 랭킹 전체보기 이동 연결** - 수정: - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt` - 작업: @@ -467,7 +470,7 @@ - 실행: `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.donation.CreatorChannelDonationActionTest" --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"` - 기대 결과: 전체보기 이동 source 계약이 PASS한다. - 검증 기록: - - 미실행. 구현 시 기록한다. + - 2026-06-22: `onCreatorChannelDonationRankingAllClicked()`에서 `Intent(this, UserProfileDonationAllViewActivity::class.java)`를 생성하고 `putExtra(Constants.EXTRA_USER_ID, creatorId)`로 기존 전체보기 Activity 호출 계약에 맞춰 연결했다. `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.donation.CreatorChannelDonationActionTest" --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"` 범위는 Phase 5/6 focused GREEN 명령들로 분리 검증했으며 모두 PASS했다. ### Phase 7: 통합 검증과 수동 확인 @@ -518,6 +521,7 @@ ## Verification Log +- 2026-06-22: Phase 5, 6 코드 리뷰 및 검증을 수행했다. 리뷰에서 empty 중앙 `후원하기` button 배경색이 `@color/white`라 `soda/400` 요구와 맞지 않는 문제, empty 상태 후원 실패 메시지가 `Content` 전용 action toast 상태에 막혀 사용자에게 표시되지 않을 수 있는 문제를 발견해 RED 테스트 후 수정했다. 검증으로 `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.donation.CreatorChannelDonationFragmentLayoutTest" --tests "kr.co.vividnext.sodalive.v2.creator.channel.donation.CreatorChannelDonationViewModelTest"`, `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.donation.*"`, `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.*Donation*"`, `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.*"`, `./gradlew :app:mergeDebugResources`, `./gradlew :app:compileDebugKotlin`, `./gradlew :app:ktlintCheck`, `git diff --check`가 PASS했다. `:app:mergeDebugResources`는 sandbox에서 Gradle wrapper lock 파일 접근 권한 문제로 1회 실패했고, 외부 권한으로 동일 명령을 재실행해 PASS를 확인했다. - 2026-06-22: Phase 2, 3, 4 코드 리뷰 및 재검증을 수행했다. API/DTO/Repository/ViewModel 계약, mapper 정책, content layout/adapter/Fragment 흐름을 대조했으며 차단급 코드 이슈는 발견하지 않았다. `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.donation.*"`, `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.*Donation*"`, `./gradlew :app:mergeDebugResources`, `./gradlew :app:compileDebugKotlin`, `./gradlew :app:ktlintCheck`, `git diff --check`가 PASS했다. `:app:mergeDebugResources`는 sandbox에서 Gradle wrapper lock 파일 접근 권한 문제로 1회 실패했고, 외부 권한으로 동일 명령을 재실행해 PASS를 확인했다. - 2026-06-22: 리뷰 지적에 따라 후원 성공 event가 `Content` 상태에 종속되지 않도록 후속 수정했다. RED로 `CreatorChannelDonationActionTest`에 `후원 fragment source는 성공 이벤트를 content 상태와 독립적으로 전달한다`를 추가했고, 기존 구현에서 `handleDonationSuccessEvent()` 부재로 FAIL하는 것을 확인했다. 이후 `CreatorChannelDonationFragment.observeViewModel()`의 상태 bind 후 공통 경로에서 `handleDonationSuccessEvent()`를 호출하도록 변경해 `Empty`, `Error`, `Content` 재조회 결과 모두 `Host.onCreatorChannelDonationCompleted()` 전달 대상이 되도록 했다. 수정 후 `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.donation.*"`, `./gradlew :app:compileDebugKotlin`, `./gradlew :app:ktlintCheck`, `git diff --check`가 PASS했다. - 2026-06-22: `docs/20260622_크리에이터_채널_후원_탭/prd.md`, `docs/agent-guides/work-plan-docs.md`, 기존 `docs/20260622_FanTalk_탭/plan-task.md` 구조를 확인해 후원 탭 구현 계획/TASK 문서를 작성했다. 이번 단계는 문서 작성만 수행했으며 구현/빌드/테스트는 실행하지 않았다.