9.6 KiB
Phase 2 API·DTO·Repository·mapper 리뷰
1. 리뷰 정보
| 항목 | 내용 |
|---|---|
| 리뷰 대상 | Phase 2 / Task 2.1~2.8 |
| 기준 commit 또는 working tree | f600d10e8b63b6fdc812b18a874b077dfe072ca8 + 2026-07-31 working tree |
| 리뷰 일자 | 2026-07-31 |
| 리뷰어 | Codex |
| 기준 문서 | 대상 prd.md, plan-task.md, docs/agent-guides/code-style.md |
| 리뷰 상태 | 수정 검증 완료 |
2. 리뷰 목적과 범위
목적
- endpoint, optional auth header, DTO nested payload, mapper 상태 계약과 locale resource가 현재 PRD를 충족하는지 확인한다.
- Phase 9에서 교체된 최근 소식 계약을 Phase 2의 과거 기록과 혼동하지 않고 현재 계약 기준으로 판정한다.
포함 범위
HomeFollowingApi.kt,HomeFollowingModels.kt,HomeFollowingRepository.ktHomeFollowingAuthHeader.kt,HomeFollowingUiState.kt,HomeFollowingUiModels.kt,HomeFollowingMappers.ktHomeFollowingAuthHeaderTest,HomeFollowingMapperTest,HomeFollowingNewsAdapterTest, 관련 string resource와 DI
제외 범위
- Fragment 표시·터치 이동과 서버
permitAll실제 설정.
3. 판정 기준
- PRD endpoint/response contract, Gson/Kotlin 관례, mapper의 login/empty/content 분기와
docs/sample/sample-review.md심각도 기준을 적용했다.
4. 검토한 근거
문서와 코드
HomeFollowingApi.kt:8-12: query 없는GET /api/v2/home/following, nullable headerHomeFollowingModels.kt:8-111: DTO와 nested payloadHomeFollowingMappers.kt:18-158: LoginRequired/Empty/Content, matching payload 필터, locale labelHomeFollowingNewsAdapter.kt:155-171: UI model label을 읽지 않고FollowingNewsType.toFeedContentCategory()로 표시 label을 결정AppDI.kt: API/Repository 등록
실행 환경
OS: Darwin 25.0.0 x86_64
JDK: OpenJDK 17.0.15
Gradle wrapper: 8.14.3
실행한 검증
| 명령 | 결과 | 핵심 증거 |
|---|---|---|
./gradlew --no-daemon :app:testDebugUnitTest --tests "...HomeFollowingAuthHeaderTest" --tests "...HomeFollowingMapperTest" --tests "...HomeFollowingViewModelTest" |
성공 | 전체 20개 중 Phase 2 대상 13개(auth 3, mapper 10) 실패 0 |
./gradlew --no-daemon :app:mergeDebugResources :app:compileDebugKotlin :app:ktlintCheck |
성공 | resource/compile/style PASS |
| 2026-07-31 Phase 1~13 통합 focused 회귀 | 성공 | 15개 suite, 113개 test, failures/errors 0 |
git diff --check |
성공 | whitespace 오류 없음 |
5. 발견 사항 요약
| ID | 심각도 | 상태 | 제목 | 소유 Task | 후속 goal |
|---|---|---|---|---|---|
REV-P2-001 |
Low | 수정 완료 | 후속 UI·오류 처리 변경 후 미사용 팔로잉 string resource 3개가 남음 | Task 2.7 | P2-R1 완료 |
REV-P2-002 |
Low | 수정 완료 | Feed category 전환 후 미사용 Content.labelResId와 mapper가 남음 |
Task 2.8 | P2-R2 완료 |
6. 발견 사항 상세
- Phase 2 기록의
rank == null필터 문구는 Phase 9 nested payload 계약에서rank: Int로 확정된 현재 계약에 의해 대체되었다. 현재 DTO·fixture·mapper가 동일 계약을 사용하므로 결함이 아닌 과거 기록으로 판정했다.
REV-P2-001 — 후속 UI·오류 처리 변경 후 미사용 팔로잉 string resource가 남음
- 심각도: Low
- 상태: 수정 완료
- 관련 요구사항: Task 2.4 string resource, Phase 6 팔로잉 크리에이터 header 제거, Task 3.2 공통 오류 Toast 패턴
- 소유 Task: Task 2.7
관찰 내용
screen_home_following_creators_title, screen_home_following_on_air_title, screen_home_following_error는 values, values-en, values-ja에 모두 선언되어 있지만 production/test/layout에서 참조되지 않는다. On Air 섹션과 상태는 screen_home_following_on_air를 사용하고, API 오류는 common_error_unknown Toast를 사용한다.
근거
- resource:
app/src/main/res/values/strings.xml:311-322,values-en/strings.xml:312-323,values-ja/strings.xml:312-323 - code:
HomeMainFragment.kt:627-640,HomeFollowingViewModel.kt:73-75 - 검색: 각 대상 key의
R.string/@stringproduction/test 참조 0건
재현 또는 검증 절차
- 3개 locale string file에서 위 key 선언을 확인한다.
rg로app/src/main,app/src/test의 resource 참조를 검색한다.- 실제 결과는 선언 외 참조 0건이다.
영향
런타임 오류는 없지만 번역·유지보수 대상을 불필요하게 늘리고, 후속 작업자가 현재 UI에 필요한 계약으로 오인할 수 있다.
권장 조치
3개 locale에서 위 3개 미사용 key만 제거하고, 사용 중인 screen_home_following_on_air와 나머지 팔로잉 문자열은 유지한다.
판정 기록
- 2026-07-30 — 3개 locale 선언과 production/test/layout 참조를 대조해 확정.
- 2026-07-30 — 코드는 수정하지 않고 Phase 2 Task 2.7 /
P2-R1로 전환.
REV-P2-002 — Feed category 전환 후 미사용 label UI model이 남음
- 심각도: Low
- 상태: 수정 완료
- 관련 요구사항: Task 2.6 최근 소식 UI model/mapper, Task 6.4 Feed 위젯 재사용
- 소유 Task: Task 2.8
관찰 내용
HomeFollowingNewsUiItem.Content.labelResId는 mapper가 값을 대입하고 test fixture가 검증하지만 production adapter는 이 필드를 읽지 않는다. 실제 label은 content.type.toFeedContentCategory()과 FeedContentCategory.labelResId에서 결정된다.
근거
- UI model:
HomeFollowingUiModels.kt:74-86 - mapper:
HomeFollowingMappers.kt:111-128,151-158 - runtime:
HomeFollowingNewsAdapter.kt:155-171,FeedContentCategory.kt:6-15 - 검색: 팔로잉
Content.labelResId의 production read 0건, test/fixture만 참조
재현 또는 검증 절차
rg -n "labelResId|toLabelResId"결과에서 팔로잉 최근 소식 model·mapper·test 참조를 확인한다.HomeFollowingNewsAdapter.ContentViewHolder.bind()의 category/label 결정 경로를 추적한다.- 실제 결과는
labelResId를 읽지 않고FeedContentCategory.Audio/Photo를 사용한다.
영향
런타임 표시 오류는 없지만 동일 label 계약이 UI model mapper와 Feed category에 이중으로 남아 후속 문구·category 변경 시 test와 production이 엇갈릴 수 있다.
권장 조치
미사용 Content.labelResId와 FollowingNewsType.toLabelResId()만 제거하고, 실제 표시 경로인 FeedContentCategory.Audio/Photo와 locale string 회귀를 유지한다.
판정 기록
- 2026-07-31 — production/test 참조와 Feed binding 경로를 대조해 확정.
- 2026-07-31 — production은 수정하지 않고 Phase 2 Task 2.8 /
P2-R2로 전환. - 2026-07-31 — Task 2.8에서 미사용 UI model 필드와 mapper를 제거하고 Feed category label 회귀 검증을 완료.
7. 확정 항목의 plan·goal 전환
plan-task.mdPhase 2에 Task 2.7 /P2-R1을 추가했다.- objective:
[P2-R1]의 REV-P2-001을 최소 resource 삭제로 정리하고 팔로잉 resource 회귀를 방지한다. plan-task.mdPhase 2에 Task 2.8 /P2-R2를 추가했다.- objective:
[P2-R2]의 REV-P2-002를 미사용 UI model/mapper 제거로 정리하고 Feed category label 회귀를 방지한다.
8. 리뷰 종료 판정
| 판정 항목 | 결과 | 근거 |
|---|---|---|
| 리뷰 범위 전체 확인 | 충족 | API→Repository→mapper와 resource 확인 |
| 후보 항목 판정 완료 | 충족 | 과거 rank 문구는 오탐, REV-P2-001~002 판정 완료 |
| 확정 항목 plan 반영 | 충족 | Task 2.7 / P2-R1, Task 2.8 / P2-R2 추가 |
| 검증 명령과 결과 기록 | 충족 | focused test 및 빌드 품질 검증 PASS |
최종 결론: 확정 발견 사항 모두 수정 완료
남은 항목: 없음
9. 수정 후 검증 기록
- 2026-07-31:
REV-P2-001보완으로screen_home_following_creators_title,screen_home_following_on_air_title,screen_home_following_error를 3개 locale에서 제거했다.rg로 production/test/layout 참조 0건을 확인했고, 사용 중인screen_home_following_on_air, empty, ranking, section title 문자열은 유지했다../gradlew --no-daemon :app:mergeDebugResources :app:compileDebugKotlin,./gradlew --no-daemon --rerun-tasks :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.HomeFollowingMapperTest",./gradlew --no-daemon :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.*Following*",./gradlew --no-daemon :app:ktlintCheck,git diff --checkPASS. - 2026-07-31 재점검: Phase 1~13 focused 회귀 15개 suite/113개 test, resource merge, Kotlin compile, ktlint는 PASS했다.
REV-P2-002는 정적 사용처 대조로 확정했고, 이번 리뷰에서 production/test 코드는 수정하지 않았다. - 2026-07-31:
REV-P2-002보완으로HomeFollowingNewsUiItem.Content.labelResId, mapper 대입,FollowingNewsType.toLabelResId()를 제거했다.PHOTO_CONTENT표시는 실제FeedContentCategory.Photo와 locale string을 쓰는 adapter 회귀로 유지했다. mapper/news adapter focused test, 팔로잉 전체 회귀, resource merge, Kotlin compile, ktlint PASS. - 2026-07-31 최종 검증: DTO·Repository·mapper 회귀를 포함한 통합 20개 suite·306개 test와 resource merge, Kotlin compile, ktlint가 PASS했다. 추가 확정 발견 사항 없음.
- 2026-07-31 이번 리뷰 재검증: endpoint·optional auth·nested payload·mapper·Feed category label 경로를 다시 추적했다. 통합 16개 suite·120개 test, resource merge, Kotlin compile, ktlint, staged/unstaged diff 검사가 PASS했으며 추가 확정 발견 사항은 없다.