Files
sodalive-backend-spring-boot/docs/20260529_메인_홈_추천_API/reviews/phase-11-review.md

9.5 KiB

Phase 11 코드 리뷰 보고서

1. 리뷰 정보

항목 내용
리뷰 대상 Phase 11 / Task 11.1~11.2 / P11-GATE
기준 commit 또는 working tree b30447f0 기준 working tree 변경
리뷰 일자 2026-07-30
리뷰어 Codex
기준 문서 docs/20260529_메인_홈_추천_API/prd.md, docs/20260529_메인_홈_추천_API/plan-task.md
리뷰 상태 수정 검증 완료 / 2차 정적 재점검 완료

2. 리뷰 목적과 범위

목적

  • Phase 11 구현이 PRD Feature D의 creatorId와 상태별 LIVE targetId 계약을 충족하는지 정적으로 확인한다.
  • 완료된 Task·Gate 기록과 실제 코드·테스트 변경이 일치하는지 확인한다.

포함 범위

  • 코드: RecentlyActiveCreatorRecord, 최근 활동 native query/row mapping, HomeActiveCreatorItem, facade 변환
  • 테스트: 최근 활동 repository 테스트, 홈 통합 API JSON 테스트, service fixture
  • 문서: PRD Feature D, plan-task Phase 11과 Verification Log
  • 수동 검증: working tree diff, 호출 흐름, Spring JSON path matcher 의미 대조

제외 범위

  • Phase 1~10과 Phase 11 외 기능
  • 앱 클라이언트 네비게이션 및 라이브 입장 실패 fallback 구현
  • 사용자 지시에 따른 Gradle 컴파일·테스트 재실행

3. 판정 기준

심각도 기준
Blocker 핵심 흐름 불능, 보안·데이터 손실 또는 완료 판정을 무효화하는 문제
High 확정 요구사항·공개 API 계약 위반 또는 주요 회귀
Medium 제한된 조건의 기능·복구 문제
Low 테스트 판별력, 유지보수성 또는 문서 정합성 문제
상태 의미
후보 근거 확인 전
확정 코드·테스트·문서 근거로 확인됨
오탐 요구사항 또는 코드 근거상 문제 아님
보류 외부 결정·환경 필요
수정 완료 수정과 검증 완료

4. 검토한 근거

문서와 코드

  • 요구사항: PRD Feature D Requirements, Response Contract, Acceptance Criteria
  • 계획: P11-T1, P11-T2, P11-GATE
  • 내부 조회: DefaultHomeRecommendationQueryRepository.kt:130-208
  • 내부 record: HomeRecommendationQueryPort.kt:105-112
  • 공개 응답: HomeRecommendationResponse.kt:38-45
  • facade: HomeRecommendationFacade.kt:247-254
  • repository 테스트: DefaultHomeRecommendationQueryRepositoryTest.kt:405-467
  • API 테스트: HomeRecommendationControllerTest.kt:527-545

실행 환경

검토 방식: working tree 정적 리뷰
기준 commit: b30447f0
컴파일·테스트: 사용자 지시에 따라 실행하지 않음
민감정보: 조회·기록하지 않음

실행한 검증

명령 또는 수동 검증 결과 핵심 증거
git status --short, git diff --name-status 성공 Phase 11 계획의 코드·테스트 7개 파일과 문서 변경 확인
Phase 11 관련 git diff 및 호출 흐름 대조 성공 query select/row index, record/DTO/facade 필드가 계약과 일치
Spring 5.3.29 JsonPathResultMatchers 로컬 source jar 확인 성공 doesNotExist()가 누락 path와 null 값 모두 허용함을 확인
Jackson null 제외 설정 검색 성공 대상 DTO와 전역 설정에 NON_NULL 적용이 없음을 확인
Gradle 컴파일·테스트 미실행 사용자가 현재 통과 상태를 제공하고 재실행을 금지함

5. 발견 사항 요약

ID 심각도 상태 제목 소유 Task 후속 goal
REV-P11-001 Low 수정 완료 종료 LIVE 테스트가 targetId 누락과 null을 구분하지 못함 Task 11.3 P11-R1

구현 코드에서 확정된 기능 결함은 발견하지 않았다.

6. 발견 사항 상세

REV-P11-001 — 종료 LIVE 테스트가 targetId 누락과 null을 구분하지 못함

  • 심각도: Low
  • 상태: 수정 완료
  • 관련 요구사항: PRD Feature D Acceptance Criteria
  • 관련 계약: 종료된 LIVE는 targetId = null
  • 소유 Task: Task 11.3 / P11-R1

관찰 내용

HomeRecommendationControllerTest.shouldExposeNavigationIdsForRecentlyActiveLiveCreators는 종료 LIVE의 targetIddoesNotExist()로 검증한다. Spring 5.3.29에서 이 matcher는 JSON path가 없을 때와 값이 null일 때 모두 통과하므로, 필드를 생략하는 회귀를 탐지하지 못한다.

근거

  • 코드: HomeRecommendationControllerTest.kt:545
  • 문서: PRD Feature D의 Response Contract와 Acceptance Criteria
  • 라이브러리: Spring Test 5.3.29 JsonPathResultMatchers.doesNotExist()JsonPathExpectationsHelper.doesNotExist(...)

재현 또는 검증 절차

  1. 종료 LIVE JSON assertion이 doesNotExist()만 사용하는지 확인했다.
  2. 로컬 Spring Test 5.3.29 source jar에서 doesNotExist() 구현을 확인했다.
  3. 해당 구현은 path 평가 실패를 정상 반환하고, path가 있으면 값이 null일 때 성공한다.
  4. 따라서 현재 assertion은 targetId 누락과 명시적 null을 구분하지 않는다.

영향

현재 production 구현은 nullable DTO를 사용하고 null 제외 설정이 없어 계약과 일치하는 구조다. 그러나 이후 Jackson null 제외 설정이나 DTO annotation이 추가되어 targetId가 생략돼도 이 테스트는 통과하므로 공개 응답 계약 회귀를 차단하지 못한다.

권장 조치

같은 JSON path에 hasJsonPath()를 추가하고 기존 doesNotExist()와 함께 검증한다. production 코드는 변경하지 않는다.

판정 기록

  • 2026-07-30 — Spring 5.3.29 matcher 구현과 PRD 계약을 대조해 Low 확정.
  • 2026-07-30 — hasJsonPath()doesNotExist() 조합으로 JSON path 존재와 null 값을 모두 검증하도록 수정하고 focused/API 회귀/lint/문서 검증을 완료했다.

7. 확정 항목의 plan·goal 전환

신규 회귀 수정 Task

  • Task 11.3: 종료 LIVE targetId의 명시적 null JSON 계약 검증 보강
  • Goal: P11-R1
  • 변경 범위: HomeRecommendationControllerTest, plan-task, 이 review 문서
  • production 코드 변경: 없음

create_goal objective 초안

[P11-R1]의 확정 review 항목 REV-P11-001을 수정하고 회귀를 방지한다.
plan-task.md의 Task 11.3만 수행한다.
종료 LIVE targetId의 JSON path 존재와 null 값을 함께 검증하고 focused test, 홈 API 회귀, lint, 문서 검증과 기록이 모두 끝나기 전에는 complete로 표시하지 않는다.
production DTO·facade·query 변경과 관련 없는 리팩터링은 범위 밖이다.

8. 리뷰 종료 판정

판정 항목 결과 근거
리뷰 범위 전체 확인 충족 Phase 11 문서·코드·테스트 diff 대조
후보 항목 판정 완료 충족 REV-P11-001 Low 확정
확정 항목 plan 반영 충족 Task 11.3 / P11-R1 추가
보류 항목의 담당·재개 조건 기록 해당 없음 보류 항목 없음
검증 명령과 결과 기록 충족 정적 검증 기록, Gradle 미실행 사유 명시

최종 결론: 수정 완료

남은 항목: 없음

9. 수정 후 검증 기록

  • 2026-07-30: HomeRecommendationControllerTest.shouldExposeNavigationIdsForRecentlyActiveLiveCreators에 종료 LIVE targetId hasJsonPath() assertion을 추가해 명시적 null JSON 계약을 고정했다. focused test는 120000ms timeout 후 240000ms로 재실행해 BUILD SUCCESSFUL로 통과했다. 이어서 ./gradlew test --tests kr.co.vividnext.sodalive.v2.api.home.HomeRecommendationControllerTest, ./gradlew ktlintCheck, ./gradlew tasks --all, git diff --check를 실행했고 모두 BUILD SUCCESSFUL 또는 무출력 통과했다. production 코드는 변경하지 않았다.

10. 2차 정적 재점검 — 2026-07-30

범위와 방법

  • 기준: b30447f0 기준 현재 working tree와 P11-R1 반영 상태
  • 문서: PRD Feature D, plan-task Phase 11·PRD Coverage Check·Verification Log
  • 코드 흐름: native query/row mapping → RecentlyActiveCreatorRecord → facade → HomeActiveCreatorItem
  • 테스트: repository의 전체 활동 타입·LIVE 상태 분기와 홈 API JSON 계약 assertion
  • 제외: 사용자 지시에 따라 Gradle 컴파일·테스트 재실행

정적 검증 결과

검증 결과 근거
git diff로 Phase 11 변경 전체 대조 충족 creatorId select/row index/DTO/facade 매핑과 LIVE targetId 분기가 PRD 계약과 일치
rg로 record·DTO 생성자와 조회 호출 지점 확인 충족 변경 타입의 모든 생성·매핑 지점이 신규 non-null creatorId를 반영
nullable JSON 설정과 assertion 대조 충족 대상 DTO·전역 설정에 null 제외가 없고 hasJsonPath() + doesNotExist()가 명시적 null 계약을 고정
비 LIVE 회귀와 LIVE 상태 분기 테스트 대조 충족 AUDIO·LIVE_REPLAY·COMMUNITY의 기존 targetId, 진행 중/종료 LIVE, 모든 활동의 creatorId를 검증
변경 Kotlin 라인 길이와 git diff --check 충족 130자 초과 신규 Kotlin 라인 없음, whitespace 오류 없음
과설계·범위 확장 점검 충족 신규 dependency·상태 타입·추상화 없이 기존 record/DTO/query만 최소 변경

발견 사항과 종료 판정

  • 신규 후보·확정·보류 항목 없음.
  • 기존 REV-P11-001은 Task 11.3 / P11-R1에서 수정 완료 상태를 유지한다.
  • 추가로 plan-task.md에 전환할 회귀 수정 Task/Goal 없음.
  • 최종 결론: Phase 11 2차 정적 리뷰 완료, 확정 발견 사항 없음.