docs(content): 추천 탭 Phase 1-3 검증을 기록한다
This commit is contained in:
@@ -112,7 +112,7 @@
|
|||||||
|
|
||||||
### Phase 1: 기존 구조 확인과 작업 경계 고정
|
### Phase 1: 기존 구조 확인과 작업 경계 고정
|
||||||
|
|
||||||
- [ ] **Task 1.1: 현재 ContentMainFragment와 MainV2 연결 확인**
|
- [x] **Task 1.1: 현재 ContentMainFragment와 MainV2 연결 확인**
|
||||||
- 확인:
|
- 확인:
|
||||||
- `app/src/main/java/kr/co/vividnext/sodalive/v2/main/ContentMainFragment.kt`
|
- `app/src/main/java/kr/co/vividnext/sodalive/v2/main/ContentMainFragment.kt`
|
||||||
- `app/src/main/java/kr/co/vividnext/sodalive/v2/main/MainV2Activity.kt`
|
- `app/src/main/java/kr/co/vividnext/sodalive/v2/main/MainV2Activity.kt`
|
||||||
@@ -123,8 +123,10 @@
|
|||||||
- 검증:
|
- 검증:
|
||||||
- `rg -n "ContentMainFragment|MainV2Tab.CONTENT|fragment_v2_main_content" app/src/main/java app/src/main/res`
|
- `rg -n "ContentMainFragment|MainV2Tab.CONTENT|fragment_v2_main_content" app/src/main/java app/src/main/res`
|
||||||
- 기대 결과: 이동 전/후 참조 지점이 모두 확인된다.
|
- 기대 결과: 이동 전/후 참조 지점이 모두 확인된다.
|
||||||
|
- 검증 기록:
|
||||||
|
- 2026-06-23: 이동 전 `ContentMainFragment`가 빈 `FragmentV2MainContentBinding` inflate Fragment이고, `fragment_v2_main_content.xml`이 black `FrameLayout`만 가진 상태임을 확인했다. 이동 후 `MainV2Activity`는 `kr.co.vividnext.sodalive.v2.main.content.ContentMainFragment` import와 `MainV2Tab.CONTENT -> ContentMainFragment()` 참조를 사용한다.
|
||||||
|
|
||||||
- [ ] **Task 1.2: 재사용 위젯과 신규 item 범위 확정**
|
- [x] **Task 1.2: 재사용 위젯과 신규 item 범위 확정**
|
||||||
- 확인:
|
- 확인:
|
||||||
- `app/src/main/java/kr/co/vividnext/sodalive/v2/widget/banner/BannerView.kt`
|
- `app/src/main/java/kr/co/vividnext/sodalive/v2/widget/banner/BannerView.kt`
|
||||||
- `app/src/main/java/kr/co/vividnext/sodalive/v2/widget/banner/BannerItem.kt`
|
- `app/src/main/java/kr/co/vividnext/sodalive/v2/widget/banner/BannerItem.kt`
|
||||||
@@ -141,8 +143,10 @@
|
|||||||
- `New&Hot`, `최근 댓글이 많은 오디오`는 Figma 구조가 공통 카드와 달라 신규 item view로 처리한다.
|
- `New&Hot`, `최근 댓글이 많은 오디오`는 Figma 구조가 공통 카드와 달라 신규 item view로 처리한다.
|
||||||
- 검증:
|
- 검증:
|
||||||
- PRD의 재사용 후보와 신규 item 범위가 일치하는지 문서상 체크한다.
|
- PRD의 재사용 후보와 신규 item 범위가 일치하는지 문서상 체크한다.
|
||||||
|
- 검증 기록:
|
||||||
|
- 2026-06-23: Phase 1~3에서는 adapter/item view를 만들지 않고, Phase 4 이후 계획대로 `BannerView`, `AudioContentCardView`, 신규 original/New&Hot/comment item 범위를 유지하는 것으로 확인했다.
|
||||||
|
|
||||||
- [ ] **Task 1.3: title-bar icon asset 확인**
|
- [x] **Task 1.3: title-bar icon asset 확인**
|
||||||
- 확인:
|
- 확인:
|
||||||
- `app/src/main/res/drawable-mdpi/ic_bar_cash.png`
|
- `app/src/main/res/drawable-mdpi/ic_bar_cash.png`
|
||||||
- `app/src/main/res/drawable-mdpi/ic_bar_search.png`
|
- `app/src/main/res/drawable-mdpi/ic_bar_search.png`
|
||||||
@@ -154,12 +158,14 @@
|
|||||||
- 검증:
|
- 검증:
|
||||||
- `rg --files app/src/main/res/drawable-mdpi | rg "ic_bar_(cash|search|storage)\\.png$"`
|
- `rg --files app/src/main/res/drawable-mdpi | rg "ic_bar_(cash|search|storage)\\.png$"`
|
||||||
- 기대 결과: 3개 파일이 모두 출력된다.
|
- 기대 결과: 3개 파일이 모두 출력된다.
|
||||||
|
- 검증 기록:
|
||||||
|
- 2026-06-23: `ic_bar_cash.png`, `ic_bar_search.png`, `ic_bar_storage.png`가 `drawable-mdpi`에 있음을 확인했고, 홈 title-bar는 수정하지 않고 `view_title_bar_content.xml`을 별도 생성했다.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Phase 2: API, DTO, Repository, DI, ViewModel 계약 추가
|
### Phase 2: API, DTO, Repository, DI, ViewModel 계약 추가
|
||||||
|
|
||||||
- [ ] **Task 2.1: API/DTO/Repository 파일 생성**
|
- [x] **Task 2.1: API/DTO/Repository 파일 생성**
|
||||||
- 생성:
|
- 생성:
|
||||||
- `app/src/main/java/kr/co/vividnext/sodalive/v2/main/content/data/AudioRecommendationsApi.kt`
|
- `app/src/main/java/kr/co/vividnext/sodalive/v2/main/content/data/AudioRecommendationsApi.kt`
|
||||||
- `app/src/main/java/kr/co/vividnext/sodalive/v2/main/content/data/AudioRecommendationsModels.kt`
|
- `app/src/main/java/kr/co/vividnext/sodalive/v2/main/content/data/AudioRecommendationsModels.kt`
|
||||||
@@ -173,8 +179,10 @@
|
|||||||
- `./gradlew :app:compileDebugKotlin`
|
- `./gradlew :app:compileDebugKotlin`
|
||||||
- 기대 결과:
|
- 기대 결과:
|
||||||
- 신규 data layer 파일이 컴파일된다.
|
- 신규 data layer 파일이 컴파일된다.
|
||||||
|
- 검증 기록:
|
||||||
|
- 2026-06-23: `AudioRecommendationsApi`, `AudioRecommendationsModels`, `AudioRecommendationsRepository`를 생성했다. `./gradlew :app:compileDebugKotlin` 순차 재실행 결과 `BUILD SUCCESSFUL`.
|
||||||
|
|
||||||
- [ ] **Task 2.2: UI model과 mapper RED 테스트 작성**
|
- [x] **Task 2.2: UI model과 mapper RED 테스트 작성**
|
||||||
- 생성:
|
- 생성:
|
||||||
- `app/src/test/java/kr/co/vividnext/sodalive/v2/main/content/AudioRecommendationsMapperTest.kt`
|
- `app/src/test/java/kr/co/vividnext/sodalive/v2/main/content/AudioRecommendationsMapperTest.kt`
|
||||||
- 테스트 케이스:
|
- 테스트 케이스:
|
||||||
@@ -190,8 +198,10 @@
|
|||||||
- `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.content.AudioRecommendationsMapperTest"`
|
- `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.content.AudioRecommendationsMapperTest"`
|
||||||
- 기대 결과:
|
- 기대 결과:
|
||||||
- mapper 구현 전 실패한다.
|
- mapper 구현 전 실패한다.
|
||||||
|
- 검증 기록:
|
||||||
|
- 2026-06-23: `AudioRecommendationsMapperTest`를 먼저 추가했고, production `data`/`model` 패키지와 `toContent()`가 없어 `compileDebugUnitTestKotlin`에서 `Unresolved reference 'data'`, `Unresolved reference 'model'`로 실패하는 RED를 확인했다.
|
||||||
|
|
||||||
- [ ] **Task 2.3: UI model과 mapper 구현**
|
- [x] **Task 2.3: UI model과 mapper 구현**
|
||||||
- 생성:
|
- 생성:
|
||||||
- `app/src/main/java/kr/co/vividnext/sodalive/v2/main/content/model/AudioRecommendationsUiState.kt`
|
- `app/src/main/java/kr/co/vividnext/sodalive/v2/main/content/model/AudioRecommendationsUiState.kt`
|
||||||
- `app/src/main/java/kr/co/vividnext/sodalive/v2/main/content/model/AudioRecommendationsUiModels.kt`
|
- `app/src/main/java/kr/co/vividnext/sodalive/v2/main/content/model/AudioRecommendationsUiModels.kt`
|
||||||
@@ -208,8 +218,10 @@
|
|||||||
- `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.content.AudioRecommendationsMapperTest"`
|
- `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.content.AudioRecommendationsMapperTest"`
|
||||||
- 기대 결과:
|
- 기대 결과:
|
||||||
- mapper 테스트가 PASS한다.
|
- mapper 테스트가 PASS한다.
|
||||||
|
- 검증 기록:
|
||||||
|
- 2026-06-23: `AudioRecommendationsUiState`, `AudioRecommendationsUiModels`, `AudioRecommendationsMappers`를 구현했다. `duration`은 UI model에 넣지 않았고, 태그/성인 badge/comment 표시 flag/empty 판단을 테스트로 확인했다. `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.content.AudioRecommendationsMapperTest"` 결과 `BUILD SUCCESSFUL`.
|
||||||
|
|
||||||
- [ ] **Task 2.4: ViewModel과 DI 등록**
|
- [x] **Task 2.4: ViewModel과 DI 등록**
|
||||||
- 생성:
|
- 생성:
|
||||||
- `app/src/main/java/kr/co/vividnext/sodalive/v2/main/content/ContentMainViewModel.kt`
|
- `app/src/main/java/kr/co/vividnext/sodalive/v2/main/content/ContentMainViewModel.kt`
|
||||||
- 수정:
|
- 수정:
|
||||||
@@ -224,12 +236,14 @@
|
|||||||
- `./gradlew :app:compileDebugKotlin`
|
- `./gradlew :app:compileDebugKotlin`
|
||||||
- 기대 결과:
|
- 기대 결과:
|
||||||
- Koin 등록과 ViewModel 생성이 컴파일된다.
|
- Koin 등록과 ViewModel 생성이 컴파일된다.
|
||||||
|
- 검증 기록:
|
||||||
|
- 2026-06-23: `ContentMainViewModel`을 추가하고 `AppDI`의 `networkModule`, `repositoryModule`, `viewModelModule`에 API/Repository/ViewModel을 등록했다. `./gradlew :app:compileDebugKotlin` 순차 재실행 결과 `BUILD SUCCESSFUL`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Phase 3: Fragment 이동, 고정 상단 UI, 기본 레이아웃 작성
|
### Phase 3: Fragment 이동, 고정 상단 UI, 기본 레이아웃 작성
|
||||||
|
|
||||||
- [ ] **Task 3.1: ContentMainFragment 패키지 이동**
|
- [x] **Task 3.1: ContentMainFragment 패키지 이동**
|
||||||
- Move:
|
- Move:
|
||||||
- `app/src/main/java/kr/co/vividnext/sodalive/v2/main/ContentMainFragment.kt` -> `app/src/main/java/kr/co/vividnext/sodalive/v2/main/content/ContentMainFragment.kt`
|
- `app/src/main/java/kr/co/vividnext/sodalive/v2/main/ContentMainFragment.kt` -> `app/src/main/java/kr/co/vividnext/sodalive/v2/main/content/ContentMainFragment.kt`
|
||||||
- 수정:
|
- 수정:
|
||||||
@@ -241,8 +255,10 @@
|
|||||||
- `./gradlew :app:compileDebugKotlin`
|
- `./gradlew :app:compileDebugKotlin`
|
||||||
- 기대 결과:
|
- 기대 결과:
|
||||||
- `MainV2Tab.CONTENT`가 이동된 Fragment를 정상 참조한다.
|
- `MainV2Tab.CONTENT`가 이동된 Fragment를 정상 참조한다.
|
||||||
|
- 검증 기록:
|
||||||
|
- 2026-06-23: `ContentMainFragment`를 `kr.co.vividnext.sodalive.v2.main.content`로 이동하고 `MainV2Activity` import를 갱신했다. `./gradlew :app:compileDebugKotlin` 순차 재실행 결과 `BUILD SUCCESSFUL`.
|
||||||
|
|
||||||
- [ ] **Task 3.2: content 추천 기본 레이아웃 작성**
|
- [x] **Task 3.2: content 추천 기본 레이아웃 작성**
|
||||||
- 수정:
|
- 수정:
|
||||||
- `app/src/main/res/layout/fragment_v2_main_content.xml`
|
- `app/src/main/res/layout/fragment_v2_main_content.xml`
|
||||||
- 생성:
|
- 생성:
|
||||||
@@ -259,8 +275,10 @@
|
|||||||
- `./gradlew :app:mergeDebugResources`
|
- `./gradlew :app:mergeDebugResources`
|
||||||
- 기대 결과:
|
- 기대 결과:
|
||||||
- ViewBinding class가 생성되고 resource merge가 PASS한다.
|
- ViewBinding class가 생성되고 resource merge가 PASS한다.
|
||||||
|
- 검증 기록:
|
||||||
|
- 2026-06-23: `fragment_v2_main_content.xml`을 고정 title-bar/tab-bar와 `NestedScrollView` 구조로 작성하고, 배너부터 추천 오디오까지 Phase 3 placeholder section을 배치했다. `추천 시리즈`, `키워드의 오디오` section container는 추가하지 않았다. `./gradlew :app:mergeDebugResources` 결과 `BUILD SUCCESSFUL`.
|
||||||
|
|
||||||
- [ ] **Task 3.3: title-bar와 tab-bar 바인딩**
|
- [x] **Task 3.3: title-bar와 tab-bar 바인딩**
|
||||||
- 수정:
|
- 수정:
|
||||||
- `app/src/main/java/kr/co/vividnext/sodalive/v2/main/content/ContentMainFragment.kt`
|
- `app/src/main/java/kr/co/vividnext/sodalive/v2/main/content/ContentMainFragment.kt`
|
||||||
- `app/src/main/res/values/strings.xml`
|
- `app/src/main/res/values/strings.xml`
|
||||||
@@ -269,6 +287,7 @@
|
|||||||
- 작업:
|
- 작업:
|
||||||
- 내부 tab-bar 메뉴는 `추천`을 첫 번째로 두고 selected index를 0으로 설정한다.
|
- 내부 tab-bar 메뉴는 `추천`을 첫 번째로 두고 selected index를 0으로 설정한다.
|
||||||
- 이번 범위에서는 다른 내부 탭 선택 시 화면 전환을 구현하지 않는다.
|
- 이번 범위에서는 다른 내부 탭 선택 시 화면 전환을 구현하지 않는다.
|
||||||
|
- title-bar 좌측은 이미지 로고가 아니라 하단 대화 탭과 같은 텍스트 title로 `콘텐츠`를 표시한다.
|
||||||
- title-bar 우측 icon 순서를 `ic_bar_cash`, `ic_bar_search`, `ic_bar_storage`로 맞춘다.
|
- title-bar 우측 icon 순서를 `ic_bar_cash`, `ic_bar_search`, `ic_bar_storage`로 맞춘다.
|
||||||
- 콘텐츠 추천 섹션 title string을 추가한다.
|
- 콘텐츠 추천 섹션 title string을 추가한다.
|
||||||
- 검증 명령:
|
- 검증 명령:
|
||||||
@@ -276,6 +295,8 @@
|
|||||||
- `./gradlew :app:compileDebugKotlin`
|
- `./gradlew :app:compileDebugKotlin`
|
||||||
- 기대 결과:
|
- 기대 결과:
|
||||||
- 문자열과 title-bar drawable 참조가 모두 resolve된다.
|
- 문자열과 title-bar drawable 참조가 모두 resolve된다.
|
||||||
|
- 검증 기록:
|
||||||
|
- 2026-06-23: `ContentMainFragment`에서 `textTabBarContent.root.setMenus(listOf(추천), selectedIndex = 0)`를 설정하고, 한국어/영어/일본어 string을 추가했다. `view_title_bar_content.xml`의 좌측은 하단 대화 탭과 같은 텍스트 title로 `screen_content_main_title`을 표시하고, 우측 아이콘은 `ic_bar_cash`, `ic_bar_search`, `ic_bar_storage` 순서로 배치했다. `./gradlew :app:mergeDebugResources`, `./gradlew :app:compileDebugKotlin` 결과 `BUILD SUCCESSFUL`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -462,3 +483,9 @@
|
|||||||
|
|
||||||
## Verification Log
|
## Verification Log
|
||||||
- 구현 중 여러 Phase에 걸친 통합 검증, 회귀 검증, 최종 수동 확인 기록을 여기에 누적한다.
|
- 구현 중 여러 Phase에 걸친 통합 검증, 회귀 검증, 최종 수동 확인 기록을 여기에 누적한다.
|
||||||
|
- 2026-06-23: Phase 1~3 구현 후 `./gradlew :app:mergeDebugResources`, `./gradlew :app:compileDebugKotlin`, `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.content.*"`, `./gradlew :app:ktlintCheck`, `git diff --check`를 실행했고 모두 성공했다.
|
||||||
|
- 2026-06-23: Reviewer gate 재검토 결과 목표/범위, 코드 품질, QA, 컨텍스트 검토는 PASS였고, security review에서 debug HTTP BODY 로그의 `Authorization` 헤더 노출 가능성이 blocking으로 지적되었다. `AppDI` primary `HttpLoggingInterceptor`에 `logging.redactHeader("Authorization")`를 추가한 뒤 `./gradlew :app:compileDebugKotlin`, `./gradlew :app:ktlintCheck`, `git diff --check`, content 단위 테스트를 재실행해 모두 성공했고, security re-review 결과 PASS 및 blocking issue 없음으로 확인했다.
|
||||||
|
- 2026-06-23: `lsp_diagnostics`는 `kotlin-ls` 미설치(`Command not found: kotlin-lsp`)로 실행하지 못했다. 대신 Gradle compile/test/ktlint와 reviewer gate로 Phase 1~3 변경을 검증했다.
|
||||||
|
- 2026-06-23: 후속 요청에 따라 content title-bar 좌측을 이미지 로고에서 하단 대화 탭과 같은 텍스트 title(`screen_content_main_title`, `콘텐츠`)로 변경했다. `./gradlew :app:mergeDebugResources`, `./gradlew :app:compileDebugKotlin`, `git diff --check` 결과 모두 성공했다. XML `lsp_diagnostics`는 XML LSP 서버 미설정으로 실행하지 못했다.
|
||||||
|
- 2026-06-23: 리뷰 지적 중 무료/포인트 섹션의 tag 강제 표시 여부를 재검토했다. `AudioRecommendationsMappers`, 기존 홈/크리에이터 채널 mapper, mapper 테스트, `ast-grep` 검색 결과 모두 tag는 섹션 소속이 아니라 item 속성(`price == 0`, `isPointAvailable == true`, `isFirstContent`, `isOriginalSeries`) 기반으로 산출하는 정책이었다. 이에 맞춰 PRD의 `무료 태그는 반드시 표시한다`, `포인트 태그는 반드시 표시한다` 문구를 섹션 membership으로 강제하지 않는 속성 기반 표시 정책으로 정정했다.
|
||||||
|
- 2026-06-23: Phase 1~3 코드 리뷰 및 검증을 재수행했다. `ContentMainFragment` 패키지 이동과 `MainV2Activity` 참조, `AudioRecommendations` API/DTO/Repository/ViewModel/mapper, 고정 title-bar/tab-bar 레이아웃, 제외 섹션 미추가 상태를 확인했고 blocking issue는 발견하지 못했다. `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.content.*"`, `./gradlew :app:mergeDebugResources`, `./gradlew :app:compileDebugKotlin`, `./gradlew :app:ktlintCheck`, `git diff --check` 결과 모두 성공했다.
|
||||||
|
|||||||
@@ -205,8 +205,8 @@ Figma `24:6807` 기준으로 무료 오디오 가로 카드 목록을 표시한
|
|||||||
#### Requirements
|
#### Requirements
|
||||||
- 섹션 타이틀은 `무료 오디오`이다.
|
- 섹션 타이틀은 `무료 오디오`이다.
|
||||||
- `freeAudios`를 가로 카드 목록으로 표시한다.
|
- `freeAudios`를 가로 카드 목록으로 표시한다.
|
||||||
- 무료 태그는 반드시 표시한다.
|
- 무료 태그는 섹션 membership으로 강제하지 않고, 공통 태그 정책에 따라 `price == 0`일 때 표시한다.
|
||||||
- 오리지널/첫 콘텐츠/성인/포인트 태그는 응답 값에 따라 함께 표시한다.
|
- 오리지널/첫 콘텐츠/성인/포인트 태그도 응답 값에 따라 함께 표시한다.
|
||||||
- item 터치 시 오디오 콘텐츠 상세로 이동한다.
|
- item 터치 시 오디오 콘텐츠 상세로 이동한다.
|
||||||
|
|
||||||
### Phase 6: 포인트 오디오
|
### Phase 6: 포인트 오디오
|
||||||
@@ -215,8 +215,8 @@ Figma `24:6813` 기준으로 포인트 오디오 가로 카드 목록을 표시
|
|||||||
#### Requirements
|
#### Requirements
|
||||||
- 섹션 타이틀은 `포인트 오디오`이다.
|
- 섹션 타이틀은 `포인트 오디오`이다.
|
||||||
- `pointAudios`를 가로 카드 목록으로 표시한다.
|
- `pointAudios`를 가로 카드 목록으로 표시한다.
|
||||||
- 포인트 태그는 반드시 표시한다.
|
- 포인트 태그는 섹션 membership으로 강제하지 않고, 공통 태그 정책에 따라 `isPointAvailable == true`일 때 표시한다.
|
||||||
- 무료/오리지널/첫 콘텐츠/성인 태그는 응답 값에 따라 함께 표시한다.
|
- 무료/오리지널/첫 콘텐츠/성인 태그도 응답 값에 따라 함께 표시한다.
|
||||||
- item 터치 시 오디오 콘텐츠 상세로 이동한다.
|
- item 터치 시 오디오 콘텐츠 상세로 이동한다.
|
||||||
|
|
||||||
### Phase 7: 최근 댓글이 많은 오디오
|
### Phase 7: 최근 댓글이 많은 오디오
|
||||||
|
|||||||
Reference in New Issue
Block a user