Files
sodalive-backend-spring-boot/docs/20260917_라이브_크리에이터_입장제한/reviews/현재변경사항-review.md
T

12 KiB

라이브 크리에이터 입장 제한 현재 변경사항 리뷰

1. 리뷰 정보

  • 일자: 2026-09-17
  • 기준: 62c834d28f0d142e81f2d303273eb1220cab0611 위의 현재 staged/working tree 변경사항. commit 자체에 대한 승인이 아니다.
  • 소스 diff SHA-256 (git diff HEAD -- src): 7b951c79f1575832ac65870a479005909da22e640772c5609a3cbdd983209b98
  • 기준 문서: ../prd.md, ../plan-task.md
  • 범위: LCR-001~004, 변경 production 7개 파일과 관련 테스트, 기존 조회/입장 정책.
  • 상태: 판정 완료. production 및 테스트 코드는 수정하지 않았다.

2. 검토 기준 및 근거

  • 홈 추천·라이브·온에어의 역할/인증 성별 전달, QueryDSL 필터와 생성자 예외를 대조한다.
  • 크리에이터 채널 라이브의 역할 판정과 기존 repository 조건을 대조한다.
  • 직접 입장 거부가 결제 및 roomInfo 접근보다 먼저 발생하는지 확인한다.
  • 공개 DTO, 일반 사용자, Gender.NONE, 기존 성인/차단/결제 정책의 회귀 여부를 확인한다.
  • docs/sample/sample-review.md 기준으로 확정 결함과 검증 한계를 구분한다.

3. 검토별 증거 기록

검토 기준 HEAD 판정 근거
코드 품질 62c834d28f0d142e81f2d303273eb1220cab0611 + 현재 변경 PASS /root/quality: SQL WHERE 적용 후 페이지네이션, 호출 3곳 인자 전달, 기본값 및 생성자 예외, 부수효과 전 차단 확인. 이전 XML은 이번 실행 증거로 사용하지 않음.
요구사항 62c834d28f0d142e81f2d303273eb1220cab0611 + 현재 변경 PASS /root/requirements: LCR-001~004 구현 일치. 채널 소유자 조회의 직접 회귀 테스트는 보완 여지 있음.
주변 문맥 62c834d28f0d142e81f2d303273eb1220cab0611 + 현재 변경 PASS /root/context: 기존 팔로잉·채널 홈 조건 및 Member.canEnter와 일치. 기존 상세 조회의 제한 미검사는 이번 diff 밖임.
보안 62c834d28f0d142e81f2d303273eb1220cab0611 + 현재 변경 FAIL /root/security: getRoomInfo의 기존 RTC 토큰 발급 경로가 입장 제한을 검사하지 않음. 코드 추적 근거이며 실제 RTC 연결은 미검증.
자동 QA 62c834d28f0d142e81f2d303273eb1220cab0611 + 현재 변경 PASS /root/qa: focused 140건 + 인접 회귀 42건 통과. 실제 HTTP/RTC QA는 INCONCLUSIVE.
런타임 감사 62c834d28f0d142e81f2d303273eb1220cab0611 + 현재 변경 INCONCLUSIVE H2 쿼리 결과, 서비스 거부 예외 및 무부수효과 assertion은 실행 확인. 실제 RTC 토큰을 사용한 연결 우회는 실행하지 않음.

4. 실행 검증

환경: macOS, Java 17, Gradle Wrapper, repository 테스트 H2. 전체 회귀 대신 변경 파일 focused test 및 직접 영향받는 기능 회귀를 실행한다. 공개 DTO·공통 인증·설정 변경은 없으며 이 리뷰에서 소스를 수정하지 않아 전체 테스트를 재실행하지 않았다. 기존 계획의 전체 회귀 성공 기록은 이번 실행 결과로 간주하지 않는다.

./gradlew test --rerun-tasks --tests '*DefaultHomeRecommendationQueryRepositoryTest' --tests '*CreatorChannelLiveQueryServiceTest' --tests '*LiveRoomServiceTest' --tests '*HomeRecommendationQueryServiceTest' --tests '*HomeRecommendationFacadeTest' --tests '*HomeOnAirLiveFacadeTest'
  • /root/qa 실행: BUILD SUCCESSFUL, 140건, 실패/오류/skip 0, 3분 19초.
  • ./gradlew ktlintCheck tasks --all: BUILD SUCCESSFUL. ktlint 작업은 UP-TO-DATE이며 강제 재실행은 하지 않았다.
  • git diff --check: exit 0.
  • ./gradlew test --tests '*HomeRecommendationControllerTest' --tests '*DefaultCreatorChannelLiveQueryRepositoryTest' --tests '*HomeOnAirLiveControllerTest' --tests '*LiveRoomServiceAdultVisibilityPolicyTest': exit 0, 42건, 실패/오류/skip 0, 41초.
  • 합계: 182건 통과. 추천 repository 81, 추천 service 35, 추천 facade 6, 온에어 facade 4, 채널 service 9, 입장 service 5, 추천 controller 27, 온에어 controller 2, 채널 repository 8, 기존 성인 정책 5.
  • 실제 HTTP/RTC 연결은 미검증. localhost:8080에 실행 중 서버가 없고 운영 데이터·외부 서비스에 연결하지 않았다. 서비스 Mockito 테스트 및 H2 repository 테스트는 입장 거부/조회 필터의 실행 증거이며 실제 RTC 우회 재현 증거는 아니다.

5. 발견 사항 및 종료 판정

REV-001 — 기존 방 정보 API의 토큰 발급 경계에 제한 검사 없음

  • 심각도: High. 상태: 제한 검사 누락은 코드로 확정, 실제 RTC 접속 우회는 미검증.
  • 관련 목표: PRD §3의 다른 크리에이터·성별 불일치 사용자의 입장 차단.
  • 이번 diff가 도입한 결함은 아니며, 계획에 명시된 목록 및 /enter 수정 범위 밖의 기존 경로다.
  • LiveRoomController.kt:129의 GET /live/room/info/{id}는 로그인 확인 후 getRoomInfo()를 호출한다.
  • LiveRoomService.kt:972는 roomInfo·room 존재와 상호 차단만 검사한다. 크리에이터 제한, 성별 제한, 호출자의 입장 완료 여부는 확인하지 않는다.
  • 같은 파일 :991부터 RTC 토큰 생성기를 호출하고 :1065부터 채널명과 토큰을 응답에 넣는다. RtcTokenBuilder.kt:83은 JoinChannel 권한을 추가한다.
  • 확인 시나리오: roomInfo가 존재하는 제한 방에서, 호스트와 차단 관계가 없는 다른 크리에이터가 방 ID로 /info/{id}를 요청한다. /enter에서 거절됐더라도 이 경로의 토큰 발급 전 제한 검사가 없다.
  • 권장 조치: 토큰 발급 경계에도 생성자 예외를 포함한 크리에이터·성별 제한을 적용하고, 제한 사용자는 토큰 생성기가 호출되지 않는 회귀 테스트로 고정한다. 전체 입장 정책 재설계는 별도 범위다.

REV-002 — 채널 소유자 조회의 직접 회귀 테스트 보완

  • 심각도: Low, 비차단 검증 보완점.
  • CreatorChannelLiveQueryServiceTest.kt:67은 다른 크리에이터의 isViewerCreator 전달을 검증한다.
  • DefaultCreatorChannelLiveQueryRepositoryTest.kt:206은 다른 크리에이터 조회 필터를 검증하지만, 소유자 본인의 제한 방 반환을 직접 검증하지 않는다.
  • 소유자 허용 조건 자체는 DefaultCreatorChannelLiveQueryRepository.kt:353에 존재하므로 구현 누락으로 판정하지 않는다.
  • 권장 조치: viewerId == creatorId이고 isAvailableJoinCreator == false인 현재 방이 반환되는 repository 회귀 테스트 1건으로 P1-T2 완료 증거를 보강한다.

6. 후속 처리

코드 수정은 수행하지 않았다. 명시된 구현 범위의 기능 결함은 발견하지 못했으나, 제품 전체의 입장 차단 완료 판정에는 REV-001 확인·보강이 필요하다. 구현을 진행할 경우 기존 계획에 토큰 발급 경계 보강 Task를 추가한 뒤 실패 재현 → 최소 수정 → 회귀 검증 순서로 진행한다. 기존 완료 체크박스와 검증 기록은 유지한다.

종합 판정: 명시된 목록·/enter 구현 범위는 적합하다. 보안 검토 FAIL 및 실제 API/RTC 검증 한계 때문에 제품 전체의 입장 차단에 대한 무조건 승인은 보류한다. 이번 diff에서 새로 도입된 확정 결함은 발견하지 못했다.

다음 행동: REV-001의 토큰 발급 경계를 후속 검증·수정 범위로 반영한다.

7. Phase 3 후속 구현 검증

  • 일자: 2026-09-17
  • 대상: REV-001, REV-002 후속 구현과 Phase 3 Gate.
  • REV-001 해소: LiveRoomService.getRoomInfo()가 기존 room/roomInfo 존재 및 상호 차단 검사 뒤, RTC/RTM/v2v 토큰 생성 전에 다른 크리에이터와 성별 불일치 사용자를 각각 live.room.not_found, live.room.gender_restricted로 거절한다.
  • REV-001 회귀: 제한 경로의 token builder 무호출, /enter 거절 후 정보 조회 거절, 소유자·성별 일치 사용자·허용 방 크리에이터·인증 성별 우선·Gender.NONE 허용, 기존 상호 차단 거절을 서비스 테스트로 확인했다.
  • REV-002 해소: 실제 H2 repository 테스트가 채널 소유자에게 isAvailableJoinCreator = false인 본인 현재 방 ID를 반환하고, 기존 다른 크리에이터 제외 테스트도 통과했다.
  • Phase 3 focused 회귀: 5개 테스트 클래스 119건이 실패·오류·skip 0으로 통과했다.
  • 품질 및 명령 검증: ./gradlew ktlintCheck, ./gradlew tasks --all, git diff --check가 성공했다.
  • 전체 회귀: 보안 경계 변경을 반영해 ./gradlew test --rerun-tasks를 실행했고 BUILD SUCCESSFUL로 종료했다.
  • 검증 한계 기록: 실제 HTTP 인증/직렬화 및 Agora RTC/RTM 연결은 실행하지 않았으며 서비스 메서드 호출, token builder 무호출 assertion, 실제 H2 조회를 대체 실행 증거로 사용했다.
  • 최종 reviewer gate: Phase 3 구현·테스트·문서 정합성을 전체 diff 기준으로 재검토했고 Blocker 0건으로 승인됐다.

후속 판정: REV-001, REV-002는 구현 및 회귀 검증으로 해소됐다. 기존 리뷰의 보안 FAIL은 토큰 발급 전 서버 제한 검사 누락 기준에서 해소됐으며, 실제 RTC 연결 검증을 수행했다는 주장은 하지 않는다.

8. Phase 1~3 문서·코드 정적 재대조 — 2026-09-17

  • 사용자 요청: 전체 자동 테스트는 이미 수행됐으므로 재실행하지 않고 문서와 실제 코드의 스펙 일치 여부를 확인한다.
  • 기준 HEAD: 62c834d28f0d142e81f2d303273eb1220cab0611 및 현재 staged/working tree 변경.
  • 소스 diff SHA-256 (git diff HEAD -- src): 4d90f90b2a262d1ee081c8e9fc78085ce6d04199d9c50a3d5a7506ceaeed0fbe.
  • 범위: LCR-001004, P1P3, REV-001/002, 호출 경로와 테스트 assertion. 이번 검토에서 테스트·애플리케이션은 실행하지 않는다. 기존 실행 성공 기록과 이번 정적 검토 판정은 구분한다.
검토 정적 판정 근거
요구사항 PASS /root/spec_v3: 전체 호출 3곳 역할·성별 전달, 목록 필터 및 생성자 예외, 입장/토큰 발급 전 거절, 채널 소유자 repository assertion까지 LCR-001~004 구현 확인.
보안 경계 PASS /root/security_v3: LiveRoomService.kt:986~995 검사 뒤 :1001/:1009/:1016 토큰 생성. 기존 존재·양방향 차단 검사 및 /enter의 결제 전 차단 유지.
코드 품질 PASS /root/quality_v3: 모든 호출부 인자 전달, WHERE 필터 후 페이지네이션, 내부 기본값 및 공개 API/DB 스키마 유지.
테스트 소스 PASS /root/tests_v3: LiveRoomServiceTest.kt:180326 제한/허용/우선순위/무호출 assertion, :368 세 토큰 응답 및 호출 횟수, 채널 repository 테스트 :244266 실제 소유자 방 ID assertion 확인. 실행 QA 판정은 아님.
문서·주변 정책 PASS /root/context_v3: Member.canEnter 및 기존 채널 조건과 일치. 이전 FAIL/미착수는 보존된 이력이며 후속 완료 기록으로 해소됨.

위 판정은 명시된 HEAD와 소스 diff 조합에 한정한다.

요구사항 대조:

  • LCR-001: 홈 추천·라이브·온에어의 역할/유효 성별 전달과 조회 필터 일치. 생성자 예외와 NONE/null 정책 유지.
  • LCR-002: 채널 조회자의 실제 CREATOR 역할 판정 및 생성자 예외 일치. REV-002의 소유자 H2 테스트 추가 확인.
  • LCR-003: /enter는 결제·상태 변경 전, /info는 모든 토큰 생성 전에 동일 제한 검사. 예외 key·우선순위·생성자 예외·Member.canEnter 재사용 일치. REV-001 해소 확인.
  • LCR-004: 허용 사용자·생성자·인증 성별 우선·Gender.NONE 회귀 assertion 존재. 공개 DTO/DB 스키마 및 기존 제한 조건 유지.

최종 정적 판정: PASS. 문서에 명시된 Phase 1~3 구현 및 후속 두 항목의 누락·스펙 위반은 발견하지 못했다. 새 수정 Task로 전환할 확정 항목은 없다. 코드·테스트는 변경하지 않았으며 이 절만 누적했다. 사용자 요청에 따라 테스트와 Gradle 작업을 재실행하지 않고 문서·소스·diff를 대조했다. 전체 자동 테스트 성공은 사용자 확인 및 기존 문서 기록으로 구분하며, 이번에 HTTP/RTC 실행 또는 과거 RED→GREEN을 재검증했다고 주장하지 않는다.