Files
sodalive-android/docs/20260625_메인_홈_팔로잉_탭/reviews/phase2-following-data-mapper-review.md

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.kt
  • HomeFollowingAuthHeader.kt, HomeFollowingUiState.kt, HomeFollowingUiModels.kt, HomeFollowingMappers.kt
  • HomeFollowingAuthHeaderTest, 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 header
  • HomeFollowingModels.kt:8-111: DTO와 nested payload
  • HomeFollowingMappers.kt:18-158: LoginRequired/Empty/Content, matching payload 필터, locale label
  • HomeFollowingNewsAdapter.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_errorvalues, 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 / @string production/test 참조 0건

재현 또는 검증 절차

  1. 3개 locale string file에서 위 key 선언을 확인한다.
  2. rgapp/src/main, app/src/test의 resource 참조를 검색한다.
  3. 실제 결과는 선언 외 참조 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만 참조

재현 또는 검증 절차

  1. rg -n "labelResId|toLabelResId" 결과에서 팔로잉 최근 소식 model·mapper·test 참조를 확인한다.
  2. HomeFollowingNewsAdapter.ContentViewHolder.bind()의 category/label 결정 경로를 추적한다.
  3. 실제 결과는 labelResId를 읽지 않고 FeedContentCategory.Audio/Photo를 사용한다.

영향

런타임 표시 오류는 없지만 동일 label 계약이 UI model mapper와 Feed category에 이중으로 남아 후속 문구·category 변경 시 test와 production이 엇갈릴 수 있다.

권장 조치

미사용 Content.labelResIdFollowingNewsType.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.md Phase 2에 Task 2.7 / P2-R1을 추가했다.
  • objective: [P2-R1]의 REV-P2-001을 최소 resource 삭제로 정리하고 팔로잉 resource 회귀를 방지한다.
  • plan-task.md Phase 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 --check PASS.
  • 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했으며 추가 확정 발견 사항은 없다.