Files

49 KiB

커뮤니티 게시물 상세 / 댓글 / 답글 구현 계획/TASK

For agentic workers: 각 단계는 체크박스(- [ ])로 추적하고, 완료 즉시 - [x]로 갱신한다. 구현 범위 변경이 생기면 이 문서를 먼저 수정한 뒤 코드에 반영한다.

Goal: 크리에이터 채널 커뮤니티 탭에서 게시글 item 터치 시 게시물 상세로 진입해 본문/좋아요/댓글을 조회·작성하고, 댓글의 답글 목록 화면(팬Talk 상세와 동일 UI)에서 답글을 조회·작성하며, 수정/삭제/좋아요는 기존 API를 재사용한다.

Architecture: 조회(상세/댓글/답글)는 신규 v2 endpoint를 v2 API/Repository로 호출한다. 쓰기/수정/삭제/좋아요는 기존 CreatorCommunityRepository를 그대로 호출한다. 화면은 커뮤니티 전용으로 신규 구현하되, 답글 목록 화면의 layout XML과 댓글/답글 item view만 재사용 가능하게 설계한다.

Tech Stack: Kotlin, Android XML Views, ViewBinding, RxJava3, Koin, JUnit4/Robolectric.


전제와 성공 기준

  • PRD: docs/20260708_커뮤니티_게시물_상세_댓글_답글/prd.md
  • 기존 커뮤니티 탭 문서:
    • docs/20260621_크리에이터_채널_커뮤니티_탭/prd.md
    • docs/20260621_크리에이터_채널_커뮤니티_탭/plan-task.md
  • 재사용 vs 복사 결정: 커뮤니티 전용 신규 구현. layout XML + 댓글/답글 item view만 데이터/콜백 주입형으로 공용화(데이터 계층은 커뮤니티 전용). 근거는 PRD 11. Open Questions & Decisions 참고.
  • 조회 API는 신규 v2 endpoint를 사용하고 기본값 page=0, size=20을 따른다.
  • 쓰기/수정/삭제/좋아요/팝업 메뉴는 기존 커뮤니티 코드를 재사용한다.
  • 구현 완료 판단 시 Gradle 검증뿐 아니라 Figma 4개 화면의 주요 layout, 하트/전송 버튼 상태, 댓글 불가 처리, 입력 영역 동작이 실제 구현 화면에 반영되었는지 확인한다.
  • Figma 대조 결과는 문서 최하단 Verification Log에 한국어로 누적 기록한다.
  • 구현 완료 후 최소 다음 명령을 실행한다.
    • ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*"
    • ./gradlew :app:mergeDebugResources
    • ./gradlew :app:compileDebugKotlin
    • ./gradlew :app:ktlintCheck
    • git diff --check

Figma 참조

  • 게시글 상세(댓글 가능 + 댓글 있음): 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=290-9243&m=dev
  • 게시글 상세(댓글 불가능): 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=290-9266&m=dev
  • 댓글 답글 목록(답글 없음): 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
  • 댓글 답글 목록(답글 있음): 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

API 계약

  • 조회(신규 v2, ApiResponse<T>):
    • 상세: GET /api/v2/creator-channels/community-posts/{postId}CreatorChannelCommunityPostDetailResponse
      • 필드: postId, creatorId, creatorNickname, creatorProfileUrl, createdAtUtc, content, imageUrl, audioUrl, price, isCommentAvailable, existOrdered, likeCount, commentCount, isPinned, isLiked, comments
      • comments는 댓글 첫 페이지(CreatorChannelCommunityCommentsResponse)를 포함한다.
    • 댓글: GET /api/v2/creator-channels/community-posts/{postId}/comments?page=0&size=20CreatorChannelCommunityCommentsResponse
      • 필드: commentCount, comments, page, size, hasNext
      • 댓글 필드: commentId, writerId, writerProfileImageUrl, writerNickname, content, isSecret, createdAtUtc, latestReply
      • 최신 답글 필드: commentId, writerId, writerProfileImageUrl, writerNickname, content, createdAtUtc
    • 답글: GET /api/v2/creator-channels/community-comments/{commentId}/replies?page=0&size=20CreatorChannelCommunityRepliesResponse
  • 쓰기/수정/삭제/좋아요(기존 CreatorCommunityRepository 재사용):
    • 좋아요: communityPostLike(postId, token)
    • 댓글 쓰기: registerComment(postId, comment, token = token)
    • 답글 쓰기: registerComment(postId, comment, parentId = commentId, token = token)
    • 댓글/답글 수정: modifyComment(ModifyCommentRequest(commentId, comment = ...), token)
    • 댓글/답글 삭제: modifyComment(ModifyCommentRequest(commentId, isActive = false), token)
  • 팝업 메뉴: R.menu.content_comment_option_menu(내 댓글/답글: 수정/삭제), R.menu.content_comment_option_menu2(채널 크리에이터가 보는 타인 댓글/답글: 삭제). 일반 타인 댓글/답글은 커뮤니티 댓글 전용 신고 API가 없어 더보기 버튼을 노출하지 않는다.

파일 구조 (예정)

  • 생성(응답 모델): app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/detail/data/CreatorChannelCommunityDetailResponse.kt
    • PRD의 CreatorChannelCommunityPostDetailResponse, CreatorChannelCommunityCommentsResponse, CreatorChannelCommunityCommentResponse, CreatorChannelCommunityReplyResponse, CreatorChannelCommunityRepliesResponse.
  • 수정: app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/data/CreatorChannelApi.kt
    • 상세/댓글/답글 조회 endpoint 3개 추가.
  • 수정: app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/data/CreatorChannelRepository.kt
    • 상세/댓글/답글 조회 method 추가.
  • 생성(진입점): 커뮤니티 탭 item 터치 → 상세 화면 이동.
    • 수정: app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityFragment.kt(item click을 Host callback으로 위임).
    • 수정: app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/ui/CreatorChannelCommunityListAdapter.kt, CreatorChannelCommunityGridAdapter.kt(item click 콜백 추가).
    • 수정: app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt(상세 화면 실행).
  • 생성(상세 화면): .../community/detail/CreatorChannelCommunityDetailActivity.kt, CreatorChannelCommunityDetailViewModel.kt
  • 생성(답글 화면): .../community/detail/reply/CreatorChannelCommunityReplyActivity.kt, CreatorChannelCommunityReplyViewModel.kt
  • 생성(layout): activity_creator_channel_community_detail.xml, activity_creator_channel_community_reply.xml, 댓글/답글 item layout, 입력 영역 layout, 전송 버튼 배경 drawable(enabled/disabled).
  • 생성(어댑터/item view): 댓글 목록 adapter, 답글 목록 adapter(재사용 가능한 댓글/답글 item view).
  • 수정: app/src/main/AndroidManifest.xml(신규 Activity 등록), app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt(신규 ViewModel binding).
  • 수정: values, values-en, values-ja strings(placeholder 등 신규 문자열 또는 기존 재사용).
  • 테스트 생성: 상세/답글 ViewModel 테스트, layout/source 테스트.

Phase 1: 조회 API/모델 계약

  • Task 1.1: 응답 데이터 클래스 생성

    • 생성: .../community/detail/data/CreatorChannelCommunityDetailResponse.kt
    • 작업: PRD 명시 5개 data class를 @Keep/@SerializedName 포함해 정의한다.
    • 검증: ./gradlew :app:compileDebugKotlin
    • 검증 기록(2026-07-08): TDD RED로 CreatorChannelCommunityDetailContractTest 추가 후 DTO 패키지/클래스 미존재로 :app:compileDebugUnitTestKotlin 실패를 확인했다. 이후 CreatorChannelCommunityPostDetailResponse, CreatorChannelCommunityCommentsResponse, CreatorChannelCommunityCommentResponse, CreatorChannelCommunityReplyResponse, CreatorChannelCommunityRepliesResponse를 생성하고 ./gradlew :app:compileDebugKotlin 성공을 확인했다.
  • Task 1.2: v2 API/Repository 조회 method 추가

    • 수정: CreatorChannelApi.kt, CreatorChannelRepository.kt
    • 작업: 상세/댓글/답글 조회 3개 추가(기본 page=0, size=20, token 포함).
    • 검증: ./gradlew :app:compileDebugKotlin
    • 검증 기록(2026-07-08): 구현 전 CreatorChannelApi/CreatorChannelRepository의 상세/댓글/답글 method 미존재로 RED 실패를 확인했다. 구현 후 ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*"./gradlew :app:compileDebugKotlin 성공을 확인했다.

Phase 2: 상세 ViewModel/화면

  • Task 2.1: 상세 ViewModel RED 테스트 작성

    • 생성: CreatorChannelCommunityDetailViewModelTest.kt
    • 케이스: 상세 로드, 좋아요 토글(낙관적 업데이트+실패 롤백, 중복 방지), 댓글 pagination(hasNext), 댓글 쓰기 성공 후 새로고침, 댓글 불가 시 댓글 조회/입력 미노출.
    • 검증: 해당 테스트 실행(구현 전 실패).
    • 검증 기록(2026-07-08): CreatorChannelCommunityDetailViewModelTest를 먼저 추가하고 ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.CreatorChannelCommunityDetailViewModelTest"를 실행해 CreatorChannelCommunityDetailViewModel/CreatorChannelCommunityDetailUiState 미존재 컴파일 오류로 RED 실패를 확인했다.
  • Task 2.2: 상세 ViewModel 구현

    • 생성: CreatorChannelCommunityDetailViewModel.kt
    • 검증: CreatorChannelCommunityDetailViewModelTest PASS.
    • 검증 기록(2026-07-08): CreatorChannelCommunityDetailViewModel과 상세/댓글/답글 UI state model을 추가하고 동일한 테스트 명령을 재실행해 PASS를 확인했다. 상세 조회, 댓글 첫 페이지/페이지네이션, 좋아요 낙관적 토글/중복 방지/실패 롤백, 댓글 trim 작성/성공 이벤트/댓글 새로고침, 댓글 불가 시 댓글 API/작성 미호출을 검증했다.
  • Task 2.3: 상세 layout/Activity 구현

    • 생성: activity_creator_channel_community_detail.xml, CreatorChannelCommunityDetailActivity.kt, 댓글 adapter/item, 입력 영역, 전송 버튼 drawable.
    • 작업: Figma 290:9243(댓글 가능)/290:9266(댓글 불가) 기준. 하트 fill/empty, 전송 버튼 gray_900/soda_400 상태, 3줄 자동확장/4줄 스크롤, 댓글 불가 시 댓글/입력 영역 숨김, 최신 답글 1개 중첩 표시, 더보기 팝업 메뉴 재사용.
    • 수정: AndroidManifest.xml, AppDI.kt.
    • 검증: ./gradlew :app:mergeDebugResources, ./gradlew :app:compileDebugKotlin
    • 검증 기록(2026-07-08): CreatorChannelCommunityDetailReplyUiContractTest를 먼저 추가하고 ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*"를 실행해 상세/답글 layout·id·source 미존재 컴파일 오류로 RED 실패를 확인했다. 이후 activity_creator_channel_community_detail.xml, CreatorChannelCommunityDetailActivity, 댓글 adapter/item, 입력 bar 배경/전송 icon drawable, 문자열, manifest/AppDI 등록을 추가했다. 상세 화면은 newIntent(context, postId)로 진입하고 postId <= 0은 toast 후 종료하며, 하트 토글/댓글 입력 trim 활성화/댓글 불가 시 댓글 목록과 하단 입력 숨김/최신 답글 card 클릭 답글 화면 진입/팝업 메뉴 재사용 계약을 반영했다.

Phase 3: 답글 화면

  • Task 3.1: 답글 ViewModel RED 테스트/구현

    • 생성: CreatorChannelCommunityReplyViewModel(.kt/Test.kt)
    • 케이스: 부모 댓글/답글 로드, 답글 pagination, 답글 쓰기(parentId = commentId) 후 새로고침, 수정/삭제 후 새로고침.
    • 검증: 테스트 PASS.
    • 검증 기록(2026-07-08): CreatorChannelCommunityReplyViewModelTest를 먼저 추가하고 ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.CreatorChannelCommunityReplyViewModelTest"를 실행해 CreatorChannelCommunityReplyViewModel/CreatorChannelCommunityReplyUiState 미존재 컴파일 오류로 RED 실패를 확인했다. 이후 CreatorChannelCommunityReplyViewModel을 추가하고 동일 명령을 재실행해 PASS를 확인했다. 부모 댓글 보존/답글 첫 페이지 조회, hasNext 페이지네이션과 중복 loadMore 방지, 답글 trim 작성/blank 무시/중복 전송 방지/성공 후 입력·이벤트 정리 및 새로고침, 수정·삭제 후 새로고침, commentId <= 0일 때 답글 API 미호출을 검증했다.
  • Task 3.2: 답글 layout/Activity 구현

    • 생성: activity_creator_channel_community_reply.xml, CreatorChannelCommunityReplyActivity.kt, 재사용 가능한 댓글/답글 item view/adapter.
    • 작업: Figma 669:40462(답글 없음)/669:40468(답글 있음) 기준. 부모 댓글 상단 표시, 답글 들여쓰기, placeholder 답글을 입력하세요, 더보기 팝업 메뉴 재사용.
    • 수정: AndroidManifest.xml, AppDI.kt.
    • 검증: ./gradlew :app:mergeDebugResources, ./gradlew :app:compileDebugKotlin
    • 검증 기록(2026-07-08): 상세 UI 계약 RED 테스트에 답글 layout/source 계약을 함께 추가해 실패를 확인한 뒤 activity_creator_channel_community_reply.xml, CreatorChannelCommunityReplyActivity, 답글 adapter/item을 생성했다. 답글 화면은 primitive extras로 부모 댓글을 재구성하고 상단 부모 댓글 표시, 들여쓰기 답글 card, 답글을 입력하세요 입력 bar, trim 기반 전송 버튼 상태, updateReplyInput/submitReply, 팝업 메뉴의 modifyReply/deleteReply 연결을 반영했다.

Phase 4: 진입점 연결

  • Task 4.1: 커뮤니티 탭 item 터치 → 상세 진입
    • 수정: CreatorChannelCommunityListAdapter.kt, CreatorChannelCommunityGridAdapter.kt, CreatorChannelCommunityFragment.kt(Host callback 추가), CreatorChannelActivity.kt.
    • 작업: item 터치 시 postId로 상세 화면 실행. 댓글에서 답글 화면(commentId) 진입 연결. 좋아요/댓글/답글 작성 후 목록 새로고침 정책 연결.
    • 검증: ./gradlew :app:compileDebugKotlin
    • 검증 기록(2026-07-08): CreatorChannelCommunityFragmentLayoutTestCreatorChannelActivitySourceTest에 RED source 계약을 먼저 추가해 list/grid adapter root click callback, fragment Host 위임, Activity의 상세 화면 newIntent 진입 계약 실패를 확인했다. 이후 list/grid adapter에 onPostClick을 추가하고 play/owner more click은 기존 콜백으로 분리 유지했으며, fragment는 postId를 Host로 위임하고 Activity는 postId <= 0L을 무시한 뒤 CreatorChannelCommunityDetailActivity.newIntent(this, postId)로 상세 화면을 실행하도록 연결했다.

Phase 5: 테스트/회귀 검증

  • Task 5.1: source/layout 테스트 추가

    • 작업: 조회 API page/size 기본값, 하트 icon 계약(ic_feed_community_heart_fill/ic_feed_community_heart), 전송 버튼 상태(ic_new_arrow_up_gray+gray_900 / ic_new_arrow_up_white+soda_400), 댓글 불가 시 댓글/입력 숨김, placeholder 문구를 검증.
    • 검증: ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*"
    • 검증 기록(2026-07-08): review-work 차단 이슈 회귀를 막기 위해 상세 댓글 수정/삭제 ViewModel 테스트와 상세/답글 source 계약 테스트를 먼저 추가했다. 구현 전 동일 targeted 테스트를 실행해 CreatorChannelCommunityDetailViewModel.modifyComment/deleteComment 미구현 컴파일 오류로 RED 실패를 확인했다. 구현 후 동일 명령을 재실행해 PASS를 확인했고, 상세/답글 Activity의 하단 도달 pagination 호출, 내 댓글/답글에만 destructive popup 노출, 수정 입력 dialog, 삭제 확인 dialog, 상세 오디오 매니저 연결/lifecycle 정리, 상세 로드 Error finish 계약을 source 테스트로 검증했다.
  • Task 5.2: 전체 검증 실행

    • 실행: 위 성공 기준의 Gradle 명령 전체.
    • Figma 수동 확인: 290:9243, 290:9266, 669:40462, 669:40468 대조.
    • 검증 기록: Verification Log에 누적.
    • 검증 기록(2026-07-08): review-work 차단 이슈 수정 후 ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*", ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest", ./gradlew :app:mergeDebugResources, ./gradlew :app:compileDebugKotlin이 PASS했다. 최초 ./gradlew :app:ktlintCheck는 신규 테스트 source 문자열 길이 초과로 실패했으며, 테스트 문자열 분리 후 재실행해 PASS했다. git diff --check는 출력 없이 PASS했다.

Phase 6: review 재반영 및 서버 계약 수정

  • Task 6.1: 서버 댓글 응답 계약 반영

    • 작업: 상세 응답 내부 comments와 댓글/최신 답글의 writer*/content 필드명을 DTO와 UI mapping에 반영한다.
    • 검증: CreatorChannelCommunityDetailContractTest, 상세/답글 ViewModel 테스트 PASS.
    • 검증 기록(2026-07-08): CreatorChannelCommunityPostDetailResponsecomments를 추가하고, CreatorChannelCommunityCommentsResponse.commentCount, 댓글/답글의 writerId, writerProfileImageUrl, writerNickname, content 계약을 반영했다. 상세 최초 댓글 목록은 상세 응답의 embedded comments에서 사용하고, 답글 수정/삭제 ID는 응답의 commentId를 답글 자체 ID로 매핑했다. ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*" PASS로 확인했다.
  • Task 6.2: 댓글/답글 refresh 중 stale pagination 응답 방지

    • 작업: 상세 댓글과 답글 pagination 요청에 generation guard를 두고, 새로고침 시 이전 요청이 현재 state를 덮지 않게 한다.
    • 검증: stale 응답 회귀 테스트 PASS.
    • 검증 기록(2026-07-08): 상세 댓글과 답글 ViewModel에 request generation guard를 추가해 새 상세/답글 로드 후 이전 page 응답이 도착해도 현재 목록을 덮지 않도록 수정했다. stale 응답 회귀 테스트를 추가하고 community targeted test PASS를 확인했다.
  • Task 6.3: 수정 dialog blank 입력 안내 보강

    • 작업: 댓글/답글/부모 댓글 수정에서 공백 입력 시 기존 커뮤니티 정책과 동일한 내용 입력 toast를 표시한다.
    • 검증: source 또는 Activity 계약 테스트 PASS.
    • 검증 기록(2026-07-08): 댓글/답글/부모 댓글 수정 요청이 공백이면 screen_creator_community_write_content_hint toast 이벤트를 노출하고 legacy modify API를 호출하지 않도록 보강했다. ViewModel 회귀 테스트 PASS를 확인했다.
  • Task 6.4: 레이아웃 속성 직접 검증 테스트 축소

    • 작업: UI layout 크기/padding/source 문자열 검증을 제거하고, 로직/상태/리소스 존재 계약 중심으로 테스트를 줄인다.
    • 검증: targeted unit test PASS.
    • 검증 기록(2026-07-08): CreatorChannelCommunityDetailReplyUiContractTest에서 layout 높이/padding/drawable 문자열 및 Activity source 문자열 직접 검증을 제거하고, inflate 가능한 layout과 필수 view id/문자열/AppDI/manifest 등록 확인으로 축소했다. community targeted test PASS를 확인했다.

Phase 7: review 결과 반영

  • Task 7.1: embedded 댓글의 채널 크리에이터 권한 매핑 수정
    • 작업: 상세 응답의 embedded comments를 최초 UI state로 매핑할 때 Content state가 아직 없어 isCreatorOwner가 false로 고정되는 문제를 수정한다.
    • 검증: 채널 크리에이터가 타인 댓글/최신 답글에 대해 삭제 메뉴 권한을 갖는 ViewModel 회귀 테스트 PASS.
    • 검증 기록(2026-07-08): CreatorChannelCommunityDetailViewModelTest에 채널 작성자가 상세 embedded 타인 댓글의 삭제 메뉴 권한을 갖는 회귀 테스트를 추가하고, 수정 전 AssertionError RED 실패를 확인했다. 이후 embedded 댓글은 상세 응답의 creatorId, 추가 페이지 댓글은 현재 post의 creatorId 기준으로 isCreatorOwner를 명시 전달하도록 수정해 동일 테스트 PASS를 확인했다.

Phase 8: 리뷰 결과 추가 반영

  • Task 8.1: 댓글 불가 화면/댓글·답글 item UI 정리

    • 작업: 댓글 불가 화면에서는 댓글 목록/입력 영역만 숨기고 별도 안내 문구를 제거한다. 댓글/답글 item에서 Figma/PRD에 없는 reaction row를 제거한다.
    • 검증: layout/source 계약 테스트 및 community targeted test PASS.
    • 검증 기록(2026-07-08): CreatorChannelCommunityDetailReplyUiContractTest에 댓글 불가 안내 view 제거, 댓글/답글 reaction id 제거 계약을 추가했다. item_creator_channel_community_comment.xmlitem_creator_channel_community_reply.xml에서 Figma에 없는 reaction row를 제거하고 adapter binding 참조를 정리했다. 상세 댓글 불가 화면은 댓글 header/list/input bar만 숨기도록 유지했다. ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*" PASS로 확인했다.
  • Task 8.2: 유료 미구매 paywall 표시 수정

    • 작업: 유료 미구매 게시물은 raw media URL을 노출하지 않되 Figma 중앙 lock + 가격 paywall 영역은 표시한다.
    • 검증: 상세 ViewModel/Activity/layout 계약 테스트 PASS.
    • 검증 기록(2026-07-08): CreatorChannelCommunityPostDetailUiModel.showPaywall을 추가하고 유료 미구매 타인 게시물에서 imageUrl/audioUrl은 계속 제거하되 showPaywall을 true로 노출하도록 수정했다. 상세 layout에는 layout_creator_channel_community_detail_paywalltv_creator_channel_community_detail_paywall_price를 추가해 이미지 컨테이너 중앙에 lock+가격 pill을 표시한다. 상세 ViewModel/UI 계약 테스트 PASS로 확인했다.
  • Task 8.3: 댓글/답글 상대시간 보정

    • 작업: v2 createdAtUtc 파싱을 ISO offset/초 단위 epoch까지 지원하고, 서버·단말 시계 차이로 작성 직후 과거 시간이 표시되지 않도록 최근 시간 보정 규칙을 추가한다. 답글 화면 부모 댓글도 원본 createdAtUtc를 전달해 답글 목록과 같은 포맷터 기준으로 표시한다.
    • 검증: 상대시간 포맷터 회귀 테스트 및 상세/답글 ViewModel 테스트 PASS.
    • 검증 기록(2026-07-08): 기존 공통 함수 formatUtcRelativeTimeText를 보강해 epoch millis 기존 동작을 유지하면서 epoch seconds, ISO offset, 6자리 fraction을 파싱하도록 수정했다. ISO 문자열은 서버/단말 시계 오차를 고려해 10분 이내를 방금전으로 보정한다. 댓글/답글 UI model에 원본 createdAtUtc를 보존하고 답글 화면 Intent에 전달해 부모 댓글도 동일한 UtcRelativeTimeTextFormatter로 재포맷하도록 수정했다. RelativeTimeFormatterTest, 상세/답글 ViewModel 테스트 PASS로 확인했다.

Phase 9: 댓글/답글 수정 UX 후속 반영

  • Task 9.1: 타이틀/메뉴/모달 계약 정리

    • 수정: activity_creator_channel_community_detail.xml, activity_creator_channel_community_reply.xml, content_comment_option_menu.xml, content_comment_option_menu2.xml, 상세/답글 Activity.
    • 작업: 상세/답글 titlebar의 커뮤니티, 답글 문구를 제거하고, 댓글/답글 더보기 메뉴 문구를 수정하기, 삭제하기로 바꾼다. v2 패키지 내부 삭제 확인은 V2ModalDialog를 사용한다.
    • 검증: layout/source 계약 테스트, ./gradlew :app:compileDebugKotlin
    • 검증 기록(2026-07-09): 상세/답글 layout에서 title TextView를 제거하고, 댓글 메뉴 리소스는 creator_channel_fantalk_edit/creator_channel_fantalk_delete를 사용하도록 수정했다. 상세/답글 Activity의 삭제 확인은 V2ModalDialog로 교체하고 AlertDialog 사용을 제거했다. CreatorChannelCommunityDetailReplyUiContractTest에 title id 제거, 메뉴 문구, V2ModalDialog source 계약을 추가했으며 targeted community test와 ./gradlew :app:compileDebugKotlin PASS로 확인했다.
  • Task 9.2: 하단 입력창 기반 수정 모드 구현

    • 수정: CreatorChannelCommunityDetailViewModel.kt, CreatorChannelCommunityReplyViewModel.kt, 상세/답글 Activity/layout, 관련 테스트.
    • 작업: 수정 선택 시 별도 입력 Dialog 없이 하단 입력창에 기존 내용을 채우고 X 취소 버튼을 표시한다. 수정 모드의 send는 쓰기가 아니라 수정 API를 호출하며, 성공/취소 시 일반 입력 모드로 복귀한다.
    • 검증: 상세/답글 ViewModel 회귀 테스트, layout/source 계약 테스트, ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*"
    • 검증 기록(2026-07-09): 상세 댓글은 editingCommentId/editingOriginalComment, 답글 화면은 CreatorChannelCommunityReplyEditTarget으로 수정 모드를 상태화했다. 수정 선택 시 하단 입력창에 기존 내용을 세팅하고 X 버튼을 표시하며, 수정 모드의 send는 댓글/답글/부모 댓글 수정 API를 호출한다. 성공 또는 X 취소 시 입력과 수정 target을 초기화한다. 변경 없음과 공백 입력은 기존 toast 정책을 유지했다. ViewModel 회귀 테스트와 layout/source 계약 테스트를 추가했고 targeted community test PASS로 확인했다.
  • Task 9.3: 후속 검증

    • 실행: ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*", ./gradlew :app:compileDebugKotlin, ./gradlew :app:ktlintCheck, git diff --check.
    • 검증 기록: Verification Log에 누적한다.
    • 검증 기록(2026-07-09): ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*", ./gradlew :app:compileDebugKotlin, ./gradlew :app:ktlintCheck, git diff --check 실행 결과 모두 통과했다. ktlintCheck.editorconfig disabled_rules deprecation 경고는 기존 설정 경고로 남아 있다.

Phase 10: 댓글/답글 더보기 메뉴 폰트 후속 반영

  • Task 10.1: 더보기 메뉴 regular font 적용
    • 수정/생성: CreatorChannelCommunityMorePopup.kt, view_creator_channel_community_more_popup.xml, 댓글/답글 adapter, UI 계약 테스트.
    • 작업: 기본 PopupMenu 대신 PopupWindow 기반 커스텀 메뉴를 사용하고, 메뉴 TextView에 android:fontFamily="@font/regular"를 명시한다.
    • 검증: ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*", ./gradlew :app:compileDebugKotlin, ./gradlew :app:ktlintCheck, git diff --check.
    • 검증 기록(2026-07-09): 댓글/답글 더보기 메뉴를 PopupMenu에서 CreatorChannelCommunityMorePopup으로 교체했다. 새 view_creator_channel_community_more_popup.xml수정하기, 삭제하기 TextView에 @font/regular를 명시했고, 내 댓글/답글은 수정+삭제, 채널 작성자가 보는 타인 댓글/답글은 삭제만 노출하는 기존 권한 규칙을 유지했다. UI 계약 테스트에 popup layout font와 adapter source 계약을 추가했다. ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*", ./gradlew :app:compileDebugKotlin, ./gradlew :app:ktlintCheck, git diff --check가 모두 통과했다.

Phase 11: 댓글/답글 입력창 키보드 후속 반영

  • Task 11.1: 수정 진입/성공 시 키보드 제어
    • 수정: CreatorChannelCommunityDetailActivity.kt, CreatorChannelCommunityReplyActivity.kt, UI 계약 테스트.
    • 작업: 수정하기 터치 후 하단 입력창 수정 모드로 전환될 때 입력창에 focus를 주고 키보드를 즉시 올린다. 댓글/답글 작성 또는 수정 API 성공 이벤트 수신 시 키보드를 내리고 focus를 해제한다.
    • 검증: ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*", ./gradlew :app:compileDebugKotlin, ./gradlew :app:ktlintCheck, git diff --check.
    • 검증 기록(2026-07-09): 상세/답글 Activity에 showSoftInput/hideSoftInputFromWindow 기반 키보드 제어를 추가했다. 수정 target이 새로 설정되면 입력창 focus 후 키보드를 올리고, 댓글 작성/수정 및 답글 작성/수정/부모 댓글 수정 성공 이벤트에서 키보드를 내리도록 연결했다. UI 계약 테스트에 IME 제어 source 계약을 추가했다. ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*", ./gradlew :app:compileDebugKotlin, ./gradlew :app:ktlintCheck, git diff --check가 모두 통과했다.

Phase 12: 커뮤니티 상세 UI border 후속 반영

  • Task 12.1: 상세 상단 게시글 배경과 댓글 경계선 수정
    • 수정: app/src/main/res/layout/activity_creator_channel_community_detail.xml, app/src/main/res/layout/item_creator_channel_community_comment.xml, CreatorChannelCommunityCommentAdapter.kt
    • 작업: 상세 게시글 컨테이너의 bg_feed_card rounded 배경을 제거하고, 게시글과 댓글 헤더 사이 1dp border를 추가한다. 댓글 item 사이에는 1dp border를 표시하되 마지막 댓글 하단 border는 숨긴다.
    • 검증: ./gradlew :app:mergeDebugResources, ./gradlew :app:compileDebugKotlin, ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.CreatorChannelCommunityDetailReplyUiContractTest", ./gradlew :app:ktlintCheck, git diff --check
    • 검증 기록(2026-07-12): 상세 게시글 컨테이너의 bg_feed_card 배경을 제거해 목록형 rounded card 배경이 상세 상단 본문에는 적용되지 않도록 했다. 게시글과 댓글 헤더 사이에는 gray_800 1dp divider를 추가하고 댓글 가능 상태에서만 노출되도록 Activity binding을 연결했다. 댓글 item 하단 divider에는 id를 부여하고 adapter에서 마지막 댓글의 divider를 숨겨 댓글 사이 border로만 보이게 했다. ./gradlew :app:mergeDebugResources, ./gradlew :app:compileDebugKotlin, ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.CreatorChannelCommunityDetailReplyUiContractTest", ./gradlew :app:ktlintCheck, git diff --check가 모두 통과했다. ktlintCheck.editorconfig disabled_rules deprecation 경고는 기존 설정 경고로 남아 있다.

Phase 13: 커뮤니티 상세 오디오/구매 후속 반영

  • Task 13.1: 상세 오디오 중앙 버튼과 구매 회귀 테스트 추가

    • 수정: app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityDetailViewModelTest.kt, CreatorChannelCommunityDetailReplyUiContractTest.kt
    • 작업: 상세 layout에 이미지 중앙 play/pause 버튼이 있고, Activity가 PurchaseCommunityPostDialogpurchaseCommunityPost를 연결하며, ViewModel이 구매 성공 후 상세를 재조회하는 계약을 RED로 고정한다.
    • 검증: ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.CreatorChannelCommunityDetailViewModelTest", ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.CreatorChannelCommunityDetailReplyUiContractTest"
    • 검증 기록(2026-07-12): 상세 layout의 중앙 오디오 버튼 id, legacy 구매 dialog 연결, ViewModel 구매 성공 후 상세 재조회 계약을 테스트에 추가했다. 최초 병렬 Gradle 실행은 120초/300초 timeout 및 병렬 resource packaging 충돌성 NoSuchFileException으로 완료 결과를 얻지 못했으나, 구현 후 순차 재실행에서 동일 테스트들이 PASS했다.
  • Task 13.2: 상세 오디오 중앙 버튼과 구매 흐름 구현

    • 수정: app/src/main/res/layout/activity_creator_channel_community_detail.xml, CreatorChannelCommunityDetailActivity.kt, CreatorChannelCommunityDetailViewModel.kt
    • 작업: item_creator_community_all.xmliv_play_or_pause처럼 상세 이미지 중앙 버튼을 추가하고, 재생 상태에 따라 play/pause drawable을 갱신한다. 상세 paywall 가격 클릭 시 기존 구매 dialog를 띄우고 구매 성공 후 상세를 다시 로드한다.
    • 검증: targeted test PASS, ./gradlew :app:mergeDebugResources, ./gradlew :app:compileDebugKotlin
    • 검증 기록(2026-07-12): activity_creator_channel_community_detail.xml의 이미지 컨테이너 중앙에 iv_creator_channel_community_detail_play_or_pause를 추가하고 btn_audio_content_play/btn_audio_content_pause를 사용하도록 연결했다. CreatorChannelCommunityDetailActivity는 이미지+오디오 게시물에서 중앙 버튼을 표시하고, 이미지 없는 오디오 게시물은 기존 텍스트 오디오 버튼을 유지한다. paywall 영역 클릭 시 기존 PurchaseCommunityPostDialog를 띄우고 확인 시 CreatorChannelCommunityDetailViewModel.purchaseCommunityPost()를 호출한다. ViewModel은 기존 CreatorCommunityRepository.purchaseCommunityPost를 호출한 뒤 성공 시 상세를 다시 로드한다. ./gradlew :app:mergeDebugResources, ./gradlew :app:compileDebugKotlin PASS로 확인했다.
  • Task 13.3: 후속 검증

    • 실행: ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*", ./gradlew :app:compileDebugKotlin, ./gradlew :app:ktlintCheck, git diff --check
    • 검증 기록: Verification Log에 누적한다.
    • 검증 기록(2026-07-12): ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.CreatorChannelCommunityDetailViewModelTest", ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.CreatorChannelCommunityDetailReplyUiContractTest", ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*", ./gradlew :app:mergeDebugResources, ./gradlew :app:compileDebugKotlin, ./gradlew :app:ktlintCheck, git diff --check가 모두 통과했다. ktlintCheck.editorconfig disabled_rules deprecation 경고와 Gradle deprecated feature 경고는 기존 설정 경고로 남아 있다.

Phase 14: 유료 미구매 상세 반응/댓글 숨김 후속

  • Task 14.1: 상세 유료 미구매 게시글 reaction/comment 숨김
    • 대상 파일:
      • app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/detail/CreatorChannelCommunityDetailViewModel.kt
      • app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/detail/CreatorChannelCommunityDetailActivity.kt
      • app/src/main/res/layout/activity_creator_channel_community_detail.xml
      • app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityDetailViewModelTest.kt
    • 작업: price > 0 && !existOrdered && creatorId != SharedPreferenceManager.userId 잠금 게시글에서는 상세의 reaction 현황, 댓글 목록, 댓글 헤더, 댓글 입력을 숨긴다.
    • 검증 기록:
      • 2026-07-12: RED로 CreatorChannelCommunityDetailViewModelTest.유료 미구매 게시물은 작성자가 아니면 reaction 현황과 댓글을 숨긴다를 추가했고, production 변경 전 showReaction 미구현 컴파일 실패를 확인했다. 이후 상세 UI 모델/상태와 Activity binding에 잠금 조건을 반영해 focused 테스트 GREEN을 확인했다.

Verification Log

  • 2026-07-12: Phase 14 유료 미구매 상세 게시글 reaction/comment 숨김 변경을 완료했다. RED는 CreatorChannelCommunityDetailViewModelTest.유료 미구매 게시물은 작성자가 아니면 reaction 현황과 댓글을 숨긴다showReaction 미구현 컴파일 실패로 확인했고, 구현 후 focused 테스트, ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*", ./gradlew :app:mergeDebugResources :app:compileDebugKotlin :app:ktlintCheck가 모두 BUILD SUCCESSFUL로 PASS했다. 실제 화면 직접 조작은 Activity가 내부 진입 경로와 데이터 계정에 의존해 이번 검증에서는 단위/리소스/컴파일/스타일 검증으로 대체했다.

  • 구현 전 문서 작성 단계에서는 Gradle 검증을 실행하지 않았다.

  • 2026-07-12: 커뮤니티 상세 오디오 중앙 버튼 및 유료 게시글 구매 후속 변경을 반영했다. 상세 ViewModel 구매 회귀 테스트, 상세 UI 계약 테스트, 커뮤니티 targeted 테스트, 리소스 병합, Kotlin 컴파일, ktlint, diff whitespace 검증이 모두 통과했다. 최초 병렬 Gradle 실행 중 resource packaging incremental output 충돌성 오류가 한 번 발생했으나 순차 재실행에서 재현되지 않았다.

  • 2026-07-08: 추가 review findings 반영 범위를 확정했다. 상세/답글 변경 결과를 상위 커뮤니티 목록과 상세 댓글/답글 카운트에 반영하고, 좋아요 API의 success=false 응답에서 낙관적 상태를 롤백하며, 댓글/답글 입력창을 3줄까지 자동 확장되도록 고정 높이를 제거하고, 수정 내용이 없을 때 기존 audio_content_comment_no_change toast를 표시하도록 보강한다.

  • 2026-07-08: Phase 2.3/3.2 UI 구현 전 ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*"를 실행해 신규 activity/layout/item/source가 없어 compileDebugUnitTestKotlin RED 실패를 확인했다.

  • 2026-07-08: Phase 2.3/3.2 UI 구현 후 동일 targeted 테스트를 재실행해 48개 테스트 PASS를 확인했다. Robolectric inflate로 상세/답글 layout의 title back/content/input bar 및 item layout 계약을 확인했고, source 검사로 AppDI/manifest/ViewModel binding/popup menu/comment hidden/newIntent 계약을 확인했다.

  • 2026-07-08: review-work 차단 이슈 대응으로 Phase 5 테스트를 보강했다. RED는 CreatorChannelCommunityDetailViewModel.modifyComment/deleteComment 미구현 컴파일 오류로 확인했고, GREEN은 community targeted 테스트와 CreatorChannelActivity source 테스트, resources merge, Kotlin compile, ktlint, diff whitespace 검증 PASS로 확인했다.

  • 2026-07-08: 최종 확인으로 ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*", ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest", ./gradlew :app:mergeDebugResources, ./gradlew :app:compileDebugKotlin, ./gradlew :app:ktlintCheck를 재실행해 모두 BUILD SUCCESSFUL을 확인했다. git diff --check는 출력 없이 통과했다.

  • 2026-07-08: review-work 재검증에서 발견된 추가 차단 이슈를 반영했다. 상세 댓글 추가 로딩은 실제 스크롤 컨테이너인 NestedScrollView 기준으로 감지하도록 수정하고, 유료 미구매 잠금 게시글은 작성자가 아닌 경우 이미지/오디오 URL을 UI model에서 제거해 raw media URL 노출을 막았다. 댓글/답글 더보기는 레거시와 동일하게 작성자 또는 채널 크리에이터에게만 노출하며, 답글 화면 부모 댓글에도 수정/삭제 메뉴를 연결했다. PRD의 상세 응답 comments 표현은 별도 댓글 endpoint 첫 페이지 조회 계약으로 정리했다.

  • 2026-07-08: 추가 차단 이슈 수정 후 ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*", ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest", ./gradlew :app:mergeDebugResources, ./gradlew :app:compileDebugKotlin, ./gradlew :app:ktlintCheck를 재실행해 모두 BUILD SUCCESSFUL을 확인했다. git diff --check는 출력 없이 통과했다.

  • 2026-07-08: 부모 댓글 수정/삭제 후 답글 화면의 부모 댓글 영역과 상세 댓글 목록이 stale 상태로 남을 수 있다는 review-work 지적을 반영했다. 부모 댓글 수정 성공 시 답글 ViewModel의 parentComment 상태를 즉시 갱신하고, 부모 댓글 변경/삭제 이벤트를 Activity result로 상세 화면에 전달해 상세를 재조회하도록 수정했다. 삭제 성공 시 답글 화면은 RESULT_OK 반환 후 종료한다. 회귀 테스트로 부모 댓글 수정 상태 갱신, 삭제 이벤트, ActivityResult source 계약을 추가하고 ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*" PASS를 확인했다.

  • 2026-07-08: 추가 review findings 4건을 반영했다. 상세 진입은 ActivityResultLauncher로 변경해 상세의 댓글/좋아요/수정/삭제 및 답글 화면 변경 결과가 상위 커뮤니티 목록 refresh로 전파되도록 했고, 좋아요 API의 success=false 응답은 낙관적 상태를 이전 좋아요 상태/개수로 롤백하도록 수정했다. 댓글/답글 작성·수정·삭제 후에는 상세/답글을 서버 재조회해 댓글·답글 count를 동기화하고, 댓글/답글 입력창은 고정 높이를 제거해 3줄까지 자동 확장되도록 wrap_content/minHeight=40dp/maxLines=3/vertical scrollbar 계약을 맞췄다. 수정 내용이 원문과 같으면 audio_content_comment_no_change toast 후 API 호출을 막도록 상세/답글 수정 dialog를 보강했다. 검증으로 ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*", ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest", ./gradlew :app:mergeDebugResources, ./gradlew :app:compileDebugKotlin, ./gradlew :app:ktlintCheck가 모두 BUILD SUCCESSFUL임을 확인했고, git diff --check는 출력 없이 통과했다. 최초 병렬 Gradle 실행 중 KSP 증분 캐시 손상/동시 접근 오류가 발생했으나 app/build/kspCaches/debug 생성 캐시 제거 후 순차 재실행으로 통과했다.

  • 2026-07-08: review-work 재검증에서 답글 화면 변경 결과가 상세 화면 재조회까지만 반영되고 상위 CreatorChannelActivity 목록 refresh로 재전파되지 않는 차단 이슈가 확인되어 수정했다. CreatorChannelCommunityDetailActivityreplyLauncher에서 답글 화면 RESULT_OK 수신 시 setResult(Activity.RESULT_OK)를 먼저 호출한 뒤 loadDetail(postId)를 수행하도록 변경했고, source contract test가 이 순서를 검증하도록 보강했다. 검증으로 ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*", ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest", ./gradlew :app:mergeDebugResources, ./gradlew :app:compileDebugKotlin, ./gradlew :app:ktlintCheck가 모두 BUILD SUCCESSFUL임을 확인했고, git diff --check는 출력 없이 통과했다.

  • 2026-07-08: 추가 review findings 3건을 반영했다. 커뮤니티 게시물 상세 진입 전 SharedPreferenceManager.token.isBlank()이면 기존 showLoginActivity()로 이동하고 상세 Activity launch를 중단하도록 보강했다. 댓글/답글 작성·수정·삭제 실패 시 v2 CreatorChannelEvent<ToastMessage> 기반 toast 이벤트를 노출해 API 메시지 또는 common_error_unknown을 표시하도록 상세/답글 ViewModel과 Activity를 수정했다. 상세 댓글 목록 상단에는 댓글 {commentCount} 헤더를 추가하고, 답글 화면 부모 댓글에서는 reply/heart count reaction row와 latest reply block을 숨겨 Figma/PRD 정적 UI와 맞췄다. 회귀 테스트로 로그인 gate source 계약, 실패 toast 이벤트 consume 계약, 댓글 헤더/부모 reaction row source·layout 계약을 추가했으며 targeted unit test는 BUILD SUCCESSFUL을 확인했다.

  • 2026-07-08: 리뷰 결과 3건과 서버 응답 계약 불일치를 반영했다. 상세 응답 내부 comments를 최초 댓글 목록으로 사용하도록 바꾸고, 댓글/최신 답글/답글 응답 DTO를 서버 계약의 writer*, content, commentId 필드명에 맞췄다. 상세 댓글/답글 pagination에는 generation guard를 추가해 새로고침 후 stale page 응답이 현재 목록을 덮지 않게 했고, 댓글/답글/부모 댓글 수정 blank 입력은 screen_creator_community_write_content_hint toast 후 API를 호출하지 않도록 했다. UI 계약 테스트는 layout 속성/source 문자열 직접 검증을 제거해 필수 view/resource 등록 중심으로 축소했다. 검증으로 ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*", ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest", ./gradlew :app:mergeDebugResources, ./gradlew :app:compileDebugKotlin, ./gradlew :app:ktlintCheck가 모두 BUILD SUCCESSFUL임을 확인했다. git diff --check, git diff HEAD --check는 출력 없이 통과했다. :app:mergeDebugResources는 최초 sandbox에서 ~/.gradle lock 파일 권한 문제로 실패했으나, 동일 명령을 권한 상승 재실행해 통과했다.

  • 2026-07-08: 코드 리뷰에서 발견된 채널 크리에이터 권한 매핑 문제를 반영했다. 상세 응답 embedded comments를 최초 UI state로 매핑할 때 아직 Content state가 없어 isCreatorOwner가 false로 고정되던 문제를, 상세 응답의 creatorId 또는 현재 post의 creatorId를 기준으로 명시 전달하도록 수정했다. 회귀 테스트는 수정 전 RED 실패 후 수정 후 PASS를 확인했다. 최종 검증으로 ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*", ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest", ./gradlew :app:mergeDebugResources, ./gradlew :app:compileDebugKotlin, ./gradlew :app:ktlintCheck가 모두 BUILD SUCCESSFUL임을 확인했다. git diff --check, git diff HEAD --check는 출력 없이 통과했다. :app:mergeDebugResources는 최초 sandbox에서 ~/.gradle lock 파일 권한 문제로 실패했으나, 동일 명령을 권한 상승 재실행해 통과했다.

  • 2026-07-08: 리뷰 결과 추가 반영을 완료했다. 댓글 불가 화면은 댓글 목록/header/input bar만 숨기고 별도 안내 문구 view를 제거했다. 댓글/답글 item에서 Figma에 없는 reaction row를 제거했다. 유료 미구매 상세는 raw image/audio URL을 UI model에서 계속 제거하면서 showPaywall로 중앙 lock+가격 paywall을 표시하도록 수정했다. 상대시간은 기존 공통 formatUtcRelativeTimeText를 보강해 epoch seconds, ISO offset, 6자리 fraction, 작성 직후 서버/단말 시계 차이를 처리하고, 답글 화면 부모 댓글에는 원본 createdAtUtc를 전달해 동일 포맷터 기준으로 표시되게 했다. 검증으로 ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.common.RelativeTimeFormatterTest", ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*", ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest", ./gradlew :app:mergeDebugResources, ./gradlew :app:compileDebugKotlin, ./gradlew :app:ktlintCheck가 모두 BUILD SUCCESSFUL임을 확인했다. git diff --check, git diff HEAD --check는 출력 없이 통과했다. :app:mergeDebugResources는 최초 sandbox에서 ~/.gradle lock 파일 권한 문제로 실패했으나, 동일 명령을 권한 상승 재실행해 통과했다.

  • 2026-07-09: 사용자 후속 요청 4건을 반영했다. 상세/답글 titlebar의 커뮤니티, 답글 문구를 제거했고, 댓글/답글 더보기 메뉴 문구를 수정하기, 삭제하기로 변경했다. v2 패키지 내부 삭제 확인은 V2ModalDialog로 교체했으며, 수정은 Dialog 없이 하단 입력창 수정 모드로 전환되도록 구현했다. 수정 모드에서는 send 버튼으로 수정 API를 호출하고, send 버튼 오른쪽 X 버튼으로 수정 취소가 가능하다. 검증으로 ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*", ./gradlew :app:compileDebugKotlin, ./gradlew :app:ktlintCheck, git diff --check가 모두 통과했다. ktlintCheck.editorconfig disabled_rules deprecation 경고는 기존 설정 경고로 남아 있다.

  • 2026-07-09: 댓글/답글 더보기 메뉴 font 후속 요청을 반영했다. PopupMenu는 메뉴 item font를 직접 지정하기 어려워, 댓글/답글 더보기만 PopupWindow 기반 CreatorChannelCommunityMorePopup으로 교체하고 메뉴 TextView에 android:fontFamily="@font/regular"를 명시했다. 검증 명령은 Phase 10.1 기록에 누적한다.

  • 2026-07-09: 수정하기 터치 시 키보드가 바로 올라오고, 입력/수정 API success 후 키보드가 내려가야 한다는 후속 요청을 반영했다. 상세/답글 Activity에서 수정 모드 진입 시 입력창 focus와 IME show를 수행하고, 작성/수정 성공 이벤트에서 IME hide와 focus clear를 수행한다. 검증 명령은 Phase 11.1 기록에 누적한다.

  • 2026-07-12: 커뮤니티 상세 상단 게시글 영역의 rounded card 배경 제거와 게시글-댓글/댓글 사이 1dp border 후속 요청을 반영했다. 검증 명령은 Phase 12.1 기록에 누적한다.