Files
T

11 KiB

라이브 크리에이터 입장 제한 PRD

문서 정보

항목 내용
문서 상태 Phase 1~3 구현 및 검증 완료
작성일 2026-09-17
최종 수정일 2026-09-17
대상 제품 라이브 방 목록 노출 및 입장 제한
작성자·결정권자 Sisyphus / 사용자
관련 API Contract 기존 API 응답 스키마 변경 없음
관련 구현 계획 docs/20260917_라이브_크리에이터_입장제한/plan-task.md
관련 review reviews/현재변경사항-review.md (REV-001, REV-002)

1. Overview

라이브 방 생성자가 isAvailableJoinCreator = false로 설정한 방은 다른 크리에이터 계정에게 노출되거나 입장 가능하면 안 된다. 또한 genderRestriction으로 입장 가능 성별이 제한된 방은 조회 단계에서도 입장 가능한 사용자에게만 노출돼야 한다. 기존 /live/room 계열 조회는 대부분 이 정책을 적용하지만, v2 홈 추천/온에어 라이브와 일부 크리에이터 채널 라이브 경로에서 정책 누락 가능성이 확인됐다. 후속 리뷰에서 /live/room/info/{id}가 같은 제한을 확인하지 않고 RTC/RTM 토큰을 발급하는 경로도 확인됐다.

2. Problem Statement

  • v2 홈 추천/온에어 라이브 조회는 findLiveRecommendations()에서 조회자의 크리에이터 여부와 유효 성별을 받지 않아 isAvailableJoinCreator = false인 방도 크리에이터에게 노출될 수 있고, 성별 제한 방도 입장 불가능한 사용자에게 노출될 수 있다.
  • v2 크리에이터 채널 라이브 탭은 조회자가 크리에이터인지가 아니라 조회자가 해당 채널 주인인지로만 isViewerCreator를 계산해, 다른 크리에이터에게 제한 방이 노출될 수 있다.
  • /live/room/enter는 성인, 비공개, 차단, 강퇴, 성별, 정원, 결제 조건은 확인하지만 크리에이터 입장 제한을 최종 차단하지 않는다.
  • /live/room/info/{id}는 방 정보와 상호 차단만 확인한 뒤 RTC/RTM 토큰을 생성하므로 /enter에서 거절된 사용자도 토큰 발급을 요청할 수 있다.

문제를 해결했다는 판단은 다른 크리에이터가 isAvailableJoinCreator = false 방을 리스트에서 보지 못하고, 성별 제한에 맞지 않는 사용자가 제한 방을 리스트에서 보지 못하며, 직접 enter 요청을 보내도 차단되는 것으로 한다.

3. Goals

  • 다른 크리에이터 계정은 isAvailableJoinCreator = false 라이브 방을 문제 의심 경로에서 볼 수 없다.
  • 다른 크리에이터 계정은 isAvailableJoinCreator = false 라이브 방에 직접 입장할 수 없다.
  • 입장 가능 성별이 제한된 라이브 방은 성별이 맞는 사용자 또는 방 생성자 본인에게만 조회된다.
  • 입장 가능 성별이 제한된 라이브 방은 성별이 맞는 사용자 또는 방 생성자 본인만 입장할 수 있다.
  • 방을 만든 크리에이터 본인은 예외로 계속 조회 및 입장 가능하다.
  • 제한 사용자는 /live/room/info/{id}에서 RTC/RTM/v2v 토큰을 발급받을 수 없다.
  • 기존 응답 DTO와 공개 API 스키마는 변경하지 않는다.

4. Non-Goals

  • isAvailableJoinCreator 필드명, 의미, DB 스키마 변경은 하지 않는다.
  • 일반 유저, 관리자, 봇, 에이전트의 기존 노출/입장 정책은 변경하지 않는다.
  • 기존 성인/성별/차단/강퇴/비공개/결제 정책은 재설계하지 않는다.
  • Gender.NONE 사용자의 기존 정책은 변경하지 않는다. 기존 Member.canEnter()와 리스트 조건처럼 성별 미설정 사용자는 성별 제한을 통과한다.
  • 새 API endpoint나 새 응답 필드는 만들지 않는다.

5. Target Users and Permissions

사용자 목표 정책
방 생성 크리에이터 본인이 만든 방 조회 및 입장 isAvailableJoinCreator = false여도 허용
다른 크리에이터 크리에이터 입장 제한 방 접근 방지 isAvailableJoinCreator = false면 목록 미노출 및 입장 차단
일반 유저 기존 라이브 조회 및 입장 genderRestriction에 맞으면 허용, Gender.NONE은 기존처럼 허용

6. 핵심 사용자 흐름

  1. 일반 유저 또는 방 생성자가 isAvailableJoinCreator = false 방을 조회하면 기존 정책에 따라 표시된다.
  2. 성별 제한에 맞지 않는 사용자가 genderRestriction 제한 방을 v2 홈 추천/온에어 라이브에서 조회하면 표시되지 않는다.
  3. 다른 크리에이터가 같은 방을 v2 홈 추천/온에어 라이브 또는 크리에이터 채널 라이브 경로에서 조회하면 표시되지 않는다.
  4. 성별 제한에 맞지 않는 사용자가 방 ID를 알고 /live/room/enter를 호출하면 입장이 거부된다.
  5. 다른 크리에이터가 방 ID를 알고 /live/room/enter를 호출하면 입장이 거부된다.
  6. 방 생성 크리에이터가 본인 방에 입장하면 기존처럼 허용된다.
  7. /enter에서 거절되는 다른 크리에이터 또는 성별 불일치 사용자가 /live/room/info/{id}를 호출하면 토큰 생성 전에 같은 정책으로 거절된다.
  8. 방 생성자, 성별이 맞는 일반 사용자, 크리에이터 입장이 허용된 방의 다른 크리에이터는 기존처럼 방 정보와 토큰을 받는다.

7. 기능 요구사항

ID 상태 요구사항 수용 기준 계약/Goal 연결
LCR-001 확정 v2 홈 추천/온에어 라이브 조회에서 다른 크리에이터에게 isAvailableJoinCreator = false 방을 숨기고, 성별 제한에 맞지 않는 사용자에게 genderRestriction 제한 방을 숨긴다. HomeRecommendationQueryService.findLiveRecommendations() 호출 경로가 조회자 크리에이터 여부와 유효 성별을 전달한다. repository는 liveRoom.isAvailableJoinCreator.isTrue.or(liveRoom.member.id.eq(memberId))와 Gender.MALE -> ALL/MALE_ONLY, Gender.FEMALE -> ALL/FEMALE_ONLY, Gender.NONE/null -> 필터 없음 조건을 적용한다. P1-T1
LCR-002 확정 v2 크리에이터 채널 라이브 탭에서 다른 크리에이터에게 제한 방을 숨긴다. CreatorChannelLiveQueryService가 viewer.role == MemberRole.CREATOR 기준으로 조회자 크리에이터 여부를 전달한다. 방 생성자 본인은 예외다. P1-T2
LCR-003 확정 /live/room/enter와 /live/room/info/{id}에서 다른 크리에이터의 제한 방 입장·토큰 발급과 성별 제한에 맞지 않는 접근을 차단한다. 다른 크리에이터 제한은 live.room.not_found, 성별 제한은 live.room.gender_restricted로 결제·입장 상태 변경 또는 RTC/RTM/v2v 토큰 생성 전에 거절한다. 생성자는 예외이며 성별 판정은 Member.canEnter()를 재사용한다. P2-T1, P3-T1
LCR-004 확정 기존 정상 경로는 유지한다. 일반 유저와 방 생성자 본인의 조회/입장 동작은 유지되고 기존 테스트 또는 신규 회귀 테스트로 확인된다. P2-GATE

8. API 계약

  • 변경되는 공개 request/response 필드는 없다.
  • /live/room/enter는 기존 오류 envelope를 사용한다.
  • /live/room/info/{id}도 기존 오류 envelope와 message key를 재사용하며 응답 필드는 변경하지 않는다.
  • 신규 message key 추가 여부는 구현 단계에서 기존 live.room.gender_restricted, common.error.invalid_request, live.room.not_found 패턴을 확인해 결정한다. 새 key가 필요하면 메시지 리소스와 테스트를 함께 갱신한다.

9. 보안과 데이터 취급

  • 숨김 정책은 클라이언트 표시만으로 끝내지 않고 서버 입장 경계에서 한 번 더 차단한다.
  • 제한 방 존재 여부를 다른 크리에이터에게 과도하게 노출하지 않는 오류 메시지를 우선한다.
  • 민감정보, 결제 정보, password, token은 로그나 테스트 fixture에 기록하지 않는다.
  • 제한 검사는 RTC, RTM, v2v 토큰 생성 호출보다 먼저 수행한다.

10. 성공 기준

  • 다른 크리에이터는 isAvailableJoinCreator = false 방을 v2 홈 추천/온에어 라이브에서 받지 않는다. (LCR-001)
  • 성별 제한에 맞지 않는 사용자는 genderRestriction 제한 방을 v2 홈 추천/온에어 라이브에서 받지 않는다. (LCR-001)
  • 다른 크리에이터는 isAvailableJoinCreator = false 방을 v2 크리에이터 채널 라이브 탭에서 받지 않는다. (LCR-002)
  • 다른 크리에이터는 isAvailableJoinCreator = false 방에 직접 입장할 수 없다. (LCR-003)
  • 성별 제한에 맞지 않는 사용자는 제한 방에 직접 입장할 수 없다. (LCR-003)
  • 방 생성 크리에이터 본인은 본인 방을 조회하고 입장할 수 있다. (LCR-001~LCR-003)
  • 공개 API 스키마 변경 없이 focused test와 영향 범위 회귀가 통과한다.
  • 다른 크리에이터와 성별 불일치 사용자는 /live/room/info/{id}에서 토큰 생성 전에 거절되고 토큰 생성기가 호출되지 않는다. (LCR-003)
  • 방 생성자, 성별이 맞는 일반 사용자, 크리에이터 입장이 허용된 방의 다른 크리에이터, Gender.NONE 사용자는 기존처럼 방 정보와 토큰을 받는다. (LCR-003, LCR-004)
  • 채널 소유자 본인은 isAvailableJoinCreator = false인 현재 방을 repository 조회에서 받는다. (LCR-002, LCR-004)

11. Decision Log

일시 결정 근거
2026-09-17 isAvailableJoinCreator = false는 다른 크리에이터만 제한하고 방 생성자 본인은 예외로 둔다. 기존 QueryDSL 조건들이 liveRoom.member.id.eq(viewerId) 예외를 두는 패턴과 사용자 선택 A
2026-09-17 이 작업은 문서가 필요한 구현 작업으로 분류한다. 저장소 AGENTS.md와 docs/agent-guides/작업절차.md가 모든 구현 작업 전 PRD와 plan-task를 요구
2026-09-17 v2 홈 추천/온에어 라이브에도 기존 조회 경로와 같은 genderRestriction 필터를 적용한다. /live/room, 팔로잉, 크리에이터 채널 조회 경로가 이미 성별 조건을 조회 단계에서 적용하고 있으며 사용자가 문서 반영을 요청
2026-09-17 /live/room/enter의 성별 제한은 기존 Member.canEnter() 정책을 유지한다. 현재 LiveRoomService.enterLive()가 이미 room.member.id != member.id && !member.canEnter(room.genderRestriction)을 차단하고, Gender.NONE은 canEnter()에서 허용됨
2026-09-17 /live/room/info/{id}에서도 /enter와 같은 크리에이터·성별 제한을 토큰 생성 전에 적용한다. REV-001에서 /enter 거절 후에도 RTC/RTM/v2v 토큰 생성 경로가 열려 있음을 코드로 확인
2026-09-17 채널 소유자의 제한 방 조회는 production 변경 없이 H2 repository 회귀 테스트로 고정한다. REV-002와 기존 creatorJoinLiveCondition()의 소유자 예외

12. 열린 질문

  • 없음. 구현 중 기존 메시지 key 재사용이 부적절하다고 확인되면 plan-task 범위를 먼저 갱신한다.