# Phase 3 리뷰 보고서 ## 1. 리뷰 정보 | 항목 | 내용 | |---|---| | 리뷰 대상 | Phase 3 / Task 3.1~3.5 | | 기준 commit 또는 working tree | 구현 commit `4f348c36`, 보정 commit `6da2378b`, 현재 `5123494e` 기준 working tree | | 리뷰 일자 | 2026-07-31 | | 리뷰어 | Codex | | 기준 문서 | PRD Feature A~C, `plan-task.md` Phase 3 | | 리뷰 상태 | 보완 완료 | ## 2. 리뷰 목적과 범위 - 최근 7일 UTC half-open window, 후원·팬Talk 집계, DB-side 점수·부스트, 후보·정렬·limit 구현을 확인한다. - 완료 처리된 Task의 테스트 증거가 명시된 경계 조건을 직접 고정하는지 확인한다. ## 3. 판정 기준 - 구현 결함과 완료 증거 누락을 구분한다. 이번 발견은 현재 코드 동작 위반이 아니라 회귀 테스트 근거 누락으로 Low다. ## 4. 검토한 근거 - 코드: `RecommendationSnapshotRefreshService.kt`, `RecommendationSnapshotWindowPolicy.kt`, `DefaultHomeRecommendationQueryRepository.kt` - 테스트: `RecommendationSnapshotRefreshServiceTest`, `DefaultHomeRecommendationQueryRepositoryTest`, `RecommendationSnapshotPersistenceAdapterTest` - 이력: `git show 4f348c36`, `git show 6da2378b` - 사용자 지시에 따라 Gradle compile/test는 실행하지 않았다. ## 5. 발견 사항 요약 | ID | 심각도 | 상태 | 제목 | 소유 Task | 후속 goal | |---|---|---|---|---|---| | `REV-P3-001` | Low | 보완 완료 | Task 3.5의 일부 후보·상위 16개·동점 정렬 완료 증거가 직접 테스트로 고정되지 않았다 | Task R3.1 | `P3-R1` | ## 6. 발견 사항 상세 ### REV-P3-001 — Task 3.5의 일부 완료 증거가 직접 테스트로 고정되지 않았다 - **심각도:** Low - **상태:** 확정 - **관련 요구사항:** Feature A·C Edge Cases, Task 3.5 - **소유 Task:** Task R3.1 **관찰 내용** 현재 테스트는 donation 종류·상태·half-open 경계, distinct 후원 수, 점수/부스트, 데뷔 이력 없음과 `limit = 1` 점수 우선순위를 검증한다. 그러나 Task 3.5에 명시된 다음 계약의 직접 테스트는 확인되지 않았다. - 실제 데뷔 이력은 있으나 후원·팬Talk가 모두 0인 후보 제외 - 미래 데뷔 이력만 있는 후보와 비활성 크리에이터 제외 - 17개 이상 후보의 상위 16개 제한 - `CHEER_CREATOR` 저장 row의 동점 `randomTieBreaker` 오름차순 조회 코드는 해당 조건을 구현하고 있어 현재 런타임 결함으로 판정하지 않는다. **영향** 후속 native SQL 수정에서 후보 조건·저장 수·동점 순서가 회귀해도 focused test가 이를 직접 잡지 못할 수 있다. **권장 조치** 프로덕션 코드를 선제 변경하지 않고 누락된 경계 테스트를 먼저 추가하며, 실제 실패가 드러나는 조건만 최소 수정한다. **판정 기록** - 2026-07-31 — 테스트명·fixture·assertion과 Task 3.5 체크리스트를 대조해 확정했다. - 2026-07-31 — 후보 제외, 상위 16개 제한, `CHEER_CREATOR` 동점 `randomTieBreaker` 오름차순 조회 테스트를 추가했다. focused repository/persistence test는 `BUILD SUCCESSFUL`, 관련 `git diff --check`는 출력 없음으로 보완 완료했다. ## 7. 확정 항목의 plan·goal 전환 - `plan-task.md` Phase 3에 Task R3.1 / `P3-R1`을 추가했다. ## 8. 리뷰 종료 판정 | 판정 항목 | 결과 | 근거 | |---|---|---| | 리뷰 범위 전체 확인 | 충족 | query·window·정책·테스트 대조 완료 | | 후보 항목 판정 완료 | 충족 | `REV-P3-001` 확정 | | 확정 항목 plan 반영 | 충족 | Task R3.1 | | 검증 명령과 결과 기록 | 충족 | 정적 검색·구현 이력 확인 | **최종 결론:** 보완 완료 **남은 항목:** 없음 --- ## 9. 2차 리뷰 기록 — 2026-07-31 ### 리뷰 정보·범위 - **기준:** `5123494e` 기준 미커밋 working tree, PRD Feature A~C, `plan-task.md` Phase 3, 선행 홈 추천 PRD Feature E. - **목적:** 최종 SQL의 7일 window·집계·점수·데뷔일·후보 조건을 현재 요구사항과 다시 대조한다. - **검증:** `findCheerCreatorSnapshots(...)` SQL과 관련 repository 테스트, `075ca88f` 종료 라이브 데뷔 판정 보강 이력을 정적 추적했다. Gradle compile/test는 실행하지 않았다. ### 발견 사항 | ID | 심각도 | 상태 | 제목 | 소유 Task | 후속 goal | |---|---|---|---|---|---| | `REV-P3-002` | High | 보완 완료 | 종료된 라이브가 `CHEER_CREATOR` 데뷔 이력에서 제외된다 | Task R3.2 | `P3-R2` | #### REV-P3-002 — 종료된 라이브가 `CHEER_CREATOR` 데뷔 이력에서 제외된다 - **심각도:** High - **상태:** 보완 완료 - **관련 요구사항:** PRD Feature C, Task 3.4 - **근거:** 현재 PRD는 데뷔일을 선행 홈 추천 PRD와 동일하게 계산하도록 한다(`prd.md:102-109`). 선행 PRD는 `channel_name`이 있는 종료 라이브도 데뷔 이력으로 인정하고 `live_room.is_active`를 조건으로 사용하지 않도록 확정한다(`docs/20260529_메인_홈_추천_API/prd.md:157-159`). 그러나 `DefaultHomeRecommendationQueryRepository.kt:589-594`의 `CHEER_CREATOR` 데뷔 CTE는 `lr.is_active = true`를 요구한다. 관련 스냅샷 테스트는 빈 채널명과 활성 라이브만 검증하고 종료 라이브 경계를 고정하지 않는다. - **재현 경로:** 활성 콘텐츠는 없고 채널명이 있는 `is_active = false` 종료 라이브와 최근 7일 응원 활동만 있는 활성 크리에이터를 준비한다. 현재 SQL에서는 `creator_debut` row가 생성되지 않아 후보에서 제외된다. - **영향:** 정상적으로 라이브를 종료한 크리에이터가 응원 점수가 있어도 스냅샷 후보에서 누락되고, 더 늦은 활성 콘텐츠가 있으면 실제 최초 데뷔일보다 높은 신규 부스트를 받을 수 있다. - **권장 조치:** `CHEER_CREATOR` CTE의 라이브 branch에서 `lr.is_active = true`만 제거하고, 종료 라이브·빈 채널명 경계를 repository 회귀 테스트로 고정한다. - **판정 기록:** 2026-07-31 — 요구사항·SQL·선행 보강 commit·테스트 누락을 정적 대조해 확정했다. - **보완 기록:** 2026-07-31 — 채널명이 있는 종료 라이브와 최근 7일 응원 활동만 있는 크리에이터가 `CHEER_CREATOR` 후보에 포함되는 RED 테스트를 추가했고, 빈 `channel_name` 종료 라이브 제외 경계를 함께 고정했다. RED 확인에서 `shouldIncludeEndedLiveWithChannelNameAsCheerCreatorDebut`가 `AssertionFailedError`로 실패했고, `findCheerCreatorSnapshots(...)` 라이브 branch의 `lr.is_active = true`만 제거한 뒤 repository focused test가 `BUILD SUCCESSFUL`로 통과했다. `./gradlew ktlintCheck`도 `BUILD SUCCESSFUL`로 통과했으며, `git diff --check`는 출력 없이 통과했다. ### plan·goal 전환과 종료 판정 - `plan-task.md` Phase 3에 Task R3.2 / `P3-R2`를 추가했다. - **최종 결론:** 보완 완료. - **남은 항목:** 없음. --- ## 10. 3차 리뷰 기록 — 2026-07-31 - **리뷰 대상:** Phase 3 / Task 3.1~3.5·Task R3.1~R3.2, `5123494e` 기준 미커밋 working tree. - **검토 근거:** `RecommendationSnapshotWindowPolicy.kt:7-34`, `DefaultHomeRecommendationQueryRepository.kt:573-647,1185-1227`, `RecommendationSnapshotRefreshService.kt:91-127`, 산식·half-open 경계·후원 distinct·후보 상한·종료 라이브·동점 정렬 repository/persistence 테스트. - **검증 방법:** 최근 7일 UTC half-open window, `CHANNEL_DONATION`·`DONATION`, `UseCanCalculate.useCan` distinct 후원 수, active 팬Talk, DB-side 점수·부스트, 미래/데뷔 없음/비활성 후보 제외, 종료 라이브 데뷔 이력, 점수순 상위 16개와 저장 정렬을 정적으로 추적했다. Gradle compile/test는 실행하지 않았다. - **발견 사항:** 확정 발견 사항 없음. - **plan·goal 전환:** 전환 항목 없음. - **최종 결론:** 확정 발견 사항 없음. - **남은 항목:** 없음.