docs(creator): 답글 상세 계획을 추가한다

This commit is contained in:
Yu Sung
2026-07-07 15:03:43 +09:00
parent 981c02a8e1
commit 26884d9e81
2 changed files with 498 additions and 0 deletions

View File

@@ -0,0 +1,192 @@
# PRD: 글 상세 - 답글 쓰기
## 1. Overview
커뮤니티 댓글 또는 팬Talk 댓글을 터치했을 때 진입하는 답글 쓰기 상세 화면을 제공한다. 화면은 선택한 원댓글과 원댓글의 답글 목록, 하단 답글 입력 바를 표시하며, 답글 작성 API는 기존 답글 쓰기 API를 그대로 사용한다.
Figma 참조:
- 답글 없음: `669:40462`, `https://www.figma.com/design/HmN1yNdJ3EIpqknFL0Hkab/-%EA%B3%B5%EC%9C%A0%EC%9A%A9-%EB%B3%B4%EC%9D%B4%EC%8A%A4%EC%98%A8-UI-UX-%EA%B8%B0%ED%9A%8D%EB%AC%B8%EC%84%9C?node-id=669-40462&m=dev`
- 답글 있음: `669:40468`, `https://www.figma.com/design/HmN1yNdJ3EIpqknFL0Hkab/-%EA%B3%B5%EC%9C%A0%EC%9A%A9-%EB%B3%B4%EC%9D%B4%EC%8A%A4%EC%98%A8-UI-UX-%EA%B8%B0%ED%9A%8D%EB%AC%B8%EC%84%9C?node-id=669-40468&m=dev`
## 2. Problem
- 현재 V2 크리에이터 채널 커뮤니티 탭은 댓글 버튼에서 V1 `CreatorCommunityCommentListView` sheet를 열고 있어, Figma 기준의 댓글 상세/답글 쓰기 화면이 없다.
- V2 팬Talk 목록은 원글과 크리에이터 답글을 표시하지만, 팬Talk 댓글을 터치해 별도 상세 화면에서 답글을 작성하는 진입점이 없다.
- 커뮤니티 댓글 답글 쓰기와 팬Talk 답글 쓰기는 이미 기존 API가 있으므로 새 API를 만들 필요가 없지만, V2 화면/진입 권한/입력 버튼 상태 규칙을 명확히 해야 한다.
## 3. Goals
- 커뮤니티 댓글 또는 팬Talk 댓글을 터치하면 글 상세 - 답글 쓰기 화면으로 진입한다.
- 팬Talk 상세는 본인 채널에서만 진입할 수 있다.
- 커뮤니티 댓글 상세는 본인 채널/본인 댓글 여부와 관계없이 진입할 수 있다.
- 화면은 Figma `669:40462`, `669:40468` 기준으로 상단 back 버튼, 원댓글 영역, 답글 영역, 하단 답글 input bar를 표시한다.
- 답글이 없으면 원댓글만 표시하고 답글 카드/연결선은 표시하지 않는다.
- 답글이 있으면 원댓글 아래에 좌측 연결선과 답글 카드를 표시한다.
- 답글 입력값이 있으면 send 버튼을 활성화한다.
- 답글 입력값이 없으면 send 버튼을 비활성화한다.
- 답글 작성 성공 후 입력값을 비우고 답글 목록을 갱신한다.
- 기존 커뮤니티 답글 API와 기존 팬Talk 답글 API를 그대로 사용한다.
- V2 패키지 하위의 기존 재사용 후보를 우선 검토하고, 중복 UI 구현을 최소화한다.
## 4. Non-Goals
- 커뮤니티 댓글 작성/수정/삭제 API를 새로 만들지 않는다.
- 팬Talk 답글 작성/수정/삭제 API를 새로 만들지 않는다.
- 커뮤니티 게시글 상세 화면 전체를 새로 설계하지 않는다.
- 팬Talk 일반 작성/수정 화면을 변경하지 않는다.
- 기존 V1 댓글 화면 전체를 V2로 일괄 교체하지 않는다.
- 신고, 차단, 프로필 상세 진입 정책을 새로 설계하지 않는다.
- Figma localhost asset URL을 앱 코드에 직접 사용하지 않는다.
- `Pods/**`, `generated/**`, `build/**`는 수정하지 않는다.
## 5. Target Users
- 커뮤니티 댓글에 답글을 남기려는 사용자
- 본인 채널의 팬Talk에 답글을 남기려는 크리에이터
## 6. User Stories
- 사용자는 커뮤니티 댓글을 터치해 해당 댓글의 답글 상세 화면으로 들어가고 답글을 작성할 수 있다.
- 크리에이터는 본인 채널의 팬Talk 댓글을 터치해 팬Talk 상세 화면으로 들어가고 팬에게 답글을 작성할 수 있다.
- 사용자는 답글 입력값이 없을 때 send 버튼이 비활성화되어 빈 답글이 전송되지 않는 것을 알 수 있다.
- 사용자는 답글 입력값이 있을 때 send 버튼이 활성화되어 바로 전송할 수 있다.
## 7. Core Requirements
### 7.1 Entry rules
- 커뮤니티 댓글 상세:
- 커뮤니티 댓글 item 터치 시 진입한다.
- 본인 채널 여부, 댓글 작성자 여부와 관계없이 진입할 수 있다.
- 기존 커뮤니티 댓글 목록/댓글 버튼 진입 흐름에서 원댓글을 선택할 수 있어야 한다.
- 팬Talk 상세:
- 팬Talk 댓글 item 터치 시 진입한다.
- `isOwnCreatorChannel == true`인 본인 채널에서만 진입할 수 있다.
- 본인 채널이 아니면 팬Talk item 터치로 상세 화면에 진입하지 않는다.
### 7.2 Screen layout
- 배경은 `Color.black`을 사용한다.
- 상단은 Figma처럼 title text 없이 back chevron만 있는 title bar를 표시한다.
- 원댓글 영역은 작성자 프로필, 닉네임, 상대 시간, 본문, 우측 액션을 표시한다.
- 답글이 없는 경우 원댓글 아래에는 빈 영역을 유지하고 답글 카드/연결선을 표시하지 않는다.
- 답글이 있는 경우 원댓글 아래에 답글 카드를 표시한다.
- 답글 카드 배경은 `Color.gray900`, radius는 14pt 기준을 사용한다.
- 답글 카드에는 답글 작성자 프로필, 닉네임, 상대 시간, 본문을 표시한다.
- 원댓글과 답글 카드 사이 좌측에는 Figma처럼 연결선을 표시한다.
- 하단 input bar는 화면 하단에 고정하고 상단 border를 표시한다.
- input field placeholder는 `답글을 입력하세요`를 표시한다.
### 7.3 Send button states
- 활성화 기준은 `replyText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty == false`이다.
- 활성화 상태:
- button background: `Color.soda400`
- icon: `ic_arrow_up_white`
- tap 시 답글 작성 API를 호출한다.
- 비활성화 상태:
- button background: `Color.gray900`
- icon: `ic_arrow_up_gray`
- tap 시 API를 호출하지 않는다.
- 입력값이 공백 또는 줄바꿈만 있으면 비활성화 상태로 처리한다.
- 전송 중 중복 tap으로 같은 답글이 여러 번 등록되지 않도록 한다.
### 7.4 Community reply API reuse
- 커뮤니티 답글 작성은 기존 `CreatorCommunityRepository.createCommunityPostComment(comment:postId:parentId:isSecret:)`를 사용한다.
- `parentId`에는 선택한 원댓글의 comment id를 전달한다.
- `postId`에는 원댓글이 속한 커뮤니티 post id를 전달한다.
- 커뮤니티 원댓글이 비밀댓글이면 답글도 자동으로 비밀 답글로 작성한다.
- 커뮤니티 원댓글이 일반댓글이면 답글도 일반 답글로 작성한다.
- 커뮤니티 댓글 상세에서는 별도 비밀 답글 toggle을 제공하지 않는다.
- `isSecret`에는 원댓글의 `isSecret` 값을 전달한다.
- 커뮤니티 답글 목록 조회는 기존 `CreatorCommunityRepository.getCommentReplyList(commentId:page:size:)`를 사용한다.
- 커뮤니티 답글 수정/삭제가 화면 액션에 포함되는 경우 기존 `CreatorCommunityRepository.modifyComment(request:)`를 사용한다.
### 7.5 FanTalk reply API reuse
- 팬Talk 답글 작성은 기존 `ExplorerRepository.writeCheers(parentCheersId:creatorId:content:)`를 사용한다.
- `parentCheersId`에는 선택한 팬Talk 원댓글의 `fanTalkId` 또는 기존 cheers id에 해당하는 값을 전달한다.
- `creatorId`에는 현재 크리에이터 채널 id를 전달한다.
- 팬Talk 답글 수정/삭제가 화면 액션에 포함되는 경우 기존 `ExplorerRepository.modifyCheers(cheersId:content:isActive:)`를 사용한다.
- 팬Talk 목록 응답의 `creatorReplies`가 상세 화면의 초기 답글 데이터로 충분하지 않으면 기존 cheers 목록 API 또는 서버 제공 상세/목록 API 재사용 가능 여부를 구현 전 확인한다.
### 7.6 Reply list refresh
- 화면 진입 시 선택한 원댓글과 기존 답글 목록을 표시한다.
- 커뮤니티 댓글 상세는 기존 `getCommentReplyList(commentId:page:size:)`로 답글 목록을 조회한다.
- 팬Talk 상세는 진입 시 전달받은 `creatorReplies`를 우선 표시한다.
- 팬Talk 답글 작성 성공 후에는 팬Talk 목록 첫 페이지를 재조회해 최신 답글을 반영한다.
- 답글 작성 성공 후:
- input field를 빈 값으로 초기화한다.
- send 버튼을 비활성화 상태로 되돌린다.
- 답글 목록을 갱신한다.
- 답글 작성 실패 시 기존 V2 화면 관례대로 toast 또는 dialog로 오류를 표시하고 입력값은 유지한다.
### 7.7 Actions
- 원댓글/답글의 더보기 버튼은 기존 권한 규칙을 따른다.
- Figma의 원댓글/답글 더보기 메뉴는 이번 범위에서 수정/삭제까지 구현한다.
- 본인이 작성한 원댓글 또는 답글이면 `수정하기`, `삭제하기`를 제공한다.
- 본인 채널의 팬Talk 답글은 크리에이터 본인이 수정/삭제할 수 있어야 한다.
- `수정하기`를 터치하면 하단 답글 입력창에 수정 대상 답글 내용을 채운다.
- 답글 수정 모드에서 send 버튼을 터치하면 신규 답글 작성 API가 아니라 기존 수정 API를 호출한다.
- 답글 수정 성공 후 수정 모드를 해제하고 input field를 비운 뒤 답글 목록을 갱신한다.
- 답글 수정 모드에서 입력값이 원래 답글과 같거나 공백이면 API를 호출하지 않는다.
- `삭제하기`를 터치하면 삭제 확인 dialog를 표시하고, 확인 시 기존 삭제 API를 호출한다.
- 삭제 확인 dialog는 기존 `SodaDialog` 또는 V2 공용 모달 중 구현 시점에 더 작은 변경으로 맞는 방식을 사용한다.
### 7.8 Reusable V2 candidates
- `SodaLive/Sources/V2/CreatorChannel/FanTalk/Components/CreatorChannelFanTalkListItem.swift`
- 팬Talk 원댓글, 답글 카드, 좌측 연결선(`CreatorChannelFanTalkReplyConnector`) 구조가 Figma 답글 있음 화면과 가장 가깝다.
- 상세 화면의 원댓글/답글 표시 컴포넌트 후보로 우선 검토한다.
- `SodaLive/Sources/V2/CreatorChannel/FanTalk/Components/CreatorChannelFanTalkActionPopup.swift`
- `수정하기`, `삭제하기` anchored popup UI가 Figma `669:40468`의 팝업과 유사하다.
- `SodaLive/Sources/V2/CreatorChannel/Community/Components/CreatorChannelCommunityListItem.swift`
- 커뮤니티 작성자 header, 본문, 댓글 버튼, 더보기 버튼 규칙을 재사용 후보로 검토한다.
- 상세 화면용으로는 게시글 카드 전체보다 header/reaction/action 규칙 참고에 가깝다.
- `SodaLive/Sources/V2/Component/Modal/SodaV2ActionModal.swift`
- 삭제/확인성 액션이 필요할 때 V2 공용 모달 후보로 검토한다.
- `SodaLive/Sources/V2/Component/DefaultTitleBar.swift`, `SodaLive/Sources/V2/Component/TitleBar.swift`
- 상단 back-only title bar 구현 시 기존 title bar 스타일 재사용 가능성을 확인한다.
- `SodaLive/Sources/V2/Component/Text/ExpandableTextView.swift`
- 원댓글 본문이 길 때 접기/펼치기 정책이 필요해지면 재사용 후보로 검토한다. Figma 상세 화면은 본문을 그대로 표시하므로 기본 요구사항은 일반 `Text` 표시이다.
- `SodaLive/Sources/V2/CreatorChannel/FanTalk/Models/CreatorChannelFanTalkTabResponse.swift`
- 팬Talk 원댓글/답글 모델(`CreatorChannelFanTalkItemResponse`, `CreatorChannelFanTalkReplyResponse`)을 상세 화면 전달 모델 후보로 검토한다.
## 8. UX / UI Expectations
- 화면 진입과 back 동작은 기존 SwiftUI navigation 흐름과 일관되어야 한다.
- 하단 input bar는 키보드 표시 여부와 관계없이 입력 상태를 유지해야 한다.
- 빈 답글은 전송되지 않아야 한다.
- send 버튼 활성/비활성 상태는 배경색과 아이콘으로 즉시 구분되어야 한다.
- 답글 작성 성공 후 사용자는 새 답글이 목록에 반영된 것을 확인할 수 있어야 한다.
## 9. Success Criteria
- 커뮤니티 댓글 item을 터치하면 본인 여부와 관계없이 글 상세 - 답글 쓰기 화면에 진입한다.
- 팬Talk 댓글 item은 본인 채널에서만 글 상세 - 답글 쓰기 화면에 진입한다.
- 답글이 없는 상태는 Figma `669:40462`처럼 원댓글과 하단 input bar만 표시한다.
- 답글이 있는 상태는 Figma `669:40468`처럼 답글 카드와 좌측 연결선을 표시한다.
- 입력값이 없으면 send 버튼 배경이 `gray900`, 아이콘이 `ic_arrow_up_gray`이고 API를 호출하지 않는다.
- 입력값이 있으면 send 버튼 배경이 `soda400`, 아이콘이 `ic_arrow_up_white`이고 tap 시 기존 답글 작성 API를 호출한다.
- 커뮤니티 답글 작성 시 기존 `CreatorCommunityRepository.createCommunityPostComment``parentId`와 함께 호출된다.
- 커뮤니티 원댓글이 비밀댓글이면 답글 작성 시 `isSecret == true`로 전송된다.
- 커뮤니티 원댓글이 일반댓글이면 답글 작성 시 `isSecret == false`로 전송된다.
- 팬Talk 답글 작성 시 기존 `ExplorerRepository.writeCheers``parentCheersId`와 함께 호출된다.
- 답글 작성 성공 후 input field가 비워지고 답글 목록이 갱신된다.
- 팬Talk 답글 작성 성공 후 팬Talk 목록 첫 페이지가 재조회된다.
- 원댓글/답글 더보기 메뉴에서 수정/삭제 액션을 사용할 수 있다.
- 답글 `수정하기`를 터치하면 하단 답글 입력창에 기존 답글 내용이 입력되고, send 시 기존 수정 API가 호출된다.
- 답글 삭제 확인 시 기존 삭제 API가 호출되고 성공 후 답글 목록이 갱신된다.
- V2 재사용 후보를 검토한 뒤 중복 구현이 필요한 경우에만 새 컴포넌트를 작성한다.
## 10. Technical Constraints
- 기능 변경은 `SodaLive/Sources/V2/**` 하위에서 우선 해결한다.
- 신규 화면, ViewModel, Repository 연결 코드는 V2 하위에 작성한다.
- 기존 V1 API wrapper를 그대로 호출할 수 있으나, V2 화면 상태와 결합되는 코드는 V2 ViewModel에 둔다.
- 신규 공용 컴포넌트가 필요하면 `SodaLive/Sources/V2/Component/**` 아래에 둔다.
- 특정 화면에서만 쓰는 컴포넌트는 해당 상세 화면의 `Components` 하위에 둔다.
- 신규 문구가 필요하면 `SodaLive/Sources/I18n/I18n.swift`에 ko/en/ja를 추가한다.
- 프로젝트 설정 변경은 신규 Swift 파일 target 등록이 필요한 경우에만 수행한다.
## 11. Assumptions
- 팬Talk API의 `fanTalkId`는 기존 cheers API의 `cheersId`와 동일하게 `parentCheersId` 또는 `cheersId`로 사용할 수 있다.
- 커뮤니티 댓글 원댓글 데이터는 상세 화면 진입 시 이미 확보되어 있거나 기존 댓글 목록 응답 모델로 전달할 수 있다.
- 커뮤니티 답글 목록은 기존 `getCommentReplyList` 응답으로 충분하다.
- 팬Talk 상세의 최신 답글 목록 갱신은 팬Talk 목록 첫 페이지 재조회로 처리한다.
## 12. Open Questions
- 해당 없음
## 13. Verification Notes
- 2026-07-07: Figma `get_design_context``get_screenshot`으로 `669:40462`, `669:40468`을 확인했다.
- 2026-07-07: 기존 커뮤니티 답글 작성/조회 API로 `CreatorCommunityRepository.createCommunityPostComment`, `CreatorCommunityRepository.getCommentReplyList`, `CreatorCommunityRepository.modifyComment`를 확인했다.
- 2026-07-07: 기존 팬Talk 답글 작성/수정 API로 `ExplorerRepository.writeCheers`, `ExplorerRepository.modifyCheers`, `PostWriteCheersRequest(parentId:creatorId:content:)`를 확인했다.
- 2026-07-07: V2 재사용 후보로 `CreatorChannelFanTalkListItem`, `CreatorChannelFanTalkActionPopup`, `CreatorChannelCommunityListItem`, `SodaV2ActionModal`, V2 title bar 컴포넌트를 확인했다.
- 2026-07-07: 사용자 확인 사항을 반영해 팬Talk 작성 성공 후 첫 페이지 재조회, 커뮤니티 비밀 원댓글의 답글 자동 비밀 처리, 원댓글/답글 수정/삭제 및 답글 입력창 기반 수정 요구사항을 추가했다.