14 KiB
Phase 4 팔로잉 UI surface와 routing 리뷰
1. 리뷰 정보
| 항목 | 내용 |
|---|---|
| 리뷰 대상 | Phase 4 / Task 4.1~4.9 |
| 기준 commit 또는 working tree | f600d10e8b63b6fdc812b18a874b077dfe072ca8 + 2026-07-31 working tree |
| 리뷰 일자 | 2026-07-31 |
| 리뷰어 | Codex |
| 기준 문서 | 대상 prd.md, plan-task.md, 후속 pull-refresh/access 문서 |
| 리뷰 상태 | 수정 검증 완료 |
2. 리뷰 목적과 범위
목적
- 팔로잉 surface 전환, section visibility, adapter click 연결과 상태 observer가 요구사항을 충족하는지 확인한다.
- 후속 pull refresh와 공통 액션 변경을 포함한 현재 실행 경로에서 회귀가 없는지 확인한다.
포함 범위
HomeMainFragment.kt,fragment_v2_main_home.xml- 팔로잉 adapter 5개,
HomeFollowingFragmentSourceTest,HomeMainFragmentLoginGuardSourceTest
제외 범위
- chevron 실제 목적지와 로그인 유도 UI 디자인.
3. 판정 기준
- item 상세 이동 누락은 확정 기능 요구사항 위반으로 High, 제한된 로그인 만료/refresh 조건의 복구 문제는 Medium으로 판정했다.
4. 검토한 근거
문서와 코드
- PRD
On Airitem 터치 요구사항과이달의 스케줄type/target 이동 요구사항 HomeMainFragment.kt:115-122,397-419,657-687HomeFollowingLiveAdapter.kt:49-54,HomeFollowingScheduleAdapter.kt:53-67
실행 환경
OS: Darwin 25.0.0 x86_64
JDK: OpenJDK 17.0.15
Gradle wrapper: 8.14.3
연결 기기: 없음
실행한 검증
| 명령 | 결과 | 핵심 증거 |
|---|---|---|
./gradlew --no-daemon :app:testDebugUnitTest --tests "...HomeFollowingFragmentSourceTest" --tests "...HomeMainFragmentLoginGuardSourceTest" |
성공 | source test 모두 PASS |
| callback/observer 본문 수동 추적 | 문제 확인 | live/schedule callback은 Unit, LoginRequired는 refresh 종료 호출 없음 |
profile helper·Coil 2.7.0 source·저장소 dispose() 사용례 대조 |
문제 확인 | blank 분기가 drawable만 비우고 View 요청을 해제하지 않음 |
HomeFollowingFragmentSourceTest 이름과 테스트명 가이드 대조 |
문제 확인 | 완전한 영문 문장형 테스트명 11개 확인 |
5. 발견 사항 요약
| ID | 심각도 | 상태 | 제목 | 소유 Task | 후속 goal |
|---|---|---|---|---|---|
REV-P4-001 |
High | 수정 완료 | On Air와 스케줄 item 터치가 no-op | Task 4.6 | P4-R1 완료 |
REV-P4-002 |
Medium | 수정 완료 | LoginRequired 응답에서 pull refresh가 종료되지 않음 | Task 4.7 | P4-R2 완료 |
REV-P4-003 |
Medium | 수정 완료 | blank 프로필 이미지 바인딩이 이전 Coil 요청을 해제하지 않음 | Task 4.8 | P4-R3 완료 |
REV-P4-004 |
Low | 수정 완료 | 공용 source test의 영문 문장형 테스트명이 한글 테스트명 규칙과 불일치 | Task 4.9 | P4-R4 완료 |
6. 발견 사항 상세
REV-P4-001 — On Air와 스케줄 item 터치가 no-op
- 심각도: High
- 상태: 수정 완료
- 관련 요구사항: PRD On Air
item 터치 시 해당 live room/detail, 스케줄type/targetId 목적지 - 소유 Task: Task 4.6
관찰 내용
adapter click listener는 Fragment callback까지 전달되지만 onFollowingLiveClick()과 onFollowingScheduleClick() 본문이 Unit이라 아무 이동도 발생하지 않는다.
근거
- 코드:
HomeMainFragment.kt:119-122,669-671 - 테스트: source test는 callback 존재만 확인하고 실제 액션을 요구하지 않음
- 문서: Task 4.5 결과도 route 없는 skeleton임을 기록
재현 또는 검증 절차
- On Air 또는 schedule item을 bind한다.
- item root를 터치하면 adapter callback이 Fragment로 전달된다.
- 실제 결과는
Unit; 요구 결과는 기존 공통 Live/Content/Community Action 이동이다.
영향
팔로잉 핵심 섹션 두 곳에서 사용자가 상세 콘텐츠로 진입할 수 없다.
권장 조치
On Air liveId는 LiveActionCoordinator, schedule type/targetId는 기존 최근 활동 route와 공통 액션을 재사용한다.
판정 기록
- 2026-07-30 — PRD와 실제 callback 본문을 대조해 확정.
- 2026-07-30 — Task 4.6에서 공통 Live/Content/Community Action 연결과 회귀 검증을 완료.
REV-P4-002 — LoginRequired 응답에서 pull refresh가 종료되지 않음
- 심각도: Medium
- 상태: 수정 완료
- 관련 요구사항: 로그인 필요 상태 분기, 후속 홈 pull refresh 완료 정책
- 소유 Task: Task 4.7
관찰 내용
Content와 Empty는 finishHomePullRefresh()를 호출하지만 LoginRequired는 section만 숨긴다. 유효하지 않은 token 등으로 refresh API가 LoginRequired를 반환하면 SwipeRefresh spinner와 내부 refresh 추적 상태가 남는다.
근거
- 코드:
HomeMainFragment.kt:397-419 - 비교 경로:
Content406,Empty411,LoginRequired413 - 테스트: LoginRequired의 section 숨김만 검사하고 refresh 종료는 검사하지 않음
재현 또는 검증 절차
- 팔로잉 탭에서 pull refresh를 시작한다.
- API가
isLoginRequired=true를 반환한다. - 실제 결과는
bindHomeFollowingEmpty(false)만 실행된다. - 요구 결과는 section 숨김과 refresh 종료다.
영향
로그인 만료·서버 세션 불일치 조건에서 refresh UI가 계속 동작 중인 것처럼 남는다.
권장 조치
LoginRequired 분기에서 팔로잉 refresh 종료를 보장하는 최소 분기와 회귀 테스트를 추가한다.
판정 기록
- 2026-07-30 — observer 분기와 refresh 상태 함수를 추적해 확정.
- 2026-07-30 — Task 4.7에서 LoginRequired refresh 종료 분기와 회귀 검증을 완료.
REV-P4-003 — blank 프로필 이미지 바인딩이 이전 Coil 요청을 해제하지 않음
- 심각도: Medium
- 상태: 수정 완료
- 관련 요구사항: PRD 팔로잉 크리에이터의 blank/실패 profile fallback, Phase 4 adapter image binding
- 소유 Task: Task 4.8
관찰 내용
팔로잉 creator/live/chat/schedule와 community profile이 재사용하는 loadHomeCreatorProfileImage()는 URL이 blank이면 drawable만 비운다. Coil 2.7.0은 View에 연결된 기존 요청을 별도로 유지하므로, 이전 item의 요청이 아직 진행 중이면 완료 시점에 재사용된 View에 이전 이미지가 다시 표시될 수 있다.
근거
- 코드:
HomeCreatorProfileImageLoader.kt:10-17의 blank 분기에dispose()가 없음 - 호출부:
HomeFollowingCreatorAdapter,HomeFollowingLiveAdapter,HomeFollowingChatAdapter,HomeFollowingScheduleAdapter,HomeFollowingNewsAdapter - 의존성:
app/build.gradle의 Coil2.7.0; 로컬 Coil source의ViewTargetRequestManager.dispose()는 현재 요청을 취소·분리함 - 저장소 정상 사용례:
HomePopularCommunityAdapter.kt:67-70은 blank image에서imageView.dispose()후 drawable을 비움
재현 또는 검증 절차
- 재사용 가능한 profile
ImageView에 완료 전 Coil 요청 A를 연결한다. - 같은 ViewHolder에 blank profile URL item B를 바인딩한다.
- 현재 구현은 drawable만 비우고 요청 A를 유지한다.
- 요청 A가 뒤늦게 완료되면 item B에 A의 프로필이 표시될 수 있다. 요구 결과는 blank 바인딩 시 요청 A를 해제하고 빈 상태를 유지하는 것이다.
영향
빠른 스크롤이나 느린 이미지 응답 조건에서 creator/live/chat/schedule/news item에 다른 사용자의 프로필 이미지가 노출될 수 있다.
권장 조치
공통 loadHomeCreatorProfileImage()의 blank 분기에서 Coil 요청을 해제한 뒤 drawable을 비운다. 각 adapter를 중복 수정하지 않고 공통 helper 한 곳을 수정하며, Robolectric에서 View 요청 연결 해제를 검증한다.
판정 기록
- 2026-07-30 — 공통 helper, 모든 팔로잉 호출부, Coil 2.7.0 요청 manager와 저장소 내
dispose()사용례를 대조해 확정. - 2026-07-30 — 구현 전 Phase 4 Task 4.8 /
P4-R3로 전환. - 2026-07-30 — Task 4.8에서
loadHomeCreatorProfileImage()blank 분기에dispose()를 추가하고, Robolectric focused test와 팔로잉 회귀 검증을 완료.
REV-P4-004 — 공용 source test의 영문 문장형 테스트명이 규칙과 불일치함
- 심각도: Low
- 상태: 수정 완료
- 관련 요구사항:
docs/agent-guides/build-test-style.md,docs/agent-guides/code-style.md의 신규 Kotlin 테스트명 규칙 - 소유 Task: 신규 Task 4.9
관찰 내용
Phase 4에서 생성되고 후속 Phase가 함께 확장한 HomeFollowingFragmentSourceTest에 완전한 영문 문장형 backtick 테스트명 11개가 남아 있다. 테스트 작성 전부터 가이드가 신규 Kotlin 테스트명을 한글 문장으로 작성하도록 규정했지만 별도 한글 설명도 없다.
근거
- 테스트:
HomeFollowingFragmentSourceTest.kt의home layout exposes...부터following recent news adapter binds...까지 영문 문장형 테스트명 11개 - 가이드:
docs/agent-guides/build-test-style.md와docs/agent-guides/code-style.md의 신규 테스트명 한글 규칙 - 이력: 테스트명 규칙은
2026-05-28, 대상 테스트는2026-06-25이후 추가됨
재현 또는 검증 절차
rg -n 'fun `[A-Za-z]' HomeFollowingFragmentSourceTest.kt로 대상 이름을 확인한다.- 클래스의 완전한 영문 문장형 이름 11개와 가이드의 한글 문장 규칙을 대조한다.
- 테스트 동작은 통과하지만 명명 규칙 불일치가 재현된다.
영향
runtime 동작에는 영향이 없지만 동일 기능 테스트의 언어 관례가 섞이고, 완료된 Phase가 저장소 테스트 규칙을 충족한다는 판정과 어긋난다.
권장 조치
assertion과 production 코드는 바꾸지 않고 해당 11개 테스트명만 검증 의도가 드러나는 한글 문장으로 변경한다.
판정 기록
- 2026-07-31 — 테스트 생성 이력, 현재 이름과 가이드를 대조해 확정하고 Phase 4 Task 4.9 /
P4-R4로 전환. - 2026-07-31 — Task 4.9에서 대상 테스트명 11개를 한글 문장으로 변경하고 focused/팔로잉 회귀 검증을 완료.
7. 확정 항목의 plan·goal 전환
- Phase 4에 Task 4.6 /
P4-R1, Task 4.7 /P4-R2를 추가해 완료했다. - 추가 재점검에서 Task 4.8 /
P4-R3를 추가했으며 구현·검증을 완료했다. - 최종 재점검에서 Task 4.9 /
P4-R4를 추가했으며 테스트명 정리를 완료했다.
8. 리뷰 종료 판정
| 판정 항목 | 결과 | 근거 |
|---|---|---|
| 리뷰 범위 전체 확인 | 충족 | UI→adapter→callback→공통 액션 경로 추적 |
| 후보 항목 판정 완료 | 충족 | REV-P4-001~004 판정 완료 |
| 확정 항목 plan 반영 | 충족 | Task 4.6~4.9 추가 |
| 검증 명령과 결과 기록 | 충족 | focused/source test PASS와 수동 코드 추적 |
최종 결론: 확정 발견 사항 모두 수정 완료
남은 항목: 없음
9. 수정 후 검증 기록
- 2026-07-30:
REV-P4-001보완으로 팔로잉 On Air item은liveActionCoordinator.enterLiveRoom(item.liveId), 스케줄 item은CreatorActivityType별 기존 Live/Content/Community Action을 호출하도록 연결했다.targetId <= 0L은 공통 action 호출 전 return하며 직접Intent또는 legacy extra 조립은 추가하지 않았다. - 2026-07-30:
REV-P4-002보완으로HomeFollowingUiState.LoginRequired분기에서 section 숨김 후finishHomePullRefresh(HOME_TAB_FOLLOWING)을 호출하도록 변경했다. focused source test, 팔로잉 전체 회귀,v2.live.action.*,v2.content.action.*,v2.community.action.*,:app:compileDebugKotlin,:app:ktlintCheck,git diff --checkPASS. - 2026-07-30:
REV-P4-003보완으로HomeCreatorProfileImageLoader.loadHomeCreatorProfileImage()의 blank URL 분기에서 기존 Coil 요청을dispose()로 해제한 뒤 drawable을 비우도록 변경했다. 구현 전HomeCreatorProfileImageLoaderTestRED, 구현 후 focused GREEN, 팔로잉 전체 회귀와 신규 프로필 테스트,:app:mergeDebugResources,:app:compileDebugKotlin,:app:ktlintCheck,git diff --checkPASS. - 2026-07-31 재점검: Fragment/source·공통 action·프로필 loader를 포함한 Phase 1~13 focused 회귀 113개 test, resource merge, Kotlin compile, ktlint PASS. 추가 확정 발견 사항 없음.
- 2026-07-31 최종 재점검:
HomeFollowingFragmentSourceTest의 영문 문장형 테스트명 11개를REV-P4-004로 확정하고, production/test 동작을 변경하기 전에 Task 4.9 /P4-R4로 전환했다. - 2026-07-31 최종 검증: 통합 20개 suite·306개 test와 resource merge, Kotlin compile, ktlint가 PASS했다. 자동 검증 성공과 별개로 이름 규칙 위반
REV-P4-004는 Task 4.9의 수정 항목으로 유지했다. - 2026-07-31:
REV-P4-004보완으로HomeFollowingFragmentSourceTest의 영문 문장형 테스트명 11개를 한글 문장으로 변경했다../gradlew --no-daemon :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.HomeFollowingFragmentSourceTest" --tests "kr.co.vividnext.sodalive.v2.main.home.HomeFollowingNewsAdapterTest", 팔로잉 전체 회귀,:app:compileDebugKotlin,:app:ktlintCheckPASS. - 2026-07-31 이번 리뷰 재검증: surface 전환, section 상태, live/chat/schedule/news 공통 액션과 blank profile 요청 해제 경로를 다시 추적했다. 통합 16개 suite·120개 test, resource merge, Kotlin compile, ktlint가 PASS해
REV-P4-001~004수정 완료 판정을 유지한다.