Files
sodalive-backend-spring-boot/docs/20260612_크리에이터_채널_홈_API/reviews/phase-4-review.md

7.2 KiB

Phase 4 코드 리뷰 보고서

1. 리뷰 정보

항목 내용
리뷰 대상 Phase 4 / Task 4.1~4.2
기준 commit 또는 working tree f1c2e6c5 + 2026-07-30 working tree
리뷰 일자 2026-07-30
리뷰어 Codex
기준 문서 prd.md, plan-task.md, 홈 API 구조 정렬 후속 문서, docs/agent-guides/*.md
리뷰 상태 판정 완료

2. 목적과 범위

  • service의 접근 검증, 조회자 context, 섹션 조립, 최종 정책 보정을 PRD와 대조했다.
  • CreatorChannelHomeQueryService.kt, MemberContentPreferenceService.kt, 대응 service 테스트를 포함했다.
  • 사용자 지시에 따라 컴파일·테스트는 실행하지 않았다.

3. 검토 근거

  • CreatorChannelHomeQueryService.kt:70-71getStoredPreference(viewer)canViewAdultContent(viewer)를 이어서 호출한다.
  • MemberContentPreferenceService.kt:144-157에서 canViewAdultContentub294 getStoredPreference(member).isAdult를 다시 호출한다.
  • 두 호출은 같은 요청에서 같은 ViewerContentPreference를 사용할 수 있으며, getStoredPreferenceREQUIRES_NEW transaction이다.

4. 발견 사항

ID 심각도 상태 제목 소유 Task 후속 goal
REV-P4-001 Low 완료 홈 조회가 콘텐츠 선호를 같은 요청에서 두 번 조회한다 Task 4.3 P4-R1

REV-P4-001 — 홈 조회가 콘텐츠 선호를 같은 요청에서 두 번 조회한다

  • 심각도: Low
  • 상태: 확정
  • 관련 요구사항: Phase 4 조회자 성인 노출·콘텐츠 타입 context 조립
  • 소유 Task: Task 4.3 / P4-R1

관찰 내용

service가 이미 받은 preference.isAdult를 사용할 수 있지만 canViewAdultContent(viewer)를 다시 호출한다. 실제 bean에서는 이 메서드가 getStoredPreference 전체 경로를 반복한다.

영향

공개 응답은 바뀌지 않지만, 홈 조회마다 독립 transaction·선호·국가 context 조회가 중복된다.

권장 조치

preference.isAdult를 성인 필터에 재사용하고, service 테스트에서 별도 canViewAdultContent 호출이 없음을 고정한다.

판정 기록

  • 2026-07-30 — 두 method의 정적 호출 관계와 transaction annotation으로 확정.
  • 2026-07-30 — CreatorChannelHomeQueryServiceTest RED/GREEN으로 preference.isAdult 재사용과 canViewAdultContent(viewer) 미호출을 검증하고 완료.

5. plan·goal 전환

  • plan-task.md Phase 4에 Task 4.3 / P4-R1을 추가했다.
  • 실행 objective: REV-P4-001을 수정하고 service 조립 회귀를 방지한다.

6. 리뷰 종료 판정

판정 항목 결과 근거
리뷰 범위 전체 확인 충족 service·선호 service·테스트 정적 대조
후보 항목 판정 완료 충족 REV-P4-001 확정
확정 항목 plan 반영 충족 Task 4.3 / P4-R1
검증 명령과 결과 기록 충족 정적 검토만 실행, 테스트 미실행 사유 기록

최종 결론: 수정 goal 완료.

남은 항목: 없음.

7. 2차 리뷰 — 2026-07-30

7.1 리뷰 범위와 방법

  • service/facade의 조회자 context 조립과 기본 now 생성 지점을 기존 라이브 목록, 홈 Following, UTC 응답·KST 월 경계 계약과 대조했다.
  • 사용자 지시에 따라 테스트·컴파일·ktlint은 실행하지 않았다.

7.2 발견 사항

ID 심각도 상태 제목 소유 Task 후속 goal
REV-P4-002 Medium 완료 다른 크리에이터가 조회하면 입장 제한이 적용되지 않는다 Task 4.4 P4-R2
REV-P4-003 Medium 완료 홈 기본 시각이 JVM timezone에 따라 달라진다 Task 4.5 P4-R3

REV-P4-002 — 다른 크리에이터가 조회하면 입장 제한이 적용되지 않는다

  • 관련 요구사항: PRD Feature B/F의 기존 라이브 목록 동일 정책, Task 4.1
  • 관찰: service는 isViewerCreator = viewerId == creatorId로 계산한다. 반면 기존 라이브 목록과 HomeFollowingQueryService는 조회자의 MemberRole.CREATOR 여부를 사용하며, repository는 이 값이 true일 때 isAvailableJoinCreator 또는 자기 라이브 예외를 적용한다.
  • 영향: 크리에이터가 다른 크리에이터 채널을 볼 때 isAvailableJoinCreator == false인 현재/예약 라이브가 홈에 노출될 수 있다.
  • 권장 조치: 조회자의 role로 flag를 산출하고 다른 크리에이터 조회 회귀 테스트를 추가한다.
  • 완료 기록: 2026-07-30 — 다른 크리에이터/일반 회원/대상 본인 focused test로 viewer.role == MemberRole.CREATOR 계산을 검증했다.

REV-P4-003 — 홈 기본 시각이 JVM timezone에 따라 달라진다

  • 관련 요구사항: UTC 시간 계약, KST 기준 이번 달 후원, Task 4.1·6.4
  • 관찰: facade와 service의 기본값은 LocalDateTime.now()인 반면 repository는 입력 now를 UTC로 간주해 KST 월 경계로 변환하고 DTO도 UTC offset을 붙인다. JVM timezone을 고정하는 설정은 확인되지 않았고, 인접 HomeFollowingQueryService는 UTC clock을 명시한다.
  • 영향: JVM이 UTC가 아니면 공개/예약 콘텐츠 경계와 이번 달 후원 범위가 timezone offset만큼 이동하고, 응답 문자열도 실제 instant와 다를 수 있다. 현재 E2E fixture도 같은 LocalDateTime.now()를 사용해 이 조건을 드러내지 못한다.
  • 권장 조치: 인자 없는 조회의 now를 UTC로 생성하고 비 UTC JVM timezone 회귀 테스트를 추가한다.
  • 완료 기록: 2026-07-30 — facade 기본 호출을 Asia/Seoul JVM timezone에서 검증하고 facade/service 기본 now를 UTC로 고정했다.

7.3 plan·goal 전환과 종료 판정

  • plan-task.md Phase 4에 Task 4.4 / P4-R2, Task 4.5 / P4-R3을 추가했다.
  • 최종 결론: Medium 2건 수정 완료.
  • 남은 항목: 없음.

8. 3차 리뷰 — 2026-07-31

  • 대상: 접근 검증 순서, 콘텐츠 선호 단일 조회, 조회자 role/effective gender 전달, facade·service 기본 UTC 시각과 전체 섹션 조립.
  • 방법: CreatorChannelHomeQueryService, CreatorChannelHomeFacade와 대응 service/facade 테스트를 Task 4.1~4.5 및 기존 라이브 목록 정책과 정적 대조했다. 사용자 지시에 따라 테스트·컴파일·ktlint은 실행하지 않았다.
  • 결과: REV-P4-001~REV-P4-003 수정 반영을 포함해 신규 확정 발견 사항 없음. Phase 4 후속 Task를 추가하지 않는다.
  • 남은 항목: 없음.

9. 4차 리뷰 — 2026-07-31

  • 대상: 접근 예외 순서, 콘텐츠 선호 단일 조회, 조회자 role/effective gender, UTC now 전달과 전체 섹션 조립.
  • 방법: query service/facade의 실제 호출 흐름과 service/facade 테스트를 기존 라이브 목록 정책 및 Task 4.1~4.5와 정적 대조했다. 사용자 지시에 따라 테스트·컴파일·ktlint은 실행하지 않았다.
  • 결과: 기존 REV-P4-001~REV-P4-003 보정이 유지되며 신규 확정 발견 사항 없음. Phase 4 후속 Task를 추가하지 않는다.
  • 남은 항목: 없음.