Files

14 KiB

PRD: FanTalk 상세 / 답글쓰기

1. Overview

크리에이터 채널 FanTalk 탭에서 본인 채널의 FanTalk item을 터치하면 FanTalk 상세 화면으로 진입하고, 기존 FanTalk 답글 쓰기 API로 크리에이터 답글을 작성할 수 있게 한다.


2. Problem

  • 현재 v2 FanTalk 탭은 목록 item에 표시되는 FanTalk 원문과 최신 크리에이터 답글을 보여주지만, item 터치로 상세 화면에 진입하는 흐름이 없다.
  • 본인 채널의 크리에이터는 FanTalk 원문을 상세히 보고 같은 화면에서 답글을 작성해야 한다.
  • FanTalk 상세 UI는 커뮤니티 답글 화면과 동일해야 하므로, 기존 구현과 Figma 기준을 문서로 고정해야 한다.
  • 답글 입력값 유무에 따른 send button 활성/비활성 상태가 명확히 정의되어야 한다.
  • 구현 전에 V2 패키지 하위에서 재사용 가능한 위젯/화면 요소 후보를 확인해 중복 구현을 줄여야 한다.

3. Goals

  • FanTalk 탭의 FanTalk item 터치 시 FanTalk 상세 화면으로 진입하는 요구사항을 정의한다.
  • FanTalk 상세 진입은 본인 채널(currentHeader?.isOwner == true)에서만 허용한다.
  • FanTalk 상세 UI는 CreatorChannelCommunityReplyActivity와 동일한 구조를 따른다.
  • Figma 답글 없음 669:40462, 답글 있음 669:40468 기준으로 FanTalk 상세/답글쓰기 UI 요구사항을 정의한다.
  • FanTalk는 별도의 상세 조회 API가 없으므로 FanTalk item 터치 시 목록의 data model을 통째로 상세 화면에 전달한다.
  • FanTalk 상세에서는 크리에이터 답글을 최대 1개만 표시/관리한다.
  • 답글 작성은 기존 FanTalk 답글 쓰기 API를 그대로 재사용한다.
    • 기존 경로: ExplorerRepository.writeCheers(parentCheersId = fanTalkId, creatorId = creatorId, content = content, token = token)
    • v2 wrapper 추가 시 CreatorChannelRepository.writeFanTalkReply(fanTalkId, creatorId, content, token)처럼 레거시 API를 감싸는 최소 wrapper만 둔다.
  • 기존 답글이 있는 상태에서 신규 답글을 쓰려고 하면 안내 모달을 표시하고, 확인 시 신규 작성 API가 아니라 답글 수정 API로 기존 답글을 대체한다.
  • 입력값이 trim() 기준 비어 있으면 send button을 비활성화한다.
  • 입력값이 trim() 기준 비어 있지 않으면 send button을 활성화한다.
  • 재사용 가능한 V2 위젯/화면 요소 후보를 계획 문서에 기록한다.

4. Non-Goals

  • 레거시 FanTalk 화면 파일을 직접 수정하지 않는다.
  • 서버 API schema나 endpoint를 새로 정의하지 않는다.
  • 별도 FanTalk 상세 조회 API를 새로 가정하지 않는다.
  • FanTalk 원글 작성 화면은 이번 범위에서 수정하지 않는다.
  • FanTalk 원글 수정/삭제 UX를 새로 설계하지 않는다.
  • 일반 사용자가 타인 채널에서 FanTalk 상세에 진입하는 흐름은 이번 범위에서 제공하지 않는다.
  • 커뮤니티 상세/답글 화면의 기존 동작을 변경하지 않는다.
  • Figma에 없는 새로운 reaction row, title text, marketing성 안내 문구를 추가하지 않는다.

5. Target Users

  • 본인 채널의 FanTalk에 답글을 작성하려는 크리에이터.
  • kr.co.vividnext.sodalive.v2 하위 크리에이터 채널 FanTalk 기능을 구현/유지보수하는 Android 개발자.

6. User Stories

  • 크리에이터는 내 채널의 FanTalk item을 터치해 상세 화면으로 들어가고 싶다.
  • 크리에이터는 FanTalk 상세에서 팬이 남긴 원문, 작성자 프로필, 닉네임, 작성 시간을 확인하고 싶다.
  • 크리에이터는 이미 작성된 답글이 있으면 FanTalk 상세에서 확인하고 싶다.
  • 크리에이터는 답글이 없는 FanTalk 상세에서도 바로 답글을 입력하고 싶다.
  • 크리에이터는 답글 input field에 글을 입력하면 send button이 활성화되기를 기대한다.
  • 크리에이터는 답글 작성 성공 후 FanTalk 목록과 홈 요약이 최신 상태로 갱신되기를 기대한다.
  • 일반 사용자는 타인 채널에서 FanTalk item을 터치해 상세 화면으로 들어가지 못해야 한다.

7. Core Features

F1. FanTalk 상세 진입

본인 채널의 FanTalk item 터치 시 상세 화면으로 이동한다.

Requirements

  • CreatorChannelFanTalkAdapter의 item root 또는 FanTalk 본문 영역 터치를 상세 진입점으로 사용한다.
  • 상세 진입은 CreatorChannelActivitycurrentHeader?.isOwner == true인 경우에만 허용한다.
  • 본인 채널이 아니면 item 터치 callback을 연결하지 않거나, Activity에서 안전하게 무시한다.
  • 상세 화면에는 목록에서 사용 중인 FanTalk data model을 통째로 전달한다.
  • data model 전달 방식은 Parcelable을 우선 사용하고, 기존 model에 직접 적용하기 어렵다면 FanTalk 상세 전용 payload model을 만들어 원본 item 데이터를 한 번에 담아 전달한다.
  • 개별 primitive extra로 fanTalkId, writerNickname, content 등을 나누어 전달하지 않는다.
  • fanTalkId <= 0L 또는 creatorId <= 0L이면 상세 화면을 열지 않는다.
  • 로그인 토큰이 없으면 기존 크리에이터 채널 로그인 이동 정책을 따른다.

Edge Cases

  • 목록 refresh 중 stale item을 터치해 유효하지 않은 ID가 전달되면 아무 동작도 하지 않는다.
  • 본인 채널이 아닌 상태에서 callback이 호출되더라도 상세 화면을 열지 않는다.

F2. FanTalk 상세 UI

Figma와 커뮤니티 답글 화면 기준으로 FanTalk 상세 화면을 표시한다.

Requirements

  • UI 구조는 app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/detail/reply/CreatorChannelCommunityReplyActivity.kt와 동일하게 한다.
  • layout 기준은 activity_creator_channel_community_reply.xml을 따른다.
  • 상단 title-bar에는 뒤로가기 icon만 표시하고 별도 title text는 표시하지 않는다.
  • 상단에는 부모 FanTalk 원문을 표시한다.
    • 프로필 이미지 42dp
    • 닉네임
    • 작성 시간
    • 본문
    • 본인 채널 관리용 더보기 button
  • 답글이 없으면(Figma 669:40462) 부모 FanTalk만 표시하고 답글 card 영역은 비운다.
  • 답글이 있으면(Figma 669:40468) 부모 FanTalk 아래에 크리에이터 답글 card 1개만 표시한다.
  • 답글 card는 gray_900 배경, round corner, profile 20dp, 닉네임, 시간, 본문, 더보기 button 구조를 따른다.
  • 하단 input bar는 화면 하단에 고정하고 키보드 표시 시 키보드 위로 함께 올라오게 한다.

Edge Cases

  • 전달받은 답글 목록이 비어 있으면 empty message를 추가하지 않는다.
  • 답글은 1개만 가능하므로 별도 pagination/API를 사용하지 않는다.
  • 서버 응답 data model에 답글 list가 들어 있더라도 상세에서는 첫 번째 답글만 기존 답글로 취급한다.

F3. FanTalk 답글 작성

기존 FanTalk 답글 쓰기 API를 재사용한다.

Requirements

  • 답글 input placeholder는 기존 커뮤니티 답글 화면과 동일한 문자열을 우선 재사용한다.
  • 입력값 판단은 trim() 기준으로 한다.
  • 입력값이 없으면 send button은 disabled 상태다.
    • button bg: gray_900
    • button icon: ic_new_arrow_up_gray
  • 입력값이 있으면 send button은 enabled 상태다.
    • button bg: soda_400
    • button icon: ic_new_arrow_up_white
  • 답글이 없는 상태에서 send를 누르면 기존 FanTalk 등록 API에 parentCheersId = fanTalkId를 전달해 호출한다.
  • 답글이 있는 상태에서 send를 누르면 기존 답글 대체 안내 모달을 먼저 표시한다.
  • 기존 답글 대체 안내 모달은 기존 답글이 신규 답글로 대체된다는 내용을 포함한다.
    • title: 답글 수정
    • desc: 기존 답글이 신규 답글로 대체됩니다.\n수정하시겠어요?
    • cancel button: 취소
    • confirm button: 확인
  • 기존 답글 대체 안내 모달에서 확인을 누르면 신규 작성 API가 아니라 답글 수정 API를 호출한다.
  • 답글 수정 API는 기존 답글의 fanTalkId를 대상으로 ExplorerRepository.modifyCheers(PutModifyCheersRequest(cheersId = replyFanTalkId, content = ...), token)를 호출하는 v2 wrapper를 사용한다.
  • 전송 content는 앞뒤 공백을 제거한 값을 사용한다.
  • 작성 중에는 중복 전송을 막는다.
  • 작성 또는 수정 성공 시 입력값을 비우고 상세 화면/목록/홈 요약 갱신을 요청한다.
  • 작성 또는 수정 성공 시 키보드를 내리고 input focus를 해제한다.
  • 작성 실패 시 입력값을 유지하고 기존 toast/error 표시 정책을 따른다.

Edge Cases

  • 공백/줄바꿈만 입력하면 API를 호출하지 않는다.
  • 기존 답글이 있는 상태에서 대체 안내 모달을 취소하면 API를 호출하지 않고 입력 상태를 유지한다.
  • 서버 실패 응답의 message가 있으면 해당 message를 우선 표시한다.
  • 답글 작성 성공 후 목록 refresh 결과가 늦게 도착해도 현재 상세 상태를 stale 데이터로 덮지 않는다.

F4. FanTalk 답글 수정/삭제 메뉴

본인 채널 상세에서 답글 관리 메뉴를 제공한다.

Requirements

  • Figma 669:40468처럼 답글 card 우측 더보기 버튼을 표시한다.
  • 메뉴 문구는 수정하기, 삭제하기를 사용한다.
  • popup UI는 커뮤니티 답글 화면의 CreatorChannelCommunityMorePopup 패턴을 우선 검토한다.
  • 삭제 확인은 v2 공통 모달 V2ModalDialog를 사용한다.
  • 기존 FanTalk 수정/삭제 API wrapper가 없으면 ExplorerRepository.modifyCheers(PutModifyCheersRequest(...))를 감싸는 v2 wrapper를 추가한다.
  • 수정 UX는 커뮤니티 답글 화면과 동일하게 하단 input field 수정 모드를 우선한다.
  • 하단 input field에서 기존 답글을 대체하는 흐름도 같은 답글 수정 API를 사용한다.

Edge Cases

  • 기존 답글이 없으면 답글 card 더보기 button을 표시하지 않는다.

8. UX / UI Expectations

  • FanTalk 상세는 커뮤니티 답글 화면과 시각적으로 동일해야 한다.
  • 본인 채널에서만 item 터치 affordance가 느껴져야 한다.
  • 하단 input bar는 화면 하단에 안정적으로 고정되어야 한다.
  • send button 상태는 입력값 변화에 즉시 반응해야 한다.
  • 답글 작성 성공 후 사용자는 목록으로 돌아가지 않아도 작성된 답글 상태를 확인할 수 있어야 한다.
  • Figma 669:40462/669:40468의 검은 배경, gray divider, gray_900 input/card, soda_400 활성 button 색상을 유지한다.

9. Technical Constraints

  • Android XML View/ViewBinding 기반으로 구현한다.
  • 신규 Activity/ViewModel 및 하위 코드는 kr.co.vividnext.sodalive.v2.creator.channel.fantalk 하위에 작성한다.
  • 레거시 FanTalk 코드는 직접 수정하지 않고 기존 repository/API 흐름만 호출한다.
  • 신규 API endpoint를 추가하지 않는다.
  • API 호출은 기존 RxJava3, Koin, ApiResponse<T> 패턴을 따른다.
  • 상대 시간 표시는 기존 UtcRelativeTimeTextFormatter를 재사용한다.
  • 삭제 확인 dialog는 v2 패키지 내부이므로 V2ModalDialog를 사용한다.
  • 기존 답글 대체 안내도 v2 패키지 내부이므로 V2ModalDialog를 사용한다.
  • 신규 문자열은 values, values-en, values-ja에 추가하거나 기존 문자열을 재사용한다.
  • 커뮤니티 답글 화면 리소스를 직접 재사용할 경우 resource id/name과 ViewBinding 충돌을 피한다.

10. Metrics

  • 별도 분석 이벤트 추가는 이번 범위에서 정의하지 않는다.
  • 기능 성공 기준은 본인 채널에서 FanTalk item 터치로 상세에 진입하고, 답글이 없으면 기존 답글 쓰기 API로 답글 작성이 성공하며, 답글이 있으면 안내 모달 확인 후 수정 API로 기존 답글이 대체되는 것이다.
  • 접근 제한 성공 기준은 본인 채널이 아닌 경우 FanTalk 상세에 진입할 수 없는 것이다.
  • UI 완료 기준은 Figma 669:40462, 669:40468CreatorChannelCommunityReplyActivity의 주요 layout 구조, input bar, send button 상태가 반영되는 것이다.
  • 자동 검증 기준은 owner gate, data model 통째 전달, send button enabled/disabled 상태, 기존 writeCheers(parentCheersId = fanTalkId) 호출 계약, 기존 답글 대체 모달 및 modifyCheers 호출 계약, 작성/수정 성공 후 refresh event를 ViewModel/source 테스트로 확인하는 것이다.

11. Open Questions & Decisions

  • 결정: 별도 FanTalk 상세 조회 API가 프롬프트에 없으므로 신규 조회 endpoint를 가정하지 않는다. 최초 상세 데이터는 목록 item의 UI model을 intent payload로 전달한다.
  • 결정: FanTalk item 터치로 상세 이동 시 data model을 통째로 전달한다. 개별 primitive extra 분해 전달은 사용하지 않는다.
  • 결정: 답글 작성은 기존 writeCheers API를 parentCheersId = fanTalkId로 호출하는 방식으로 정의한다.
  • 결정: FanTalk 상세의 답글은 1개만 가능하므로 pagination/API가 필요 없다.
  • 결정: 기존 답글이 있는 상태에서 신규 답글을 쓰려 하면 안내 모달을 표시하고, 확인 시 답글 수정 API로 기존 답글을 신규 답글 내용으로 대체한다.
  • 결정: send button icon은 ic_new_arrow_up_white, ic_new_arrow_up_gray를 사용한다.
  • 결정: FanTalk 상세 진입은 currentHeader?.isOwner == true일 때만 허용한다.
  • 남은 확인: 없음.