docs(home): 인기 커뮤니티 검증을 기록한다

This commit is contained in:
2026-06-05 13:17:14 +09:00
parent 293f34ca13
commit 9c20b86373
2 changed files with 34 additions and 3 deletions

View File

@@ -346,7 +346,7 @@
### Phase 7: FeedCommunityView 추천 페이지 확장 ### Phase 7: FeedCommunityView 추천 페이지 확장
- [ ] **Task 7.1: FeedItem.Community 추천 필드 확장** - [x] **Task 7.1: FeedItem.Community 추천 필드 확장**
- 수정: `app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedItem.kt` - 수정: `app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedItem.kt`
- 추가 후보: - 추가 후보:
- `imageUrl: String?` - `imageUrl: String?`
@@ -356,7 +356,7 @@
- 주의: 기존 호출부 기본값을 제공해 기존 feed 사용처 영향 최소화. - 주의: 기존 호출부 기본값을 제공해 기존 feed 사용처 영향 최소화.
- 검증 명령: `./gradlew :app:compileDebugKotlin` - 검증 명령: `./gradlew :app:compileDebugKotlin`
- [ ] **Task 7.2: 커뮤니티 이미지/유료 overlay 레이아웃 추가** - [x] **Task 7.2: 커뮤니티 이미지/유료 overlay 레이아웃 추가**
- 수정: `app/src/main/res/layout/view_feed_community.xml` - 수정: `app/src/main/res/layout/view_feed_community.xml`
- 수정: `app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedCommunityView.kt` - 수정: `app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedCommunityView.kt`
- 수정: `app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedAdapter.kt` - 수정: `app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedAdapter.kt`
@@ -368,7 +368,7 @@
- `FeedImageViews.primary`로 커뮤니티 이미지도 외부에서 로드 가능하게 노출 - `FeedImageViews.primary`로 커뮤니티 이미지도 외부에서 로드 가능하게 노출
- 검증: 기존 Community variant는 기본값으로 keyword를 유지하고, 추천용 item만 keyword를 숨긴다. - 검증: 기존 Community variant는 기본값으로 keyword를 유지하고, 추천용 item만 keyword를 숨긴다.
- [ ] **Task 7.3: 인기 커뮤니티 섹션 바인딩** - [x] **Task 7.3: 인기 커뮤니티 섹션 바인딩**
- 생성 후보: `app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/ui/HomePopularCommunityAdapter.kt` - 생성 후보: `app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/ui/HomePopularCommunityAdapter.kt`
- 재사용: `FeedAdapter` 또는 `FeedCommunityView` - 재사용: `FeedAdapter` 또는 `FeedCommunityView`
- 구현 내용: - 구현 내용:
@@ -376,6 +376,25 @@
- `audioUrl`은 별도 플레이어 UI 없이 상세 이동 데이터로만 유지 - `audioUrl`은 별도 플레이어 UI 없이 상세 이동 데이터로만 유지
- 검증: keyword 미노출, 이미지 null이면 이미지 영역 `GONE`. - 검증: keyword 미노출, 이미지 null이면 이미지 영역 `GONE`.
- [x] **Task 7.4: 실기기 확인용 인기 커뮤니티 샘플 데이터 주입**
- 수정: `app/src/main/java/kr/co/vividnext/sodalive/v2/main/HomeMainFragment.kt`
- 구현 내용:
- 기존 `phase6SampleContent()``popularCommunityPosts` 빈 목록을 무료/유료 미구매/구매 완료 샘플 3건으로 교체
- 추천용 커뮤니티 샘플은 `showKeyword = false`로 유지
- 유료 미구매 샘플은 lock overlay와 가격 capsule 확인용으로 구성
- 주의: Phase 9 실제 API/ViewModel 바인딩 시 임시 샘플 데이터는 실제 상태 바인딩으로 교체한다.
- 검증: 실제 기기에서 인기 커뮤니티 섹션과 카드 상태 3종을 육안 확인할 수 있다.
- [x] **Task 7.5: 커뮤니티 이미지 고정 크기 제거와 동적 비율 적용**
- 수정: `app/src/main/res/layout/view_feed_community.xml`
- 수정: `app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedCommunityView.kt`
- 수정: `app/src/test/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedViewTest.kt`
- 구현 내용:
- `FeedCommunityView` root와 이미지 container의 고정 폭을 제거하고 `match_parent`로 변경
- 이미지 container 높이는 실제 card content width 기준으로 Figma `346:236` 비율을 유지해 계산
- Kotlin `clipToOutline`/`ViewOutlineProvider.setRoundRect(...)` clipping 계약 유지
- 검증: 인기 커뮤니티 이미지 영역이 화면 폭에 맞춰 계산되어 고정 폭 때문에 잘리지 않는다.
--- ---
### Phase 8: 사업자 정보 접기/더보기 구현 ### Phase 8: 사업자 정보 접기/더보기 구현
@@ -509,3 +528,10 @@
- 2026-06-04: 실제 화면에서 장르 크리에이터 grid 우측 끝 이미지가 절반 정도 잘리는 문제를 수정했다. 원인은 profile size 계산 시 group item width가 아직 `MATCH_PARENT`이거나 미측정일 때 display width fallback을 사용해 cell이 과대 계산될 수 있는 점이었다. 구현 전 `HomeMainFragmentLayoutTest`에 group width가 미확정인 상황에서도 parent RecyclerView width `360dp` 기준으로 cell size가 계산되는 회귀 테스트를 추가했고, 기존 display width fallback에서 RED 실패를 확인했다. 이후 `HomeGenreCreatorAdapter.GenreCreatorGroupViewHolder`가 parent RecyclerView를 보관하고, card width가 확정되지 않은 경우 `parent.width - 28dp`를 사용해 profile cell 크기를 계산하도록 수정했다. 수정 후 `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.HomeMainFragmentLayoutTest"`, `./gradlew :app:compileDebugKotlin`, `./gradlew :app:ktlintCheck`를 실행했고 모두 BUILD SUCCESSFUL을 확인했다. - 2026-06-04: 실제 화면에서 장르 크리에이터 grid 우측 끝 이미지가 절반 정도 잘리는 문제를 수정했다. 원인은 profile size 계산 시 group item width가 아직 `MATCH_PARENT`이거나 미측정일 때 display width fallback을 사용해 cell이 과대 계산될 수 있는 점이었다. 구현 전 `HomeMainFragmentLayoutTest`에 group width가 미확정인 상황에서도 parent RecyclerView width `360dp` 기준으로 cell size가 계산되는 회귀 테스트를 추가했고, 기존 display width fallback에서 RED 실패를 확인했다. 이후 `HomeGenreCreatorAdapter.GenreCreatorGroupViewHolder`가 parent RecyclerView를 보관하고, card width가 확정되지 않은 경우 `parent.width - 28dp`를 사용해 profile cell 크기를 계산하도록 수정했다. 수정 후 `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.HomeMainFragmentLayoutTest"`, `./gradlew :app:compileDebugKotlin`, `./gradlew :app:ktlintCheck`를 실행했고 모두 BUILD SUCCESSFUL을 확인했다.
- 2026-06-04: 한국어/영어 장르 suffix의 선행 공백이 실제 기기에서 보이지 않고, 우측 끝 profile image가 일부 잘리는 문제를 추가 수정했다. 일본어에는 공백을 넣으면 안 되므로 title row margin 방식은 사용하지 않고 한국어/영어 string에 `\u0020`를 사용해 선행 공백을 보존했다. `xml:space="preserve"` 시도는 Android resource merge에서 실패해 제거했고, stale incremental resource 산출물(`app/build/intermediates/incremental/debug/packageDebugResources`, `mergeDebugResources`)을 삭제한 뒤 재검증했다. profile cell 크기는 itemView 측정 폭이 parent RecyclerView content 폭보다 크게 잡히는 경우를 방지하도록 parent padding을 제외한 content width로 cap 했다. 구현 전 `HomeMainFragmentLayoutTest`에 parent padding이 있는 상태에서 measured group width가 과대 측정되어도 cell size가 `RecyclerView content width` 기준으로 계산되는 회귀 테스트와 한국어/영어는 선행 공백, 일본어는 선행 공백 없음 테스트를 추가해 RED 실패를 확인했다. 수정 후 `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.HomeMainFragmentLayoutTest"`, `./gradlew :app:mergeDebugResources`, `./gradlew :app:compileDebugKotlin`, `./gradlew :app:ktlintCheck`를 실행했고 모두 BUILD SUCCESSFUL을 확인했다. - 2026-06-04: 한국어/영어 장르 suffix의 선행 공백이 실제 기기에서 보이지 않고, 우측 끝 profile image가 일부 잘리는 문제를 추가 수정했다. 일본어에는 공백을 넣으면 안 되므로 title row margin 방식은 사용하지 않고 한국어/영어 string에 `\u0020`를 사용해 선행 공백을 보존했다. `xml:space="preserve"` 시도는 Android resource merge에서 실패해 제거했고, stale incremental resource 산출물(`app/build/intermediates/incremental/debug/packageDebugResources`, `mergeDebugResources`)을 삭제한 뒤 재검증했다. profile cell 크기는 itemView 측정 폭이 parent RecyclerView content 폭보다 크게 잡히는 경우를 방지하도록 parent padding을 제외한 content width로 cap 했다. 구현 전 `HomeMainFragmentLayoutTest`에 parent padding이 있는 상태에서 measured group width가 과대 측정되어도 cell size가 `RecyclerView content width` 기준으로 계산되는 회귀 테스트와 한국어/영어는 선행 공백, 일본어는 선행 공백 없음 테스트를 추가해 RED 실패를 확인했다. 수정 후 `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.HomeMainFragmentLayoutTest"`, `./gradlew :app:mergeDebugResources`, `./gradlew :app:compileDebugKotlin`, `./gradlew :app:ktlintCheck`를 실행했고 모두 BUILD SUCCESSFUL을 확인했다.
- 2026-06-04: 우측 profile image 잘림 범위가 group card/RecyclerView가 아니라 `item_home_genre_creator_group.xml` 내부 `GridLayout`임을 확인해, profile cell 계산 기준을 `GridLayout`의 실제 측정 width 우선으로 수정했다. 구현 전 `HomeMainFragmentLayoutTest`에 GridLayout width가 `300dp`로 측정된 경우 cell size가 `(300 - 14*3) / 4`로 계산되어야 하는 회귀 테스트를 추가했고, 기존 card width 기준 계산에서 RED 실패를 확인했다. 이후 `HomeGenreCreatorAdapter``calculateProfileSize()``creatorGrid.width`를 우선 사용하고, layout 이후 width가 확정되는 경우 `creatorGrid.post { ... }`에서 다시 바인딩해 재계산하도록 변경했다. 수정 후 `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.HomeMainFragmentLayoutTest"`, `./gradlew :app:compileDebugKotlin`, `./gradlew :app:ktlintCheck`를 실행했고 모두 BUILD SUCCESSFUL을 확인했다. - 2026-06-04: 우측 profile image 잘림 범위가 group card/RecyclerView가 아니라 `item_home_genre_creator_group.xml` 내부 `GridLayout`임을 확인해, profile cell 계산 기준을 `GridLayout`의 실제 측정 width 우선으로 수정했다. 구현 전 `HomeMainFragmentLayoutTest`에 GridLayout width가 `300dp`로 측정된 경우 cell size가 `(300 - 14*3) / 4`로 계산되어야 하는 회귀 테스트를 추가했고, 기존 card width 기준 계산에서 RED 실패를 확인했다. 이후 `HomeGenreCreatorAdapter``calculateProfileSize()``creatorGrid.width`를 우선 사용하고, layout 이후 width가 확정되는 경우 `creatorGrid.post { ... }`에서 다시 바인딩해 재계산하도록 변경했다. 수정 후 `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.HomeMainFragmentLayoutTest"`, `./gradlew :app:compileDebugKotlin`, `./gradlew :app:ktlintCheck`를 실행했고 모두 BUILD SUCCESSFUL을 확인했다.
- 2026-06-05: Figma `24:5645` 기준 Phase 7 인기 커뮤니티 섹션을 구현했다. 구현 전 `FeedViewTest``HomeMainFragmentLayoutTest`에 기존 Community keyword 기본 노출, 추천용 keyword 숨김, 이미지 null 시 이미지 영역 `GONE`, 유료 미구매 overlay/가격 capsule, 구매 완료 overlay 숨김, 인기 커뮤니티 최대 10개 노출 테스트를 추가했고, 기존 구현에서 새 필드/뷰/adapter/helper 미존재로 RED 컴파일 실패를 확인했다. 이후 `FeedItem.Community``imageUrl`, `price`, `existOrdered`, `showKeyword` 기본값 필드를 추가하고, `FeedCommunityView`/`FeedAdapter`가 커뮤니티 primary image와 유료 overlay를 지원하도록 확장했으며, `HomePopularCommunityAdapter``HomeMainFragment` 바인딩을 추가했다. `popularCommunityPosts`는 최대 10개만 표시한다.
- 2026-06-05: Phase 7 검증으로 `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.widget.feed.FeedViewTest" --tests "kr.co.vividnext.sodalive.v2.main.home.HomeMainFragmentLayoutTest"`, `./gradlew :app:mergeDebugResources`, `./gradlew :app:compileDebugKotlin`, `./gradlew :app:testDebugUnitTest`, `./gradlew :app:ktlintCheck`를 실행했고 모두 BUILD SUCCESSFUL을 확인했다. 최초 병렬 Gradle 실행은 KSP cache 경합으로 실패해 `./gradlew --stop` 후 순차 재실행했다. ktlint 최초 실행은 새 긴 줄 위반으로 실패했고 줄바꿈 수정 후 재실행으로 성공했다. `lsp_diagnostics`는 Kotlin/XML LSP 미구성으로 실행하지 못해 Gradle compile/test/ktlint로 보완했다.
- 2026-06-05: Phase 7 리뷰 게이트에서 `audioUrl` 상세 이동 데이터 유실과 유료 미구매 커뮤니티 원본 이미지 로드 가능성이 차단 이슈로 지적됐다. `HomeMainFragmentLayoutTest``popular community mapper preserves audio url for detail data`, `home popular community adapter does not load original image for locked paid post` 회귀 테스트를 추가했고, 구현 전 `audioUrl` 필드 미존재로 RED 컴파일 실패를 확인했다. 이후 `FeedItem.Community.audioUrl` 기본값 필드와 mapper 전달을 추가하고, `HomePopularCommunityAdapter``price > 0 && existOrdered == false`인 item의 원본 `imageUrl`을 로드하지 않도록 수정했다.
- 2026-06-05: Phase 7 차단 이슈 수정 후 `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.HomeMainFragmentLayoutTest"`, `./gradlew :app:mergeDebugResources`, `./gradlew :app:ktlintCheck`, `./gradlew :app:compileDebugKotlin`, `./gradlew :app:testDebugUnitTest`를 실행했고 모두 BUILD SUCCESSFUL을 확인했다.
- 2026-06-05: 보안 재리뷰에서 유료 미구매 item으로 재바인딩할 때 기존 Coil 비동기 요청이 늦게 완료될 가능성이 차단 이슈로 지적됐다. `HomePopularCommunityAdapter.bindImage()`의 null/blank 경로에서 `imageView.dispose()`로 기존 Coil 요청을 취소한 뒤 drawable을 비우도록 보완했다. 이후 `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.HomeMainFragmentLayoutTest"`, `./gradlew :app:compileDebugKotlin`, `./gradlew :app:ktlintCheck`, `./gradlew :app:testDebugUnitTest`를 실행했고 모두 BUILD SUCCESSFUL을 확인했다.
- 2026-06-05: Phase 7 인기 커뮤니티 UI를 실제 기기에서 확인할 수 있도록 `HomeMainFragment.phase6SampleContent()``popularCommunityPosts`에 무료/유료 미구매/구매 완료 샘플 3건을 임시 주입했다. 샘플은 추천용 계약에 맞춰 keyword를 숨기고, 유료 미구매 샘플은 lock overlay와 가격 capsule을 확인할 수 있게 구성했다. `./gradlew :app:compileDebugKotlin`, `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.HomeMainFragmentLayoutTest"`, `./gradlew :app:ktlintCheck`, `./gradlew :app:mergeDebugResources`는 모두 BUILD SUCCESSFUL을 확인했다. `./gradlew :app:installDebug`는 연결 기기가 없어 `No connected devices!`로 실패해 실기기 설치/육안 확인은 수행하지 못했다.
- 2026-06-05: 사용자 확인 중 커뮤니티 게시물 이미지가 잘리는 문제가 있어 `view_feed_community.xml`의 root `374dp`, 이미지 container `346dp x 236dp` 고정 크기를 제거했다. root와 이미지 container는 `match_parent`로 두고, `FeedCommunityView.onMeasure()`에서 실제 card content width 기준 Figma `346:236` 비율로 이미지 높이를 계산하도록 변경했다. Kotlin `clipToOutline`/`ViewOutlineProvider.setRoundRect(...)` 계약은 유지했다. `FeedViewTest`에 동적 이미지 폭/높이 회귀 테스트를 추가했으며, 최초 테스트는 이미지 URL 미바인딩으로 container가 `GONE`이라 실패했고 테스트 조건을 실제 표시 상태로 수정한 뒤 성공했다. 이후 `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.widget.feed.FeedViewTest"`, `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.HomeMainFragmentLayoutTest"`, `./gradlew :app:compileDebugKotlin`, `./gradlew :app:mergeDebugResources`, `./gradlew :app:ktlintCheck`가 모두 BUILD SUCCESSFUL임을 확인했다.

View File

@@ -414,3 +414,8 @@ HomeRecommendation 화면
- 2026-06-01: 사용자 추가 제공 정보에 따라 `HomeFirstAudioContentItem`에서는 오리지널 여부를 판단하지 않고, 오리지널 태그를 항상 숨기는 정책으로 PRD에 반영했다. - 2026-06-01: 사용자 추가 제공 정보에 따라 `HomeFirstAudioContentItem`에서는 오리지널 여부를 판단하지 않고, 오리지널 태그를 항상 숨기는 정책으로 PRD에 반영했다.
- 2026-06-01: 사용자 추가 제공 정보에 따라 `popularCommunityPosts.price``existOrdered` 조합으로 유료 미구매/유료 구매 완료/무료 포스트 UI를 판정하도록 PRD에 반영했다. - 2026-06-01: 사용자 추가 제공 정보에 따라 `popularCommunityPosts.price``existOrdered` 조합으로 유료 미구매/유료 구매 완료/무료 포스트 UI를 판정하도록 PRD에 반영했다.
- 2026-06-02: 사용자 추가 제공 정보에 따라 `ViewPager`/swipe tab 전환을 제외하고, tab 글자 터치 전환만 허용하며, `TextTabBarView` 아래 추천 content 영역만 세로 스크롤되도록 요구사항을 반영했다. - 2026-06-02: 사용자 추가 제공 정보에 따라 `ViewPager`/swipe tab 전환을 제외하고, tab 글자 터치 전환만 허용하며, `TextTabBarView` 아래 추천 content 영역만 세로 스크롤되도록 요구사항을 반영했다.
- 2026-06-05: Phase 7 구현에서 Figma `24:5645` 기준 인기 커뮤니티 섹션을 `FeedCommunityView` 확장과 `HomePopularCommunityAdapter`로 연결했다. 추천용 커뮤니티는 keyword를 숨기고, 이미지 null 시 이미지 영역을 숨기며, 유료 미구매 상태에서는 overlay와 가격 capsule을 표시한다. 사용자 추가 요청에 따라 인기 커뮤니티 게시글은 최대 10개만 노출하도록 반영했고, 관련 targeted test/full unit test/resource merge/compile/ktlint가 성공했음을 확인했다.
- 2026-06-05: Phase 7 리뷰에서 확인된 `audioUrl` 상세 이동 데이터 보존 누락과 유료 미구매 원본 이미지 로드 위험을 수정했다. `FeedItem.Community.audioUrl`과 mapper 전달을 추가하고, 유료 미구매 item은 원본 `imageUrl`을 로드하지 않도록 adapter를 보완했으며 관련 회귀 테스트와 Gradle 검증이 성공했다.
- 2026-06-05: 유료 미구매 item 재바인딩 시 이전 Coil 요청이 뒤늦게 완료될 가능성을 방지하기 위해 locked image 경로에서 기존 Coil 요청을 `dispose()`로 취소한 뒤 drawable을 비우도록 추가 보완했다.
- 2026-06-05: 인기 커뮤니티 Phase 7 UI를 실제 기기에서 확인할 수 있도록 `HomeMainFragment`의 임시 샘플 content에 무료/유료 미구매/구매 완료 커뮤니티 3건을 추가했다. 관련 컴파일, 홈 레이아웃 테스트, ktlint, resource merge는 성공했으나 연결 기기가 없어 `installDebug` 기반 실기기 확인은 수행하지 못했다.
- 2026-06-05: 커뮤니티 게시물 이미지가 고정 크기 때문에 잘려 보이는 문제를 수정했다. `view_feed_community.xml`에서 root와 이미지 container의 고정 폭/높이를 제거하고, `FeedCommunityView`에서 실제 card content width 기준 `346:236` 비율로 이미지 영역 높이를 계산하도록 변경했다. 관련 Feed/Home 테스트, compile, resource merge, ktlint가 성공했다.