Files
sodalive-ios/docs/20260914_크리에이터_DM_리스너_선택/prd.md
T

16 KiB
Raw Blame History

크리에이터 DM 리스너 선택 PRD

문서 정보

항목 내용
문서 상태 검토 중
작성일 2026-09-14
최종 수정일 2026-09-14
대상 제품 크리에이터가 리스너에게 먼저 DM 보내기
작성자·결정권자 제품 결정: 요청자 / 문서 작성: Sisyphus
관련 API Contract 이 문서 §11
관련 구현 계획 docs/20260914_크리에이터_DM_리스너_선택/plan-task.md
관련 review 없음

요구사항 상태

상태 의미 구현 처리
확정 제품·기술 결정이 완료되어 구현 기준으로 사용 plan-task.md의 Task와 완료 증거로 추적
미결 제품·UX·운영 결정이 더 필요함 구현 전 질문 또는 API 확인 필요
제외 현재 릴리스에서 구현하지 않기로 결정 Decision Log에 기록

1. Overview

현재 리스너는 크리에이터 채널에서 크리에이터에게 바로 DM을 시작할 수 있지만, 크리에이터가 리스너에게 먼저 DM을 시작하는 진입점은 없다. 이 기능은 메인 대화 탭에서 크리에이터가 팔로우 리스트 또는 닉네임 검색으로 리스너를 선택하고, 확인 팝업 후 기존 유저-크리에이터 DM 방 생성 API로 DM 방에 진입하게 한다.

2. Problem Statement

현재 사용자는 다음 문제를 겪는다.

  • 크리에이터가 리스너에게 선제적으로 1:1 DM을 시작할 수 없다.
  • 기존 DM 생성 흐름은 크리에이터 채널에서 리스너가 크리에이터에게 보내는 방향을 기준으로 구성되어 있다.
  • 크리에이터가 리스너를 찾기 위해 별도 화면이나 외부 수단을 사용해야 한다.

문제를 해결했다는 판단은 크리에이터 계정이 메인 대화 탭에서 리스너를 선택해 기존 DM 방 생성 API를 호출하고, 생성된 DM 방으로 진입하는 것으로 한다.

3. Goals

3.1 제품 목표

  • 크리에이터가 메인 대화 탭에서 리스너에게 먼저 DM을 시작할 수 있다.
  • 초기 화면은 기존 팔로우 전체 리스트 페이지와 동일한 API를 사용한다.
  • 검색은 2글자 이상일 때만 GET /member/search를 500ms debounce 후 호출한다.
  • 선택한 유저에게 메시지를 보낼지 확인하는 다이얼로그를 보여준다.
  • 보내기 시 기존 유저-크리에이터 DM 방 생성 API를 재사용한다.

3.2 UX 목표

  • 메인 대화 탭 우측 하단에 홈의 플로팅 + 버튼과 같은 진입점을 제공한다.
  • 새 화면은 Figma 2372:23496 기준의 검색 바, 팔로우 섹션, 유저 리스트 구조를 따른다.
  • 확인 팝업은 Figma 2372:23521 기준 문구와 V2 공통 SodaV2ActionModal을 재사용한다.
  • 검색 결과가 없을 때 화면 중앙에 사용자가 없어요.\n다른 이름으로 다시 검색해 주세요.를 다국어 문구로 표시한다.

4. Non-Goals

  • 새 채팅 프로토콜, WebSocket 전송 방식, 메시지 본문 전송 기능은 만들지 않는다.
  • 기존 채팅방 UI(UserCreatorChatRoomView)의 메시지 표시·전송 UX를 변경하지 않는다.
  • 팔로우 리스트 API의 서버 계약을 새로 정의하지 않는다. 기존 API를 재사용한다.
  • 검색 API의 서버 응답 필드, 필터링 정책, 차단 유저 제외 정책을 클라이언트에서 추정하지 않는다.
  • 새 공통 모달 컴포넌트를 만들지 않는다.

5. Target Users and Permissions

사용자 목표 주요 작업 사용 환경
크리에이터 리스너에게 먼저 DM 시작 대화 탭 진입, 팔로우 리스트 조회, 검색, 유저 선택, 확인 후 DM 방 진입 iOS 앱
리스너 크리에이터가 시작한 DM 수신 기존 DM 방에서 메시지 확인 iOS 앱

5.2 권한

  • 인증 주체: 로그인된 사용자.
  • 허용 역할: MemberRole.CREATOR인 크리에이터.
  • 거부 조건: 비로그인 또는 크리에이터가 아닌 사용자는 메인 대화 탭의 신규 + 진입점을 보지 않는다.
  • 리소스 소유권: 방 생성 권한과 recipient 검증은 서버의 /api/v2/user-creator-chat/rooms/create 정책을 따른다.

6. 핵심 사용자 흐름

  1. 크리에이터가 메인 대화 탭에 진입한다.
  2. 우측 하단 + 버튼을 터치한다.
  3. 새 유저 선택 화면이 열린다.
  4. 초기 상태에서 기존 팔로우 전체 리스트 API의 결과를 보여준다.
  5. 검색창에 2글자 이상 입력하면 500ms 동안 추가 입력이 멈춘 뒤 GET /member/search?nickname={query}를 호출한다.
  6. 검색 결과가 없으면 중앙에 empty 문구를 표시한다.
  7. 유저를 터치하면 메시지 보내기 확인 팝업을 표시한다.
  8. 보내기를 터치하면 기존 DM 방 생성 API를 호출한다.
  9. 성공 시 반환된 roomIdAppStep.userCreatorChatRoom(roomId:)에 진입한다.

7. 정보 구조와 라우팅

MainView / MainTab.chat
  MainChatView
    + floating action button
    -> AppStep.userCreatorChatRecipientSearch
       UserCreatorChatRecipientSearchView
       -> AppStep.userCreatorChatRoom(roomId: Int)
  • 새 라우트 이름은 구현 시 코드 스타일에 맞춰 조정할 수 있으나, 역할은 “크리에이터가 DM을 시작할 리스너 선택 화면” 하나로 제한한다.
  • 기존 AppStep.userCreatorChatCreator(creatorId:)는 리스너가 크리에이터 채널에서 DM을 시작하는 흐름으로 유지한다.
  • 새 흐름은 유저 선택 후 recipientId 기반으로 방을 생성한다.

8. 기능 요구사항

8.1 진입점

ID 상태 요구사항 수용 기준 계약/Goal 연결
CDM-ENTRY-001 확정 메인 대화 탭 우측 하단에 홈처럼 + 플로팅 버튼을 추가한다. 크리에이터 계정에서만 보이고, 탭 시 새 리스너 선택 화면으로 이동한다. P1-T1
CDM-ENTRY-002 확정 비크리에이터와 비로그인 사용자는 신규 + 버튼을 보지 않는다. MemberRole.CREATOR가 아니면 버튼이 렌더링되지 않는다. P1-T1

8.2 리스너 선택 화면

ID 상태 요구사항 수용 기준 계약/Goal 연결
CDM-LIST-001 확정 새 화면은 Figma 2372:23496 구조를 따른다. 뒤로가기, 검색 바, 섹션 타이틀, 리스트가 검은 배경 위에 배치된다. P2-T1
CDM-LIST-002 확정 초기 진입 시 기존 팔로우 전체 리스트 페이지와 동일한 API를 호출한다. FollowCreatorRepository.getFollowedCreatorAllList(page:size:)와 같은 endpoint·pagination 정책을 사용한다. P2-T2
CDM-LIST-003 확정 초기 리스트 아이템 터치 시 확인 팝업을 보여준다. 터치만으로 방 생성 API가 바로 호출되지 않는다. P2-T4

8.3 검색

ID 상태 요구사항 수용 기준 계약/Goal 연결
CDM-SEARCH-001 확정 검색어가 2글자 미만이면 검색 API를 호출하지 않는다. 0~1글자 입력 중 network 요청 0회, 화면은 초기 팔로우 리스트 기준을 유지한다. P2-T3
CDM-SEARCH-002 확정 검색어가 2글자 이상이면 500ms debounce 후 GET /member/search를 호출한다. 연속 입력 중에는 마지막 입력 후 500ms가 지나기 전 요청하지 않는다. P2-T3
CDM-SEARCH-003 확정 검색 결과가 없을 때 중앙 empty 문구를 표시한다. 사용자가 없어요.\n다른 이름으로 다시 검색해 주세요.가 다국어 키로 표시된다. P2-T3

8.4 확인 팝업과 방 생성

ID 상태 요구사항 수용 기준 계약/Goal 연결
CDM-MODAL-001 확정 유저 터치 시 V2 내부 공통 팝업을 재사용한다. SodaV2ActionModal을 사용하고 새 모달 컴포넌트를 만들지 않는다. P2-T4
CDM-MODAL-002 확정 팝업 문구는 메시지 보내기, {{사용자이름}}에게 메시지를 보낼까요?, 취소, 보내기를 다국어 처리한다. 모든 문구가 I18n 키를 통해 참조된다. P2-T4
CDM-CREATE-001 확정 보내기 시 기존 유저-크리에이터 DM 방 생성 API를 호출한다. POST /api/v2/user-creator-chat/rooms/create 성공 시 roomId를 받아 DM 방으로 진입한다. P2-T5
CDM-CREATE-002 확정 크리에이터가 리스너에게 보내는 흐름은 선택한 유저 ID를 recipientId로 보낸다. request body가 recipientIdcreatorId를 동시에 서로 다른 값으로 보내지 않는다. P2-T5

9. UI/UX Expectations

9.1 디자인 기준

  • 신규 화면 Figma: 2372:23496 (chat_src_001, 402×874)
  • 확인 팝업 Figma: 2372:23521 (Frame 1707482932, 340×207)
  • 검색 안내 문구: Figma 기준 팬 이름을 입력하세요
  • 초기 섹션 타이틀: Figma 기준 팔로워
  • 리스트 아이템: 원형 프로필 이미지와 닉네임 텍스트 구조를 사용한다.

9.2 화면 상태

  • loading: 초기 팔로우 리스트와 검색 요청 중 기존 프로젝트 loading 패턴을 따른다.
  • empty: 검색 결과 0건일 때 중앙 안내 문구 표시.
  • error: 기존 toast 또는 공통 오류 메시지 정책을 따른다.
  • success: 방 생성 성공 시 별도 성공 toast 없이 채팅방으로 이동한다.

10. 다국어 문구

용도 한국어 문구 비고
검색 안내 문구 팬 이름을 입력하세요 Figma 기준
초기 섹션 타이틀 팔로워 Figma 기준
검색 empty 1행 사용자가 없어요. 줄바꿈 포함
검색 empty 2행 다른 이름으로 다시 검색해 주세요. 줄바꿈 포함
팝업 제목 메시지 보내기 Figma 기준
팝업 본문 {{사용자이름}}에게 메시지를 보낼까요? 닉네임 치환
팝업 취소 취소 기존 I18n.Common.cancel 재사용 가능
팝업 보내기 보내기 새 키 또는 기존 동일 의미 키 재사용

11. API 계약

11.1 초기 팔로우 전체 리스트

항목 내용
기존 호출 지점 FollowCreatorViewModel.getFollowedCreatorAllList()
Repository FollowCreatorRepository.getFollowedCreatorAllList(page:size:)
Method GET
Path /live/recommend/following/channel/all/list
Query page, size, timezone
Response decode ApiResponse<GetCreatorFollowingAllListResponse>
Item model GetCreatorFollowingAllListItem(creatorId, nickname, profileImageUrl, isFollow, isNotify)

11.2 유저 검색

항목 내용
기존 API UserApi.searchUser(nickname:)
Repository UserRepository.searchUser(nickname:)
Method GET
Path /member/search
Query nickname
호출 조건 검색어 trim 후 2글자 이상, 500ms debounce 완료

11.3 DM 방 생성

항목 내용
기존 API UserCreatorChatApi.createRoom
Repository UserCreatorChatRepository.createRoom(...)
Method POST
Path /api/v2/user-creator-chat/rooms/create
기존 iOS request UserCreatorCreateRoomRequest(creatorId: Int)
신규 요구 request recipientId: Int?, creatorId: Int? 중 하나만 유효하게 전송
성공 response UserCreatorCreateRoomResponse(roomId: Int)

서버 request 기준:

data class CreateUserCreatorChatRoomRequest(
    val recipientId: Long? = null,
    val creatorId: Long? = null
)
  • 리스너가 크리에이터 채널에서 DM 시작: 기존처럼 creatorId 전송.
  • 크리에이터가 리스너에게 DM 시작: 선택한 유저의 ID를 recipientId로 전송.
  • recipientIdcreatorId가 서로 다른 값으로 동시에 전송되는 상태는 만들지 않는다.

12. 보안과 데이터 취급

  • 인증 header는 기존 Moya target의 Authorization: Bearer {token} 정책을 따른다.
  • 검색어, 닉네임, member ID 외 민감정보를 로그에 남기지 않는다.
  • 방 생성 실패 시 서버 message 또는 I18n.Common.commonError를 사용한다.

13. 성능과 품질 요구사항

  • 검색 debounce 시간은 500ms로 고정한다.
  • 2글자 미만 검색어는 network 요청을 보내지 않는다.
  • 검색어가 바뀌면 이전 pending debounce 작업은 취소한다.
  • pagination은 기존 팔로우 전체 리스트의 page = 1, size = 10, isLast 정책을 따른다.
  • 신규 dependency를 추가하지 않는다.

14. 성공 기준

14.1 기능 수용 기준

  • 크리에이터 계정의 메인 대화 탭 우측 하단에 + 버튼이 표시된다.
  • + 버튼을 누르면 Figma 기준 리스너 선택 화면으로 이동한다.
  • 화면 최초 진입 시 기존 팔로우 전체 리스트 API가 호출된다.
  • 검색어 2글자 미만에서는 /member/search 요청이 없다.
  • 검색어 2글자 이상에서 마지막 입력 500ms 후 /member/search?nickname= 요청이 1회 발생한다.
  • 검색 결과가 없으면 다국어 empty 문구가 중앙에 표시된다.
  • 유저 터치 시 SodaV2ActionModal 확인 팝업이 표시된다.
  • 보내기 터치 시 recipientId 기반으로 기존 DM 방 생성 API가 호출되고, 성공 시 DM 방으로 이동한다.

14.2 추적성 완료 기준

  • 모든 확정 요구사항이 plan-task.md의 Goal에 연결된다.
  • 모든 신규 문구가 다국어 키에 연결된다.
  • 기존 크리에이터 채널 DM 시작 흐름이 회귀하지 않는다.

15. Open Questions

ID 상태 결정 필요 사항 현재 권고 결정 주체 결정 기한/시점 영향 Goal
없음 확정 인터뷰로 초기 리스트 API 기준 확인 완료 기존 팔로우 전체 리스트 API 사용 요청자 2026-09-14 P2-T2

16. 요구사항 추적표

요구사항 범위 API Contract 계획 Phase Goal 자동 검증 수동 검증
CDM-ENTRY-001~002 해당 없음 1 P1-T1 빌드 크리에이터/비크리에이터 버튼 노출 확인
CDM-LIST-001~003 §11.1 2 P2-T1, P2-T2, P2-T4 빌드 초기 목록과 팝업 확인
CDM-SEARCH-001~003 §11.2 2 P2-T3 빌드 2글자/500ms/empty 확인
CDM-MODAL-001~002, CDM-CREATE-001~002 §11.3 2 P2-T4, P2-T5 빌드 request payload와 방 진입 확인

17. Decision Log

날짜 ID 상태 결정 근거 영향 요구사항·계약·Goal
2026-09-14 DEC-001 확정 코드 구현 없이 PRD와 plan-task.md만 작성한다. 사용자 직접 지시 전체
2026-09-14 DEC-002 확정 새 화면 초기 목록은 기존 팔로우 전체 리스트 페이지와 동일한 API를 사용한다. 사용자 답변 B CDM-LIST-002, §11.1, P2-T2
2026-09-14 DEC-003 확정 크리에이터가 리스너에게 보내는 새 흐름은 recipientId를 사용하고, 기존 크리에이터 채널 흐름은 creatorId를 유지한다. 서버 request contract CDM-CREATE-002, §11.3, P2-T5

18. 변경 관리

요구사항 변경 시 다음을 확인한다.

  • Decision Log에 변경 이유와 날짜를 기록했다.
  • 관련 요구사항 상태·본문·수용 기준을 갱신했다.
  • API request/response/error 계약을 갱신했다.
  • plan-task.md의 범위·Files·Interfaces·체크박스·완료 증거를 코드 변경 전에 갱신했다.
  • 기존 Progress·review·검증 기록을 삭제하거나 덮어쓰지 않았다.