diff --git a/docs/20260621_크리에이터_채널_커뮤니티_탭/plan-task.md b/docs/20260621_크리에이터_채널_커뮤니티_탭/plan-task.md index 1e7be743..b37c7bf4 100644 --- a/docs/20260621_크리에이터_채널_커뮤니티_탭/plan-task.md +++ b/docs/20260621_크리에이터_채널_커뮤니티_탭/plan-task.md @@ -553,6 +553,52 @@ ## Verification Log - 계획 문서 생성 단계에서는 코드 변경을 수행하지 않았다. 구현 후 통합 검증, 회귀 검증, 최종 수동 확인 기록을 이 섹션에 누적한다. +- 2026-06-22 수동 확인 후속 UI 불일치 수정 계획: + - 발견 항목: 썸네일형 전환 시 3열 Grid가 시각적으로 유지되지 않는 문제, 리스트형 공지 표시가 Figma와 다른 문제, 중앙/우측 상단 유료 가격 capsule이 Figma와 다른 문제, 게시물 이미지 14dp radius 미반영 및 GIF 미재생 문제를 확인했다. + - 수정 범위: `item_creator_channel_community_grid.xml`, `item_creator_channel_community_list.xml`, `CreatorChannelCommunityGridAdapter.kt`, `CreatorChannelCommunityListAdapter.kt`에 한정한다. 레거시 커뮤니티 파일과 공용 `ImageExtensions.loadUrl()`은 수정하지 않는다. + - TDD 예외 사유: 이번 후속 수정은 RecyclerView item 측정, XML 배치, bitmap/GIF 로딩 라이브러리 전환처럼 실제 Android 렌더링 표면에서 확인되는 시각 보정이다. 기존 layout/source 테스트가 구조 존재와 연결을 이미 검증하고 있어, 새 production 변경 전 실패하는 순수 단위 테스트를 안정적으로 만들기 어렵다. 대신 resource merge, Kotlin compile, ktlint, diff check와 소스 기반 표면 검증으로 확인한다. + - 기대 결과: 썸네일형은 `GridLayoutManager(3)`에서 정사각형 item 높이를 명시적으로 받아 3열 Grid로 표시되고, 리스트형 공지는 pin icon + `Notice` 행으로 표시되며, 유료 가격 capsule은 중앙/우측 상단 Figma 형태를 따른다. 게시물 이미지는 Glide `CenterCrop + RoundedCorners(14dp)`로 로드되어 GIF 재생과 14dp radius를 지원한다. + +- 2026-06-22 수동 확인 후속 UI 불일치 수정 검증: + - 수정 기록: Grid item root 높이를 adapter가 계산한 정사각형 크기로 직접 지정할 수 있게 XML root를 `match_parent`로 변경하고, Grid/List 게시물 이미지는 Glide `CenterCrop + RoundedCorners(14dp)`로 로딩하도록 전환했다. 리스트형 공지는 item 최상단 pin icon + `Notice` 행으로 이동했고, owner 우측 상단 가격 capsule과 중앙 locked 가격 capsule의 크기/typography/icon gap을 Figma 기준에 맞게 조정했다. + - 보정 기록: 최초 검증에서 `@color/point_400` 미존재로 resource linking이 실패해 기존 design token `@color/green_400(#73FF01)`로 교체했다. 기존 layout/source 테스트 3건은 새 XML 구조와 adapter 정사각형 계약에 맞게 기대값을 갱신했다. + - 검증: `./gradlew :app:mergeDebugResources` PASS, `./gradlew :app:compileDebugKotlin` PASS, `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*"` PASS, `./gradlew :app:ktlintCheck` PASS, `git diff --check` PASS. + - 수동 확인: `adb devices` 결과 연결된 기기가 없어 실제 앱에서 리스트/썸네일 토글, GIF 재생, radius, 공지/가격 표시를 직접 조작 검증하지 못했다. 이번 세션에서는 Figma screenshot 대조, source/layout 검증, resource/compile/test/lint로 대체했다. + - 리뷰어 게이트: visual-engineering reviewer가 변경 파일, Figma 이슈 4건, 검증 증거, 실제 기기 QA 제한을 검토했고 blocking issue 없음으로 PASS했다. + +- 2026-06-22 썸네일형 후속 동작 보정 계획: + - 요구사항: 썸네일형에서는 GIF 재생을 요구하지 않고 정적 썸네일 표시를 허용한다. 썸네일형 item은 모두 정사각형 비율을 유지해야 하며, 썸네일형 상태에서도 스크롤 하단 pagination이 동작해야 한다. + - 수정 계획: `CreatorChannelCommunityGridAdapter`의 Glide 요청은 grid 전용으로 `asBitmap()`을 사용해 정적 이미지를 로드하고, 리스트형 adapter의 GIF 재생 가능 경로는 유지한다. `CreatorChannelActivity`는 Community content/view mode 변경으로 ViewPager 높이를 갱신한 뒤 현재 하단 조건을 재평가해 NestedScrollView의 추가 scroll 이벤트가 없어도 load-more 경로가 호출되도록 보정한다. + - 검증 계획: `CreatorChannelCommunityFragmentLayoutTest`, `CreatorChannelActivitySourceTest`, community 관련 unit test, `mergeDebugResources`, `compileDebugKotlin`, `ktlintCheck`, `git diff --check`를 실행한다. + - 수정 기록: Grid adapter 이미지 요청에 `asBitmap()`을 적용해 썸네일형 GIF를 정적 이미지로 로드하도록 했다. `updateViewPagerHeight()`에 height 갱신 이후 callback을 추가하고 Community/Live/Audio/Series content 변경 시 높이 갱신 후 bottom 조건을 재평가하도록 순서를 보장했다. + - 검증: focused source/layout test 최초 실행은 기존 source test가 `updateViewPagerHeight()` 시그니처와 height 비교 문자열을 고정해 둔 탓에 2건 실패했고, 새 계약에 맞춰 테스트 기대값을 갱신한 뒤 `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.CreatorChannelCommunityFragmentLayoutTest" --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"` PASS를 확인했다. + - 회귀/빌드: `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*"` PASS, `./gradlew :app:mergeDebugResources :app:compileDebugKotlin :app:ktlintCheck` PASS, `git diff --check` PASS. `ktlintCheck`는 기존 `.editorconfig disabled_rules` deprecation 경고만 출력됐다. + - 수동 확인: 현재 세션에서는 연결된 기기/에뮬레이터가 없어 실제 화면에서 썸네일형 스크롤 pagination과 GIF 정적 표시를 직접 조작 검증하지 못했다. + - 리뷰 보정 계획: context mining reviewer가 content/view mode 변경 후 bottom 재평가 경로가 기존 scroll listener의 200dp threshold와 달리 `remainingScroll <= 0`만 사용한다고 지적했다. `checkCreatorChannelCurrentTabNeedsMore()`도 동일 threshold를 사용하도록 보정하고, PRD의 GIF 재생 문구를 리스트형/썸네일형 기준으로 분리한다. + - 리뷰 보정 검증: `checkCreatorChannelCurrentTabNeedsMore()`가 `CREATOR_CHANNEL_LOAD_MORE_THRESHOLD_DP`를 사용하도록 수정했고, `CreatorChannelActivitySourceTest`에 threshold 재사용 검증을 추가했다. PRD의 GIF 문구는 리스트형은 재생, 썸네일형은 정적 썸네일 허용으로 분리했다. `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.CreatorChannelCommunityFragmentLayoutTest" --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"` PASS, `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*"` PASS, `./gradlew :app:mergeDebugResources :app:compileDebugKotlin :app:ktlintCheck` PASS, `git diff --check` PASS. + - 추가 보정 계획: 수동 확인 요청에 따라 썸네일형 Grid는 3등분 구조와 기존 item margin을 유지하되, 이미지가 있는 item content가 세로로 길어지지 않고 1:1 비율을 가져야 한다. margin을 포함한 cell 폭에서 좌우 margin을 제외한 content width를 계산하고 같은 값을 height로 지정한다. + - 추가 보정 기록: `item_creator_channel_community_grid.xml` root margin은 유지했고, `CreatorChannelCommunityGridAdapter`의 item size 계산은 `(availableWidth - itemHorizontalMargins * 3) / 3`을 사용하는 helper로 분리했다. `CreatorChannelCommunityFragmentLayoutTest`는 360px 가용 폭과 좌우 margin 8px 기준 content 112px, 365px 기준 113px, 좁은 폭 0px 계산과 `height = squareSize` 계약을 검증한다. + - 추가 보정 검증: `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.CreatorChannelCommunityFragmentLayoutTest"` PASS. + +- 2026-06-22 썸네일형 Grid Figma/레거시 재보정: + - 기준 확인: Figma `290:9078`은 134px 정사각 item이 gap 0으로 배치되고, Figma `290:9079` 공지 item은 우측 상단 pin icon만 표시한다. 레거시 `CreatorCommunityAllGridAdapter`는 bind 시 root `layoutParams.width`와 `height`를 같은 `itemSize`로 지정하고, `item_creator_community_all_grid.xml`은 pin icon `ImageView`를 `top|end`에 둔다. + - RED: 새 source/layout 계약을 먼저 추가했고, production 보정 전 `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.CreatorChannelCommunityFragmentLayoutTest"`는 `iv_creator_channel_community_grid_notice` 미존재와 helper signature 불일치로 `compileDebugUnitTestKotlin` 실패를 확인했다. + - 수정 기록: v2 Grid adapter도 레거시처럼 `setItemSizePx()`로 item size를 받아 root width/height를 같은 값으로 고정하도록 변경했다. Grid mode에서는 RecyclerView 좌우 padding을 0으로 조정해 Figma처럼 item 사이 gap이 생기지 않게 했고, list mode 복귀 시 좌우 14dp padding을 복구한다. Grid notice는 text label 대신 우측 상단 `ic_pin` ImageView로 변경했다. + - GREEN: `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.CreatorChannelCommunityFragmentLayoutTest"` PASS. + - 리뷰 게이트 FAIL: 5-agent review에서 code quality reviewer는 Grid item size가 RecyclerView width 측정 전 0으로 계산되면 `itemSizePx`가 0으로 남을 수 있다고 지적했고, context mining reviewer는 locked grid tile에서 text preview가 lock overlay 뒤에 표시될 수 있다고 지적했다. QA reviewer는 debug build 설치와 deep link 진입까지 확인했지만 테스트 creator id의 API error 상태로 실제 grid content visual QA는 blocked로 판정했다. + - 리뷰 보정 RED: `CreatorChannelCommunityFragmentLayoutTest`에 layout 이후 `doOnLayout` 기반 size 재계산 계약과 locked grid item에서 text preview를 숨기는 계약을 추가했다. Production 보정 전 focused test는 `updateGridItemSize()`/`doOnLayout` 미존재와 locked text 조건 미충족으로 2건 실패했다. + - 리뷰 보정 기록: Grid mode bind 시 `updateGridItemSize()`를 즉시 호출하고 `RecyclerView.doOnLayout { updateGridItemSize() }`로 width 측정 이후 item size를 재계산하도록 했다. Grid adapter는 `!item.isLocked && item.imageMode != CreatorChannelCommunityImageMode.Image`일 때만 text preview를 표시해 locked tile은 lock/price overlay만 보이도록 했다. + - 리뷰 보정 GREEN: `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.CreatorChannelCommunityFragmentLayoutTest"` PASS. + +- 2026-06-22 썸네일형 Grid rounded corner 제거 계획: + - 요구사항: 썸네일형 Grid item은 rounded corner를 제거하고 정사각 모서리로 표시한다. 리스트형 게시물 이미지의 14dp radius와 GIF 재생 정책은 유지한다. + - 수정 계획: `CreatorChannelCommunityGridAdapter`에서 Grid 전용 `RoundedCorners(14dp)` transform과 root `clipToOutline`을 제거한다. `item_creator_channel_community_grid.xml`의 Grid root/image rounded drawable background는 non-rounded 배경으로 교체한다. 공유 drawable과 레거시 파일은 수정하지 않는다. + - 검증 계획: `CreatorChannelCommunityFragmentLayoutTest`에 Grid rounded corner 제거 계약을 RED로 추가한 뒤 production 보정 후 focused/community regression, resource merge, Kotlin compile, ktlint, `git diff --check`를 실행한다. + - RED: `CreatorChannelCommunityFragmentLayoutTest`에 Grid XML이 `bg_feed_card`/`bg_feed_community_image`를 사용하지 않고, Grid adapter source가 `RoundedCorners`, `14f.dpToPx()`, `root.clipToOutline = true`를 포함하지 않는다는 계약을 추가했다. Production 보정 전 `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.CreatorChannelCommunityFragmentLayoutTest"`는 rounded drawable background와 `RoundedCorners` 사용으로 2건 실패했다. + - 수정 기록: `CreatorChannelCommunityGridAdapter`에서 `RoundedCorners` transform, `dpToPx` import, root `clipToOutline` 설정을 제거하고 `CenterCrop()`만 유지했다. `item_creator_channel_community_grid.xml`의 root/image background는 공유 rounded drawable 대신 `@color/gray_900`으로 변경했다. + - GREEN: `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.CreatorChannelCommunityFragmentLayoutTest"` PASS. + - 회귀/빌드: `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*" --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"` PASS, `./gradlew :app:mergeDebugResources :app:compileDebugKotlin :app:ktlintCheck` PASS, `git diff --check` PASS. `ktlintCheck`는 기존 `.editorconfig disabled_rules` deprecation 경고만 출력됐다. + - 2026-06-21 Phase 2 검증: - RED: `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.CreatorChannelCommunityViewModelTest" --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.CreatorChannelCommunityPaginationTest"`는 production ViewModel 구현 전 `CreatorChannelCommunityViewModel`/`CreatorChannelCommunityUiState`/`CreatorChannelCommunityViewMode` 미구현으로 `:app:compileDebugUnitTestKotlin` 실패를 확인했다. - GREEN: `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*"` PASS.