feat(home): 팔로잉 탭 최근 소식 정책을 보강한다

This commit is contained in:
2026-07-30 19:51:30 +09:00
parent e6f56f24fe
commit f1c2e6c50b
21 changed files with 2145 additions and 19 deletions

View File

@@ -0,0 +1,185 @@
# Phase 6 코드 리뷰 보고서
## 1. 리뷰 정보
| 항목 | 내용 |
|---|---|
| 리뷰 대상 | Phase 6 / Task 6.1~6.2 |
| 기준 commit 또는 working tree | `e6f56f24` + 2026-07-30 working tree |
| 리뷰 일자 | 2026-07-30 |
| 리뷰어 | Codex |
| 기준 문서 | `prd.md`, `plan-task.md`, DDL, 기존 검증 기록 |
| 리뷰 상태 | 판정 완료 |
## 2. 목적과 범위
- PRD, 구현 계획, DDL, 실제 공개 DTO의 현재 계약과 Phase별 기존 검증 기록을 정적으로 대조했다.
- 현재 compile/test 통과 상태는 사용자 설명과 `plan-task.md` 기존 기록을 근거로 삼았으며 직접 재실행하지 않았다.
## 3. 검토 근거
- PRD와 계획의 endpoint, 섹션 limit, nested 최근 소식 필드, 무료 커뮤니티 정책, DDL 유니크 키가 현재 코드와 일치한다.
- `plan-task.md`에는 Phase 1~7의 focused/회귀/lint 성공 기록과 실패 후 보완 이력이 누적되어 있다.
- 이번 리뷰에서 확정된 후속 결함은 기존 완료 상태를 되돌리지 않고 소유 Phase의 신규 Task로 추가했다.
- `./gradlew tasks --all` 최초 실행은 sandbox의 사용자 Gradle cache 접근 제한으로 실패했고, 승인된 권한으로 재실행한 결과
`BUILD SUCCESSFUL`이었다. task 목록만 확인했으며 컴파일과 테스트는 실행하지 않았다.
## 4. 발견 사항
확정 발견 사항 없음.
## 5. plan·goal 전환
전환 항목 없음. Phase 3과 Phase 7의 코드 발견 사항은 각 Phase 보고서와 Task에 귀속했다.
## 6. 리뷰 종료 판정
| 판정 항목 | 결과 | 근거 |
|---|---|---|
| 리뷰 범위 전체 확인 | 충족 | PRD/plan/DDL/code/기존 기록 정적 대조 |
| 후보 항목 판정 완료 | 충족 | Phase 6 자체 후보 없음 |
| 확정 항목 plan 반영 | 해당 없음 | 다른 Phase 소유 항목은 해당 Phase에 반영 |
| 검증 명령과 결과 기록 | 충족 | 테스트 미실행 사유와 기존 기록 분리 |
**최종 결론:** 확정 발견 사항 없음.
**남은 항목:** 없음. Phase 3·7 회귀 Goal과 Phase 6 후속 문서 검증 기록은 이후 섹션에 누적했다.
## 7. 2차 리뷰 — 2026-07-30
### 기존 후속 항목 확인
- Phase 3의 `P3-R1`과 Phase 7의 `P7-R1`·`P7-R2` 구현 및 기존 Gate 성공 기록이 누적된 것을 확인했다.
- 이번 확인에서는 컴파일과 테스트를 재실행하지 않았다.
### REV-P6-001 — PRD의 `newsId` 형식이 현재 공개 동작과 불일치
**심각도:** Low
**상태:** 확정
**근거**
- PRD 공통 식별자 설명은 `scheduleId``newsId` 모두 `{TYPE}:{targetId}` 형식을 기본안으로 적고 있다.
- `DefaultHomeFollowingQueryRepository``home_following_news_inbox.id`를 문자열로 변환해 `newsId`로 반환한다.
- repository test와 E2E도 inbox PK의 10진 문자열을 계약으로 검증한다.
- 최근 소식 정렬과 `CONTENT_RANKING` 동률 해소도 inbox `id`를 사용하므로, 현재 동작을 유지한 문서 수정이 가장 작은 정합성 보완이다.
**영향**
클라이언트 또는 후속 구현자가 PRD만 보면 `newsId`를 타입·target 기반 식별자로 해석할 수 있어 실제 응답 파싱, 정렬 의미, 동일 target의 여러 소식 식별을 잘못 구현할 수 있다.
**권장 조치**
runtime 코드와 공개 응답 값은 변경하지 않는다. PRD에서 `scheduleId``{TYPE}:{targetId}`, `newsId``home_following_news_inbox.id`의 10진 문자열이며 같은 노출 시각의 정렬·동률 해소에 쓰인다고 분리해 명시한다.
**판정 기록**
- 2026-07-30 — PRD, repository, repository test, E2E를 정적으로 대조해 확정했다. Gradle 명령은 실행하지 않았다.
### plan·goal 전환
- `plan-task.md` Phase 6에 문서 전용 Task 6.3, `P6-R1`, `P6-R-GATE`를 추가했다.
- 기존 Task 6.1~6.2의 완료 체크와 검증 기록은 유지했다.
### 2차 리뷰 종료 판정
| 판정 항목 | 결과 | 근거 |
|---|---|---|
| 리뷰 범위 전체 확인 | 충족 | PRD/repository/test/E2E 식별자 계약 정적 대조 |
| 후보 항목 판정 완료 | 충족 | `REV-P6-001` 확정 |
| 확정 항목 plan 반영 | 충족 | Task 6.3 / `P6-R1` |
| 검증 명령과 결과 기록 | 충족 | Gradle 미실행 사유 기록 |
**최종 결론:** 문서 수정 goal 필요.
**남은 항목:** 없음. `P6-R1``P6-R-GATE` 수정 후 검증은 아래 기록에 누적했다.
## 8. 수정 후 검증 — 2026-07-30
- PRD에서 `scheduleId``newsId` 식별자 설명을 분리했다.
- `scheduleId``{TYPE}:{targetId}` 형식, `newsId``home_following_news_inbox.id`의 10진 문자열이며 `visibleFromAtUtc desc`, `newsId desc` 정렬과 `CONTENT_RANKING` 동률 해소에 사용한다고 명시했다.
- runtime 코드, 테스트, DDL, 공개 응답 필드는 변경하지 않았다.
- 정적 검색 `rg -n "newsId|scheduleId|home_following_news_inbox\.id" ...` 실행 결과 PRD와 repository/test/E2E의 식별자 계약이 일치함을 확인했다.
- `git diff --check` 실행 결과 오류 없음.
- `./gradlew tasks --all` 실행 결과 `BUILD SUCCESSFUL`.
- 리뷰 게이트에서 Critical/Important/Minor blocker 없음으로 승인됐다.
**수정 후 결론:** `REV-P6-001` 문서 보완 완료.
## 9. 3차 정적 리뷰 — 2026-07-30
### 리뷰 범위
- PRD의 최근 소식 최신 배치 정책, Phase 7 회귀 Task, repository 조건과 회귀 테스트를 정적으로 대조했다.
- 컴파일과 테스트는 사용자 지시에 따라 실행하지 않았다.
### REV-P6-002 — PRD의 최신 크리에이터 랭킹 배치 판정 기준이 현재 구현과 불일치
**심각도:** Low
**상태:** 확정
**관련 요구사항:** 최신 공개 `WEEKLY` 배치만 조회하고 빈 최신 배치에서 과거 순위를 보충하지 않는 정책
**소유 Task:** Task 6.4 / `P6-R2`
**관찰 내용**
PRD Feature F와 기술 제약은 최신 `CREATOR_RANKING` 배치를 `creator_ranking_snapshot`의 최대 공개 시각으로 판정한다고 기술한다. 그러나 `REV-P7-001` 보완 이후 현재 repository는 적용 가능한 `creator_ranking_snapshot_job`의 최신 `WEEKLY`, `DONE`, `visibleFromAtUtc <= nowUtc` 시각을 우선 사용하고, 해당 job이 전혀 없을 때만 snapshot으로 fallback한다.
**근거**
- PRD의 최신 배치 설명 두 곳은 `creator_ranking_snapshot`만 판정 원천으로 명시한다.
- `plan-task.md` Task 7.2는 빈 최신 완료 배치를 식별하기 위해 job 우선·legacy snapshot 제한 fallback을 확정했다.
- `DefaultHomeFollowingQueryRepository.latestVisibleCreatorRankingBatchCondition(...)`은 최신 DONE job 시각을 우선하고 `hasRankingJob.not()`일 때만 snapshot 시각을 사용한다.
- `DefaultHomeFollowingQueryRepositoryTest.shouldExcludeCreatorRankingNewsWhenLatestDoneBatchIsEmpty`는 최신 DONE job의 snapshot row가 0건이어도 과거 소식을 반환하지 않는 현재 계약을 검증한다.
**영향**
후속 구현자가 PRD만 따르면 최신 빈 완료 배치에서 과거 snapshot을 다시 최신으로 판정해 이미 수정한 회귀를 재도입할 수 있다.
**권장 조치**
runtime은 변경하지 않는다. PRD 두 곳을 최신 공개 DONE job 우선으로 동기화하고, 적용 가능한 DONE job이 전혀 없는 legacy/backfill 데이터에서만 snapshot fallback을 허용하며 빈 DONE 배치는 과거 snapshot으로 보충하지 않는다고 명시한다.
**판정 기록**
- 2026-07-30 — PRD, Task 7.2, repository, 빈 최신 배치 회귀 테스트를 정적으로 대조해 확정했다. Gradle 명령은 실행하지 않았다.
### plan·goal 전환
- `plan-task.md` Phase 6에 문서 전용 Task 6.4, `P6-R2`, `P6-R2-GATE`를 추가했다.
- 기존 Task 6.1~6.3의 완료 체크와 검증 기록은 유지했다.
### 3차 리뷰 종료 판정
| 판정 항목 | 결과 | 근거 |
|---|---|---|
| 리뷰 범위 전체 확인 | 충족 | PRD/Task/repository/test 최신 배치 기준 정적 대조 |
| 후보 항목 판정 완료 | 충족 | `REV-P6-002` 확정 |
| 확정 항목 plan 반영 | 충족 | Task 6.4 / `P6-R2` |
| 검증 명령과 결과 기록 | 충족 | Gradle 미실행 사유와 정적 근거 기록 |
**최종 결론:** 문서 수정 goal 필요.
**남은 항목:** 없음. `P6-R2``P6-R2-GATE` 수정 후 검증은 아래 기록에 누적했다.
## 10. 3차 수정 후 검증 — 2026-07-30
- PRD Feature F와 최근 소식 Inbox 기술 제약의 `CREATOR_RANKING` 최신 공개 배치 설명을 현재 구현의 `creator_ranking_snapshot_job` 최신 `WEEKLY`, `DONE`, `visibleFromAtUtc <= nowUtc` 우선 기준과 일치하도록 갱신했다.
- 적용 가능한 완료 job이 전혀 없는 legacy/backfill 데이터에서만 `creator_ranking_snapshot` fallback을 허용하고, 최신 완료 job의 결과가 0건이면 과거 snapshot으로 보충하지 않는다고 명시했다.
- P6-R2-GATE 정적 검색 `rg -n "creator_ranking_snapshot_job|creator_ranking_snapshot|최신 공개 배치|WEEKLY|DONE|legacy|fallback" ...` 실행 결과 PRD, Task 7.2, repository, 빈 최신 배치 회귀 테스트의 기준을 대조했다. 검색 결과의 과거 Task 7.1 snapshot 설명은 Task 7.2에서 superseded된 완료 기록으로 확인했다.
- P6-R2-GATE `git diff --check` 실행 결과 오류 없음.
- P6-R2-GATE `./gradlew tasks --all` 실행 결과 `BUILD SUCCESSFUL`.
- 추가 전체 회귀 확인: `./gradlew --no-daemon test` 실행 결과 `BUILD SUCCESSFUL`.
- 리뷰 게이트에서 Critical/Important/Minor blocker 없음으로 승인됐다.
**수정 후 결론:** `REV-P6-002` 문서 보완 완료.
## 11. 4차 정적 리뷰 — 2026-07-30
- PRD·plan·DDL·공개 DTO와 현재 repository의 endpoint, limit, 식별자, latest ranking batch, nested 최근 소식 계약을 다시 대조했다.
- `newsId`의 inbox PK 문자열 계약과 최신 `WEEKLY`, `DONE` job 우선·legacy snapshot 제한 fallback 설명이 현재 코드·테스트와 일치함을 확인했다.
- 컴파일과 테스트는 사용자 지시에 따라 실행하지 않았다.
- 신규 확정 발견 사항 없음. `REV-P6-001`, `REV-P6-002` 문서 보완 완료와 기존 Phase 6 완료 판정을 유지한다.