docs(creator): 커뮤니티 후속 작업 기록을 갱신한다
This commit is contained in:
@@ -285,7 +285,694 @@
|
||||
- 검증 기록:
|
||||
- 2026-07-12: RED로 `CreatorChannelCommunityDetailViewModelTest.유료 미구매 게시물은 작성자가 아니면 reaction 현황과 댓글을 숨긴다`를 추가했고, production 변경 전 `showReaction` 미구현 컴파일 실패를 확인했다. 이후 상세 UI 모델/상태와 Activity binding에 잠금 조건을 반영해 focused 테스트 GREEN을 확인했다.
|
||||
|
||||
---
|
||||
|
||||
### Phase 15: 커뮤니티 구매 진입점·표시 상태·상세 메뉴 정리
|
||||
|
||||
**Phase 결과:** 홈과 커뮤니티 탭은 게시글 상태를 동일하게 표시하고 상세 이동만 수행하며, 구매와 권한별 관리/신고는 상세에서 수행한다.
|
||||
|
||||
**선행조건:** PRD `F0-20260810` 승인, 홈 Response의 `isPinned`/`isCommentAvailable` 서버 계약 확정.
|
||||
|
||||
**Phase 완료 조건:** `P15-T1`~`P15-T5`와 `P15-GATE` 완료, Task별 검증 기록 및 문서 최하단 `Verification Log` 누적.
|
||||
|
||||
**실행 제약:** 2026-08-10 사용자 지시에 따라 이번 계획 작성 단계에서는 구현과 Git 커밋을 수행하지 않는다. 이후 구현도 별도 사용자 요청 전에는 시작하지 않으며, 이 Phase에는 commit 단계를 두지 않는다.
|
||||
|
||||
#### Phase 15 파일 구조
|
||||
|
||||
- 홈 계약/표시:
|
||||
- `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/data/CreatorChannelHomeModels.kt`
|
||||
- `app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedItem.kt`
|
||||
- `app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedCommunityView.kt`
|
||||
- `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/ui/CreatorChannelHomeSectionAdapter.kt`
|
||||
- `app/src/main/res/layout/view_feed_community.xml`
|
||||
- 커뮤니티 탭:
|
||||
- `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityFragment.kt`
|
||||
- `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/model/CreatorChannelCommunityUiModels.kt`
|
||||
- `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/model/CreatorChannelCommunityMappers.kt`
|
||||
- `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/ui/CreatorChannelCommunityListAdapter.kt`
|
||||
- `app/src/main/res/layout/item_creator_channel_community_list.xml`
|
||||
- 확인만 수행: `app/src/main/res/layout/item_creator_channel_community_grid.xml`
|
||||
- 상세/결과 전파:
|
||||
- `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/detail/CreatorChannelCommunityDetailActivity.kt`
|
||||
- `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/data/CreatorChannelRepository.kt`
|
||||
- `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt`
|
||||
- `app/src/main/java/kr/co/vividnext/sodalive/v2/community/action/CommunityChange.kt`
|
||||
- `app/src/main/res/layout/activity_creator_channel_community_detail.xml`
|
||||
- 기존 테스트 수정:
|
||||
- `app/src/test/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedItemTest.kt`
|
||||
- `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelHomeModelsTest.kt`
|
||||
- `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityMapperTest.kt`
|
||||
- `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityFragmentLayoutTest.kt`
|
||||
- `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityDetailViewModelTest.kt`
|
||||
- `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityDetailReplyUiContractTest.kt`
|
||||
- `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivitySourceTest.kt`
|
||||
- `app/src/test/java/kr/co/vividnext/sodalive/v2/community/action/CommunityChangeTest.kt`
|
||||
|
||||
#### Task 15.1 홈 Response와 게시글 표시 정책
|
||||
|
||||
**Goal 실행 `P15-T1`:** 홈 커뮤니티 Response의 고정/댓글 가능 계약과 잠금·reaction 표시 조건을 순수 로직으로 고정한다.
|
||||
|
||||
- **시작 조건:** PRD `Home Response Contract`, `Home Community Requirements` 승인.
|
||||
- **완료 증거:** 신규 DTO 필드 파싱 및 `FeedItem.Community` 표시 정책 focused test PASS.
|
||||
- **범위 밖:** View binding, 커뮤니티 탭, 상세 메뉴.
|
||||
|
||||
**Files:**
|
||||
|
||||
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/data/CreatorChannelHomeModels.kt`
|
||||
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedItem.kt`
|
||||
- Test: `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelHomeModelsTest.kt`
|
||||
- Test: `app/src/test/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedItemTest.kt`
|
||||
|
||||
**Interfaces:**
|
||||
|
||||
- Consumes: 홈 JSON `isPinned: Boolean`, `isCommentAvailable: Boolean`, 기존 `price`, `existOrdered`.
|
||||
- Produces:
|
||||
|
||||
`FeedItem.Community`에 추가할 member:
|
||||
|
||||
```kotlin
|
||||
val isPinned: Boolean = false
|
||||
val isCommentAvailable: Boolean = true
|
||||
val hideReactionWhenLocked: Boolean = false
|
||||
val isLocked: Boolean
|
||||
val showReaction: Boolean
|
||||
val showComment: Boolean
|
||||
```
|
||||
|
||||
- `isLocked = price > 0 && !existOrdered`
|
||||
- `showReaction = !hideReactionWhenLocked || !isLocked`
|
||||
- `showComment = showReaction && isCommentAvailable`
|
||||
|
||||
- [x] **RED:** `CreatorChannelHomeModelsTest`의 홈 JSON에 `isPinned=true`, `isCommentAvailable=false` 커뮤니티를 넣고 두 필드 보존을 검증한다.
|
||||
- [x] **RED:** `FeedItemTest`에 잠금 숨김 opt-in 유료 미구매는 reaction/comment 모두 false, 기본값 유료 미구매는 기존 reaction/comment 표시 유지, 댓글 불가 무료 글은 reaction true/comment false, 고정 상태 보존 케이스를 추가한다.
|
||||
- [x] **RED 확인:** 아래 명령을 실행해 신규 DTO/property 미존재로 인한 컴파일 또는 assertion 실패를 확인한다.
|
||||
|
||||
```bash
|
||||
./gradlew :app:testDebugUnitTest \
|
||||
--tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelHomeModelsTest" \
|
||||
--tests "kr.co.vividnext.sodalive.v2.widget.feed.FeedItemTest"
|
||||
```
|
||||
|
||||
- [x] **GREEN:** `CreatorChannelCommunityPostResponse`에 `@SerializedName("isPinned")`, `@SerializedName("isCommentAvailable")` 필드를 추가하고 `FeedItem.Community`에 다른 화면의 기존 표시를 유지하는 기본값 및 위 계산 property를 최소 구현한다.
|
||||
- [x] **GREEN 확인:** 같은 focused test가 PASS하는지 확인한다.
|
||||
- [x] **REFACTOR:** 신규 별도 presentation class를 만들지 않고 `FeedItem.Community` 계산 property만 유지한다.
|
||||
|
||||
- 검증 기록(2026-08-10): DTO/property 추가 전 focused test의 미존재 컴파일 RED를 확인했다. 구현 및 `P15-R3` 범위 보정 후 홈 JSON 신규 필드, 잠금 opt-in/default, 댓글 불가, 고정 상태 테스트가 최종 Gate에서 PASS했다.
|
||||
|
||||
#### Task 15.2 홈 커뮤니티 표시 연결
|
||||
|
||||
**Goal 실행 `P15-T2`:** 홈 커뮤니티 item이 잠금·댓글 가능·고정 상태를 표시하고 card 전체 상세 이동 외의 액션을 제공하지 않는다.
|
||||
|
||||
- **시작 조건:** `P15-T1` 완료.
|
||||
- **완료 증거:** `P15-T1` 정책을 실제 bind에 사용하고 resource merge/Kotlin compile PASS.
|
||||
- **범위 밖:** 커뮤니티 탭 item과 상세 메뉴.
|
||||
- **TDD 예외 사유:** XML view 위치·visibility 자체를 직접 검증하는 테스트는 저장소 규칙상 작성하지 않는다. 표시 분기는 `P15-T1` 순수 로직 test로 검증한다.
|
||||
- **대체 검증 방법:** View binding id 생성, resource merge, Kotlin compile, 기존 `FeedViewTest` 회귀를 실행한다.
|
||||
|
||||
**Files:**
|
||||
|
||||
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/ui/CreatorChannelHomeSectionAdapter.kt`
|
||||
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedCommunityView.kt`
|
||||
- Modify: `app/src/main/res/layout/view_feed_community.xml`
|
||||
- Verify: `app/src/test/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedViewTest.kt`(수정 없이 기존 회귀만 실행)
|
||||
|
||||
**Interfaces:**
|
||||
|
||||
- Consumes: `FeedItem.Community.isPinned`, `showReaction`, `showComment`.
|
||||
- Produces: `FeedCommunityView.bind(item)`의 공지/reaction 상태와 기존 `FeedCommunityView` root click 계약.
|
||||
|
||||
- [x] `CreatorChannelCommunityPostResponse.toFeedCommunityItem()`이 `isPinned`, `isCommentAvailable`을 전달하도록 수정한다.
|
||||
- [x] `view_feed_community.xml`에 커뮤니티 탭과 같은 공지 row와 reaction row/comment icon 식별 id를 추가한다.
|
||||
- [x] `FeedCommunityView.bind()`가 공지 row, reaction row, 댓글 icon/count, 하트 icon/count를 `FeedItem.Community` 계산 property로 bind하도록 수정한다.
|
||||
- [x] `CreatorChannelHomeSectionAdapter.bindCommunities()`의 `row.setOnClickListener { onCommunityClick(community.postId) }`만 item 액션으로 유지한다.
|
||||
- [x] 아래 명령으로 focused 회귀 및 compile을 확인한다.
|
||||
|
||||
```bash
|
||||
./gradlew :app:testDebugUnitTest \
|
||||
--tests "kr.co.vividnext.sodalive.v2.widget.feed.FeedItemTest" \
|
||||
--tests "kr.co.vividnext.sodalive.v2.widget.feed.FeedViewTest"
|
||||
./gradlew :app:mergeDebugResources :app:compileDebugKotlin
|
||||
```
|
||||
|
||||
- 검증 기록(2026-08-10): 홈 mapper/bind/root click을 정적 대조했고 `P15-R2`에서 reaction id 위치를 정정했다. `FeedItemTest`, `FeedViewTest`, resource merge, Kotlin compile이 PASS했다.
|
||||
|
||||
#### Task 15.3 커뮤니티 탭 상세 이동 전용화와 가격 UI 통일
|
||||
|
||||
**Goal 실행 `P15-T3`:** 커뮤니티 탭 리스트/그리드 item 액션을 상세 이동 하나로 제한하고 잠금 가격 UI를 홈/상세 구조로 통일한다.
|
||||
|
||||
- **시작 조건:** 기존 list/grid `onPostClick` 상세 routing 계약 확인.
|
||||
- **완료 증거:** play/owner-more callback 제거, list/grid root 상세 이동 유지, mapper/routing focused test 및 compile PASS.
|
||||
- **범위 밖:** 상세 화면 내부 구매·메뉴 동작.
|
||||
|
||||
**Files:**
|
||||
|
||||
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityFragment.kt`
|
||||
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/model/CreatorChannelCommunityUiModels.kt`
|
||||
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/model/CreatorChannelCommunityMappers.kt`
|
||||
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/ui/CreatorChannelCommunityListAdapter.kt`
|
||||
- Modify: `app/src/main/res/layout/item_creator_channel_community_list.xml`
|
||||
- Verify only: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/ui/CreatorChannelCommunityGridAdapter.kt`
|
||||
- Verify only: `app/src/main/res/layout/item_creator_channel_community_grid.xml`
|
||||
- Test: `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityMapperTest.kt`
|
||||
- Test: `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityFragmentLayoutTest.kt`
|
||||
|
||||
**Interfaces:**
|
||||
|
||||
- Consumes: `CreatorChannelCommunityPostUiModel.postId`, `price`, `isLocked`, `showOwnerTopPrice`.
|
||||
- Produces: list/grid adapter constructor의 단일 item callback `onPostClick: (CreatorChannelCommunityPostUiModel) -> Unit`.
|
||||
|
||||
- [x] **RED:** routing/source 계약 테스트에 Fragment/list adapter가 `onPlayClick`, `onOwnerMoreClick`, `toggleCommunityAudio`, `onCreatorChannelCommunityOwnerMoreClicked`를 갖지 않고 list/grid root가 `onPostClick`만 호출한다는 케이스를 추가한다.
|
||||
- [x] **RED 확인:** 아래 명령으로 현재 하위 액션이 남아 있어 실패함을 확인한다.
|
||||
|
||||
```bash
|
||||
./gradlew :app:testDebugUnitTest \
|
||||
--tests "kr.co.vividnext.sodalive.v2.creator.channel.community.CreatorChannelCommunityMapperTest" \
|
||||
--tests "kr.co.vividnext.sodalive.v2.creator.channel.community.CreatorChannelCommunityFragmentLayoutTest"
|
||||
```
|
||||
|
||||
- [x] **GREEN:** Fragment의 media player lifecycle/재생 함수와 Host owner-more callback, list adapter의 play/owner-more callback 및 더보기 view를 제거한다.
|
||||
- [x] **GREEN:** UI model/mapper에서 이번 변경으로 미사용이 된 `audioUrl`, `showPlayButton`, `showOwnerMore`만 제거하고 작성자 상단 가격인 `showOwnerTopPrice`는 유지한다.
|
||||
- [x] **GREEN:** 기존 Fragment/layout/source test에서 제거된 play/owner-more의 positive assertion만 삭제하거나 상세 이동 단일 callback의 negative assertion으로 교체한다. View 크기·간격·constraint·visibility 속성 assertion은 새로 추가하지 않는다.
|
||||
- [x] **GREEN:** 리스트 잠금 금액의 compound drawable `TextView`를 그리드/상세와 같은 별도 `ImageView(ic_bar_cash)` + 금액 `TextView` capsule 구조로 변경한다.
|
||||
- [x] **GREEN:** 그리드는 이미 `lock icon + cash icon + 금액 capsule` 구조와 root 상세 이동만 사용하므로 신규 production 변경 없이 계약 일치만 확인한다.
|
||||
- [x] **GREEN 확인:** focused test, `./gradlew :app:mergeDebugResources :app:compileDebugKotlin`을 실행한다.
|
||||
- [x] **REFACTOR:** play/owner-more 제거로 생긴 import·binding·Host 구현 orphan만 삭제하고 다른 탭 코드는 정리하지 않는다.
|
||||
|
||||
- 검증 기록(2026-08-10): 하위 액션 제거 계약의 4개 RED 실패를 확인한 뒤 list/grid root `onPostClick`만 유지했다. mapper/layout focused test, resource merge, Kotlin compile과 최종 Gate가 PASS했다.
|
||||
|
||||
#### Task 15.4 상세 더보기 권한과 게시글 mutation
|
||||
|
||||
**Goal 실행 `P15-T4`:** 상세 작성자 영역 우측 끝에서 권한별 관리/신고 메뉴를 제공하고 성공/실패 상태를 정확히 전파한다.
|
||||
|
||||
- **시작 조건:** 상세 DTO의 `creatorId`, `price`, `existOrdered`, `isPinned` 계약과 기존 레거시 dialog/API 확인.
|
||||
- **완료 증거:** 더보기 노출 4개 권한 케이스, 고정/삭제/신고 API와 event focused test PASS, resource merge/compile PASS.
|
||||
- **범위 밖:** 홈/커뮤니티 탭 새로고침 실행.
|
||||
|
||||
**Files:**
|
||||
|
||||
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/detail/CreatorChannelCommunityDetailViewModel.kt`
|
||||
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/detail/CreatorChannelCommunityDetailActivity.kt`
|
||||
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/data/CreatorChannelRepository.kt`
|
||||
- Modify: `app/src/main/res/layout/activity_creator_channel_community_detail.xml`
|
||||
- Test: `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityDetailViewModelTest.kt`
|
||||
- Test: `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityDetailReplyUiContractTest.kt`
|
||||
|
||||
**Interfaces:**
|
||||
|
||||
- Produces UI model fields:
|
||||
|
||||
`CreatorChannelCommunityPostDetailUiModel`에 추가할 member:
|
||||
|
||||
```kotlin
|
||||
val isOwner: Boolean
|
||||
val showMore: Boolean
|
||||
```
|
||||
|
||||
- `isOwner = creatorId == SharedPreferenceManager.userId`
|
||||
- `showMore = isOwner || price == 0 || existOrdered`
|
||||
- Produces ViewModel methods/events:
|
||||
|
||||
```kotlin
|
||||
fun updateCommunityPostFixed()
|
||||
fun deleteCommunityPost()
|
||||
fun reportCommunityPost(reason: String)
|
||||
val postDeletedEventLiveData: LiveData<Boolean>
|
||||
```
|
||||
|
||||
- Produces repository method:
|
||||
|
||||
```kotlin
|
||||
fun reportCommunityPost(postId: Long, reason: String, token: String)
|
||||
```
|
||||
|
||||
- [x] **RED:** 상세 ViewModel test에 작성자 유료 미구매=true, 일반 무료=true, 일반 유료 구매=true, 일반 유료 미구매=false인 `showMore` 케이스를 추가한다.
|
||||
- [x] **RED:** 고정 성공은 `isPinned` 반전 요청 후 상세 재조회와 `postChangedEventLiveData=true`, 삭제 성공은 `postDeletedEventLiveData=true`, 신고는 `ReportType.COMMUNITY_POST` repository 호출만 수행하는 케이스를 추가한다.
|
||||
- [x] **RED:** UI 계약 test에 `R.id.btn_creator_channel_community_detail_more` resource와 Activity의 modify launcher/기존 BottomSheet·신고 dialog 연결 계약을 추가한다. 위치·constraint·visibility 값은 test에서 직접 검증하지 않는다.
|
||||
- [x] **RED 확인:** 아래 명령으로 신규 fields/methods 미존재 실패를 확인한다.
|
||||
|
||||
```bash
|
||||
./gradlew :app:testDebugUnitTest --tests \
|
||||
"kr.co.vividnext.sodalive.v2.creator.channel.community.CreatorChannelCommunityDetailViewModelTest"
|
||||
```
|
||||
|
||||
- [x] **GREEN:** `CreatorChannelRepository.reportCommunityPost()`가 `ReportRequest(ReportType.COMMUNITY_POST, reason, communityPostId = postId)`를 기존 `ReportRepository`에 위임하도록 추가한다.
|
||||
- [x] **GREEN:** DetailViewModel의 고정은 `updateCommunityPostFixed(postId, !content.post.isPinned, authToken())`, 삭제는 `ModifyCommunityPostRequest(creatorCommunityId = postId, isActive = false)`를 JSON `text/plain` RequestBody로 변환한 `modifyCommunityPost(postImage = null, ...)`, 신고는 신규 report method를 호출한다. 각 mutation의 중복 요청을 막고 실패 시 기존 Toast event만 내보낸다.
|
||||
- [x] **GREEN:** 신고 성공은 API message 또는 기존 `character_comment_report_submitted` 문구를 Toast event로 전달하고 게시글 변경 event는 내보내지 않는다.
|
||||
- [x] **GREEN:** 상세 layout에서 `layout_creator_channel_community_detail_price`와 `tv_creator_channel_community_detail_purchased`를 제거하고, 작성자 영역 우측 끝에 `@drawable/ic_seemore_vertical`, `@string/read_more` content description을 사용하는 `btn_creator_channel_community_detail_more`를 추가한다. 닉네임/작성 시간의 end constraint는 이 버튼 start에 연결한다.
|
||||
- [x] **GREEN:** Activity는 `post.showMore`로 더보기 버튼 visibility를 bind한다.
|
||||
- [x] **GREEN:** Activity에서 `CreatorCommunityPostMenuBottomSheetDialog`를 열어 작성자는 수정/삭제/고정, 일반 사용자는 신고를 연결한다. 수정은 기존 `CreatorCommunityModifyActivity`, 삭제 확인은 `V2ModalDialog`, 신고 입력은 `CreatorCommunityReportDialog`를 재사용한다.
|
||||
- [x] **GREEN:** 상세 paywall의 `PurchaseCommunityPostDialog -> purchaseCommunityPost()` 연결은 유지하고 홈/커뮤니티 탭에는 구매 호출부가 없음을 확인한다.
|
||||
- [x] **GREEN:** 수정 Activity `RESULT_OK`와 고정 성공 시 상세를 재조회하고 상위 `RESULT_OK`를 설정하며, 삭제 event 수신 시 `RESULT_OK` 설정 후 상세를 종료한다.
|
||||
- [x] **GREEN 확인:** focused test, `./gradlew :app:mergeDebugResources :app:compileDebugKotlin`을 실행한다.
|
||||
- [x] **REFACTOR:** 신규 menu abstraction 또는 별도 popup을 만들지 않고 기존 BottomSheet/Dialog를 직접 재사용한다.
|
||||
|
||||
- 검증 기록(2026-08-10): 신규 fields/methods/resource 미존재 RED를 확인한 뒤 권한 truth table, 고정·삭제·신고 성공/실패·중복 guard, 기존 dialog 재사용과 결과 전파를 구현했다. 커뮤니티 focused test와 resource/compile Gate가 PASS했다.
|
||||
|
||||
#### Task 15.5 상위 새로고침 전파와 목록 메뉴 orphan 제거
|
||||
|
||||
**Goal 실행 `P15-T5`:** 상세 변경 결과가 홈·커뮤니티 탭을 함께 갱신하고 목록에 남은 관리 메뉴 코드를 제거한다.
|
||||
|
||||
- **시작 조건:** `P15-T3`, `P15-T4` 완료.
|
||||
- **완료 증거:** 상세 `RESULT_OK -> CommunityChange.Updated -> 홈+커뮤니티 refresh` routing test PASS, 제거된 callback 관련 compile PASS.
|
||||
- **범위 밖:** 신고 후 새로고침, 다른 creator channel 탭.
|
||||
|
||||
**Files:**
|
||||
|
||||
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt`
|
||||
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/community/action/CommunityChange.kt`
|
||||
- Test: `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivitySourceTest.kt`
|
||||
- Test: `app/src/test/java/kr/co/vividnext/sodalive/v2/community/action/CommunityChangeTest.kt`
|
||||
|
||||
**Interfaces:**
|
||||
|
||||
- Consumes: `resolveCommunityActivityResult(CommunityActivityResultSource.Detail, RESULT_OK) == CommunityChange.Updated`.
|
||||
- Produces: `CommunityChange.Updated` 처리 시 `homeActionDelegate?.refreshHome()`과 `refreshCreatorChannelCommunity()` 호출.
|
||||
|
||||
- [x] **RED:** `CreatorChannelActivitySourceTest`에 상세 `Updated` 처리 블록이 홈/커뮤니티 refresh를 모두 호출한다는 routing 계약을 추가한다.
|
||||
- [x] **RED 확인:** 아래 명령으로 현재 `Updated`가 커뮤니티만 refresh하고 목록 전용 change가 남아 있어 실패함을 확인한다.
|
||||
|
||||
```bash
|
||||
./gradlew :app:testDebugUnitTest \
|
||||
--tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest" \
|
||||
--tests "kr.co.vividnext.sodalive.v2.community.action.CommunityChangeTest"
|
||||
```
|
||||
|
||||
- [x] **GREEN:** `handleCommunityChange(Updated)`가 홈과 커뮤니티를 함께 갱신하도록 변경한다.
|
||||
- [x] **GREEN:** 목록 owner-more 제거로 미사용이 된 `communityPostModifyLauncher`, `onCreatorChannelCommunityOwnerMoreClicked`, 목록용 고정/삭제/dialog 함수와 관련 import/repository 의존을 `CreatorChannelActivity`에서 제거한다.
|
||||
- [x] **GREEN:** 호출자가 사라진 `CommunityChange.Deleted`, `CommunityChange.PinChanged`를 제거하고 `CommunityChangeTest`의 삭제/고정 전용 케이스만 제거한다. `Write -> Created`, `Modify/Detail -> Updated`, 취소 -> `Ignored` 회귀는 유지한다.
|
||||
- [x] **GREEN 확인:** focused test와 `./gradlew :app:compileDebugKotlin`을 실행한다.
|
||||
- [x] **REFACTOR:** 다른 화면에서 사용 중인 `CommunityActionCommand.PostDetail`, `CommunityChange.Created/Updated`는 유지한다.
|
||||
|
||||
- 검증 기록(2026-08-10): routing RED 2건을 확인한 뒤 상세 `RESULT_OK`의 `Updated` 처리에서 홈·커뮤니티를 함께 갱신하고 목록 메뉴 orphan을 제거했다. Activity/action focused test와 Kotlin compile이 PASS했다.
|
||||
|
||||
#### Task 15.R1 목록 메뉴 제거 후 미사용 import 정리
|
||||
|
||||
**Goal 실행 `P15-R1`:** 확정 review 항목 `REV-P15-001`의 미사용 import를 제거해 Phase 15 style Gate를 회복한다.
|
||||
|
||||
- **시작 조건:** `REV-P15-001` 확정, `P15-T5` 목록 메뉴/orphan 제거 완료.
|
||||
- **대상 파일:** `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt`
|
||||
- **수정 범위:** `SharedPreferenceManager` 미사용 import 1줄 제거.
|
||||
- **회귀 테스트:** `./gradlew :app:ktlintCheck`, Phase 15 Gate 전체.
|
||||
- **완료 증거:** RED ktlint 정확한 1건 → import 제거 → ktlint/Gate PASS → review 보고서 수정 후 검증 누적.
|
||||
- **범위 밖:** 다른 import 순서, 관련 없는 style 정리, `.editorconfig` deprecation 경고.
|
||||
|
||||
- [x] `./gradlew :app:ktlintCheck`에서 `CreatorChannelActivity.kt:29:1 Unused import`만 확정된 RED를 기록한다.
|
||||
- [x] `SharedPreferenceManager` import 1줄만 제거한다.
|
||||
- [x] `./gradlew :app:ktlintCheck`와 Phase 15 Gate를 재실행한다.
|
||||
- [x] `plan-task.md` Verification Log와 `phase15-community-purchase-detail-menu-review.md`에 완료 증거를 누적한다.
|
||||
|
||||
- 검증 기록(2026-08-10): 최초 Gate에서 `CreatorChannelActivity.kt:29:1 Unused import` RED를 확인하고 해당 import 1줄만 제거했다. 최종 `ktlintCheck`와 Phase 15 Gate가 PASS했다.
|
||||
|
||||
#### Task 15.R2 홈 reaction row binding 대상 정정
|
||||
|
||||
**Goal 실행 `P15-R2`:** 확정 review 항목 `REV-P15-002`의 잘못된 `ll_feed_community_reaction` id 위치를 정정해 유료 미구매 홈 item의 reaction UI만 숨긴다.
|
||||
|
||||
- **시작 조건:** `REV-P15-002` 확정, `P15-T2` 표시 정책 구현 완료.
|
||||
- **대상 파일:** `app/src/main/res/layout/view_feed_community.xml`
|
||||
- **수정 범위:** `ll_feed_community_reaction` id를 작성자 row에서 하트·댓글 reaction row로 이동.
|
||||
- **회귀 검증:** `FeedItemTest`, `FeedViewTest`, `:app:mergeDebugResources`, `:app:compileDebugKotlin`, Phase 15 Gate, XML tree 정적 재확인.
|
||||
- **완료 증거:** 수정 전 XML tree에서 id가 프로필 row를 가리키는 근거 → id 1개 이동 → focused 회귀/Gate PASS → 리뷰 보고서 누적.
|
||||
- **TDD 예외 사유:** 저장소 규칙상 View visibility·layout 속성을 직접 검증하는 신규 테스트를 추가하지 않는다. 표시 분기는 기존 `FeedItemTest`, binding/resource는 resource merge·compile·정적 XML tree 검토로 대체한다.
|
||||
- **범위 밖:** 홈 card 간격·크기·제약, 다른 row 레이아웃.
|
||||
|
||||
- [x] 수정 전 `ll_feed_community_reaction` id가 프로필 row에 있고 실제 reaction row에는 id가 없는 근거를 기록한다.
|
||||
- [x] id를 실제 reaction row로 이동한다.
|
||||
- [x] focused 회귀, resource merge/compile, Phase 15 Gate를 재실행한다.
|
||||
- [x] `plan-task.md` Verification Log와 review 보고서에 완료 증거를 누적한다.
|
||||
|
||||
- 검증 기록(2026-08-10): 수정 전 id가 프로필 row에 연결되고 실제 reaction row에는 없음을 XML tree로 확인했다. id 1개를 실제 reaction row로 이동한 뒤 focused test, resource merge, Kotlin compile과 최종 Gate가 PASS했다.
|
||||
|
||||
#### Task 15.R3 공유 FeedItem reaction 정책 범위 정정
|
||||
|
||||
**Goal 실행 `P15-R3`:** 확정 review 항목 `REV-P15-003`의 공유 모델 회귀를 제거해 크리에이터 채널 홈에서만 유료 미구매 reaction을 숨기고 다른 `FeedItem.Community` 호출부는 기존 표시 동작을 유지한다.
|
||||
|
||||
- **시작 조건:** `REV-P15-003` 확정, `P15-T1`~`P15-T2` 표시 정책 구현 완료.
|
||||
- **대상 파일:** `app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedItem.kt`, `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/ui/CreatorChannelHomeSectionAdapter.kt`, `app/src/test/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedItemTest.kt`, `app/src/test/java/kr/co/vividnext/sodalive/v2/main/home/HomeMainFragmentLayoutTest.kt`
|
||||
- **수정 범위:** `FeedItem.Community` 신규 정책은 기본값으로 기존 reaction을 유지하고, 크리에이터 채널 홈 mapper만 잠금 시 숨김을 명시하도록 제한.
|
||||
- **회귀 테스트:** 잠금 item의 기본값은 reaction/comment 표시 유지, 크리에이터 채널 홈 opt-in은 reaction/comment 숨김, 기존 댓글 불가·고정 상태 테스트, Phase 15 Gate.
|
||||
- **완료 증거:** 메인 홈 인기 커뮤니티 mapper와 공유 `FeedCommunityView` 호출 경로 확인 → 기본값 회귀 테스트 RED → 최소 opt-in 구현 → focused 회귀/Gate PASS → 리뷰 보고서 누적.
|
||||
- **범위 밖:** 메인 홈 인기 커뮤니티의 이미지 잠금/가격 정책, 다른 feed UI 변경.
|
||||
|
||||
- [x] 메인 홈 인기 커뮤니티가 `price`, `existOrdered`를 전달하고 공유 `FeedCommunityView.bind()`를 사용해 기존 reaction까지 숨겨지는 호출 경로를 기록한다.
|
||||
- [x] **RED:** 잠금 유료 `FeedItem.Community`가 신규 정책 기본값에서는 기존 reaction/comment 표시를 유지하고, opt-in에서는 둘 다 숨기는 회귀 테스트를 추가해 실패를 확인한다.
|
||||
- [x] **GREEN:** 신규 정책 기본값은 기존 표시를 유지하고 `CreatorChannelHomeSectionAdapter`만 잠금 reaction 숨김을 선택하도록 최소 수정한다.
|
||||
- [x] focused 회귀와 Phase 15 Gate를 재실행한다.
|
||||
- [x] `plan-task.md` Verification Log와 review 보고서에 완료 증거를 누적한다.
|
||||
|
||||
- 검증 기록(2026-08-10): `HomeRecommendationMappers -> FeedItem.Community -> HomePopularCommunityAdapter -> FeedCommunityView.bind()` 호출 경로로 공유 정책 회귀를 확정했다. `hideReactionWhenLocked` 미존재 컴파일 RED 후 기본값 false, 크리에이터 채널 홈 true로 제한했고 `FeedItemTest`, 메인 홈 mapper 회귀 테스트와 최종 Gate가 PASS했다.
|
||||
|
||||
#### Task 15.R4 메인 홈 회귀 테스트 파일 미사용 import 정리
|
||||
|
||||
**Goal 실행 `P15-R4`:** 확정 review 항목 `REV-P15-004`의 미사용 import를 제거해 Phase 15 style Gate를 회복한다.
|
||||
|
||||
- **시작 조건:** `P15-R3` 메인 홈 회귀 테스트 추가 후 `ktlintCheck` 실패 확정.
|
||||
- **대상 파일:** `app/src/test/java/kr/co/vividnext/sodalive/v2/main/home/HomeMainFragmentLayoutTest.kt`
|
||||
- **수정 범위:** 실제 사용처가 없는 `ColorDrawable` import 1줄 제거.
|
||||
- **회귀 검증:** `./gradlew :app:ktlintCheck`, Phase 15 Gate, `git diff --check`.
|
||||
- **완료 증거:** ktlint 정확한 unused import 1건 → import 제거 → ktlint/Gate PASS → 리뷰 보고서 누적.
|
||||
- **범위 밖:** 같은 테스트 파일의 기존 구조·deprecated API 정리.
|
||||
|
||||
- [x] `ktlintCheck`의 `HomeMainFragmentLayoutTest.kt:6:1 Unused import` RED를 기록한다.
|
||||
- [x] `ColorDrawable` import 1줄만 제거한다.
|
||||
- [x] `ktlintCheck`와 Phase 15 Gate를 재실행한다.
|
||||
- [x] `plan-task.md` Verification Log와 review 보고서에 완료 증거를 누적한다.
|
||||
|
||||
- 검증 기록(2026-08-10): 메인 홈 회귀 테스트 추가 후 lint 대상이 된 파일에서 사용처 없는 `ColorDrawable` import 1건을 확인해 제거했다. 최종 `ktlintCheck`와 전체 focused test Gate가 PASS했다.
|
||||
|
||||
#### Phase 15 Gate
|
||||
|
||||
**Goal 실행 `P15-GATE`:** 승인된 홈/탭/상세 사용자 흐름과 회귀 방지를 최종 판정한다.
|
||||
|
||||
- **시작 조건:** `P15-T1`~`P15-T5` 완료.
|
||||
- **완료 증거:** 아래 명령을 순차 실행해 모두 exit code 0을 확인하고 각 Task 검증 기록 및 `Verification Log`에 실제 결과를 누적한다.
|
||||
- **범위 밖:** `app/src/androidTest`, `connectedDebugAndroidTest`, 기기·에뮬레이터 조작, 스크린샷·시각 QA, Git commit.
|
||||
|
||||
```bash
|
||||
./gradlew :app:testDebugUnitTest \
|
||||
--tests "kr.co.vividnext.sodalive.v2.widget.feed.FeedItemTest" \
|
||||
--tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelHomeModelsTest" \
|
||||
--tests "kr.co.vividnext.sodalive.v2.main.home.HomeMainFragmentLayoutTest"
|
||||
./gradlew :app:testDebugUnitTest \
|
||||
--tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*" \
|
||||
--tests "kr.co.vividnext.sodalive.v2.community.action.*"
|
||||
./gradlew :app:testDebugUnitTest --tests \
|
||||
"kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"
|
||||
./gradlew :app:mergeDebugResources
|
||||
./gradlew :app:compileDebugKotlin
|
||||
./gradlew :app:ktlintCheck
|
||||
git diff --check
|
||||
```
|
||||
|
||||
**Expected:** 홈 Response 신규 필드와 reaction/pin 정책, list/grid 상세 이동 전용화, 상세 더보기 권한·구매/관리/신고, 상세 변경 후 홈+커뮤니티 refresh 관련 focused test PASS. 리소스 병합·Kotlin 컴파일·ktlint·diff whitespace 검증 PASS.
|
||||
|
||||
#### Phase 15 실행 순서
|
||||
|
||||
```text
|
||||
P15-T1 → P15-T2 → P15-T3 → P15-T4 → P15-T5 → P15-R1 → P15-R2 → P15-R3 → P15-R4 → P15-GATE
|
||||
```
|
||||
|
||||
#### Phase 15 계획 기록 — 2026-08-10
|
||||
|
||||
- 상태: 계획 완료 / 구현 미시작
|
||||
- 무엇을: 승인된 PRD `F0-20260810`을 `P15-T1`~`P15-T5`, `P15-GATE`로 분해했다.
|
||||
- 왜: 홈·커뮤니티 탭의 표시/액션 일관성과 상세 구매·메뉴·결과 전파를 구현 전에 검증 가능한 단위로 고정하기 위해서다.
|
||||
- 어떻게:
|
||||
- `git diff --check` — 문서 변경 whitespace 검증 PASS.
|
||||
- `./gradlew tasks --all` — exit code 0, `BUILD SUCCESSFUL`.
|
||||
- 남은 항목: Phase 15 구현 전체. 사용자 지시에 따라 이번 작업에서는 수행하지 않는다.
|
||||
- 다음 행동: 사용자가 구현을 별도로 요청하면 `P15-T1` RED부터 순차 실행한다.
|
||||
|
||||
#### Phase 15 구현·검증 기록 — 2026-08-10
|
||||
|
||||
- 상태: 구현 및 검증 완료 / Git commit 미수행
|
||||
- 무엇을: `P15-T1`~`P15-T5`를 구현하고 리뷰 확정 항목 `P15-R1`~`P15-R4`를 수정했다.
|
||||
- 왜: 미체크 항목이 구현 누락이었음을 코드·테스트 대조로 확인했고, 구현 후 독립 리뷰와 Gate에서 실제 회귀·style 문제를 확인했기 때문이다.
|
||||
- 어떻게:
|
||||
- 홈 Response에 `isPinned`, `isCommentAvailable`을 연결하고 크리에이터 채널 홈만 유료 미구매 reaction 숨김을 opt-in했다.
|
||||
- 홈·커뮤니티 탭 item 액션을 상세 이동으로 제한하고 상세에 구매·권한별 더보기·변경 결과 전파를 모았다.
|
||||
- `REV-P15-001`~`REV-P15-004`를 각각 회귀 Task로 전환한 뒤 최소 수정했다.
|
||||
- 전체 focused local unit/source contract test, resource merge, Kotlin compile, ktlint를 최종 working tree에서 재실행해 `BUILD SUCCESSFUL`을 확인했고 `git diff --check`, `git diff HEAD --check`는 출력 없이 PASS했다.
|
||||
- 제외: 저장소 규칙과 사용자 지시에 따라 `app/src/androidTest`, 기기·에뮬레이터 조작, 스크린샷·시각 QA, Git commit은 수행하지 않았다.
|
||||
- 남은 항목: 실제 서버 Response 배포 상태와 기기 수동 UI 확인은 이번 자동 검증 범위 밖이다.
|
||||
|
||||
## Phase 16 — 홈·커뮤니티 리스트 권한별 더보기 메뉴
|
||||
|
||||
**Phase 결과:** 상세와 동일한 권한별 게시글 더보기 메뉴를 홈 커뮤니티 item과 커뮤니티 탭 리스트형에서 사용할 수 있고, 성공한 관리 작업은 두 목록에 함께 반영된다.
|
||||
|
||||
**선행조건:** 승인된 PRD `Home and Community List More Menu Requirements`, Phase 15 구현·검증 완료.
|
||||
|
||||
**Phase 완료 조건:** `P16-T1`~`P16-T3`, `P16-GATE` 완료와 Task별 검증 기록 및 `Verification Log` 누적.
|
||||
|
||||
### 범위
|
||||
|
||||
**포함**
|
||||
|
||||
- 홈 커뮤니티 item과 커뮤니티 탭 리스트형 작성자 영역 우측 끝 `ic_seemore_vertical` 버튼.
|
||||
- 상세와 동일한 작성자/무료/구매 완료/유료 미구매 권한 truth table.
|
||||
- 작성자 수정·삭제·고정/고정 해제, 일반 사용자 신고.
|
||||
- 성공한 수정·삭제·고정/고정 해제 후 홈+커뮤니티 새로고침.
|
||||
- card 본문 상세 이동과 더보기 메뉴 click 분리.
|
||||
|
||||
**제외**
|
||||
|
||||
- 커뮤니티 탭 썸네일형(그리드형) 더보기 버튼.
|
||||
- 목록에서 유료 게시글 구매·오디오 재생.
|
||||
- 상세 메뉴 구조 변경, 레거시 파일 수정, 신규 범용 coordinator/dependency.
|
||||
- `app/src/androidTest`, 기기·에뮬레이터 조작, 스크린샷·시각 QA, Git commit.
|
||||
|
||||
### Task 16.1 공용 메뉴 권한 presentation 계약
|
||||
|
||||
**Goal 실행 `P16-T1`:** 홈과 커뮤니티 리스트가 동일한 메뉴 payload와 권한 계산을 사용하고 다른 공유 feed는 기존 표시를 유지한다.
|
||||
|
||||
- **시작 조건:** PRD 권한 truth table 승인.
|
||||
- **완료 증거:** 메뉴 권한 4개 케이스와 홈/커뮤니티 mapper focused test PASS.
|
||||
- **범위 밖:** 버튼 layout/click, Activity menu/API 실행.
|
||||
|
||||
**Files:**
|
||||
|
||||
- Create: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/model/CreatorChannelCommunityMenuItem.kt`
|
||||
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/model/CreatorChannelCommunityUiModels.kt`
|
||||
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/model/CreatorChannelCommunityMappers.kt`
|
||||
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/model/CreatorChannelHomeUiModels.kt`
|
||||
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/model/CreatorChannelHomeMappers.kt`
|
||||
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedItem.kt`
|
||||
- Test: `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityMapperTest.kt`
|
||||
- Test: `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelHomeMapperTest.kt`
|
||||
- Test: `app/src/test/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedItemTest.kt`
|
||||
|
||||
**Interfaces:**
|
||||
|
||||
```kotlin
|
||||
data class CreatorChannelCommunityMenuItem(
|
||||
val postId: Long,
|
||||
val creatorId: Long,
|
||||
val currentUserId: Long,
|
||||
val price: Int,
|
||||
val existOrdered: Boolean,
|
||||
val isPinned: Boolean
|
||||
) {
|
||||
val isOwner: Boolean
|
||||
val showMore: Boolean
|
||||
}
|
||||
```
|
||||
|
||||
- `isOwner = creatorId == currentUserId`
|
||||
- `showMore = isOwner || price == 0 || existOrdered`
|
||||
- `CreatorChannelCommunityPostUiModel`은 `menuItem: CreatorChannelCommunityMenuItem`을 제공한다.
|
||||
- `CreatorChannelHomeSection.Communities`는 `currentMemberId: Long`을 함께 보존해 adapter가 같은 menu item을 만든다.
|
||||
- `FeedItem.Community`는 `showMore: Boolean = false`를 추가해 다른 공유 feed 호출부의 기존 동작을 유지한다.
|
||||
|
||||
- [x] **RED:** `CreatorChannelCommunityMapperTest`에 작성자 유료 미구매=true, 일반 무료=true, 일반 유료 구매=true, 일반 유료 미구매=false인 `menuItem.showMore`와 `isPinned` 보존 케이스를 추가한다.
|
||||
- [x] **RED:** `CreatorChannelHomeMapperTest`에 `Communities.currentMemberId` 보존, `FeedItemTest`에 `showMore` 기본값 false 회귀를 추가한다.
|
||||
- [x] **RED 확인:** 아래 명령을 실행해 신규 type/property 미존재 컴파일 실패를 확인한다.
|
||||
|
||||
```bash
|
||||
./gradlew :app:testDebugUnitTest \
|
||||
--tests "kr.co.vividnext.sodalive.v2.creator.channel.community.CreatorChannelCommunityMapperTest" \
|
||||
--tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelHomeMapperTest" \
|
||||
--tests "kr.co.vividnext.sodalive.v2.widget.feed.FeedItemTest"
|
||||
```
|
||||
|
||||
- [x] **GREEN:** 위 `CreatorChannelCommunityMenuItem` 계산 property를 추가하고 커뮤니티 mapper/UI model과 홈 `Communities.currentMemberId`를 연결한다.
|
||||
- [x] **GREEN:** `FeedItem.Community.showMore`를 기본값 false로 추가한다.
|
||||
- [x] **GREEN 확인:** 같은 focused test가 PASS하는지 확인한다.
|
||||
- [x] **REFACTOR:** 별도 권한 service/factory를 만들지 않고 menu item 계산 property 하나만 공용 정책으로 유지한다.
|
||||
|
||||
- 검증 기록(2026-08-10): `menuItem`, `currentMemberId`, `showMore` 미존재로 `compileDebugUnitTestKotlin` RED 실패를 확인했다. `CreatorChannelCommunityMenuItem` 계산 property와 커뮤니티/홈 mapper 연결, `FeedItem.Community.showMore=false` 기본값을 최소 구현한 뒤 지정된 focused test 26개가 모두 PASS했다. 명세·코드 품질 독립 검토에서도 차단 이슈가 없음을 확인했다.
|
||||
|
||||
### Task 16.2 홈·커뮤니티 리스트 더보기 버튼과 callback
|
||||
|
||||
**Goal 실행 `P16-T2`:** 홈 커뮤니티 item과 커뮤니티 리스트형의 더보기 버튼이 card 상세 이동과 분리된 공용 menu callback을 호출한다.
|
||||
|
||||
- **시작 조건:** `P16-T1` 완료.
|
||||
- **완료 증거:** 홈/리스트 callback routing focused test, resource merge, Kotlin compile PASS와 grid 무변경 확인.
|
||||
- **범위 밖:** BottomSheet 표시와 mutation API.
|
||||
- **TDD 예외 사유:** 버튼 위치·constraint·visibility 속성 자체는 저장소 규칙상 자동 테스트에서 직접 검증하지 않는다.
|
||||
- **대체 검증 방법:** 권한 visibility는 `P16-T1` 순수 로직 test, callback은 click/source contract test, UI resource는 id 존재·resource merge·compile·정적 XML tree 대조로 검증한다.
|
||||
|
||||
**Files:**
|
||||
|
||||
- Modify: `app/src/main/res/layout/view_feed_community.xml`
|
||||
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedCommunityView.kt`
|
||||
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/ui/CreatorChannelHomeSectionAdapter.kt`
|
||||
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelHomeFragment.kt`
|
||||
- Modify: `app/src/main/res/layout/item_creator_channel_community_list.xml`
|
||||
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/ui/CreatorChannelCommunityListAdapter.kt`
|
||||
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityFragment.kt`
|
||||
- Verify only: `app/src/main/res/layout/item_creator_channel_community_grid.xml`
|
||||
- Verify only: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/ui/CreatorChannelCommunityGridAdapter.kt`
|
||||
- Test: `app/src/test/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedViewTest.kt`
|
||||
- Test: `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityFragmentLayoutTest.kt`
|
||||
- Test: `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivitySourceTest.kt`
|
||||
|
||||
**Interfaces:**
|
||||
|
||||
```kotlin
|
||||
fun FeedCommunityView.setOnMoreClick(listener: ((FeedItem.Community) -> Unit)?)
|
||||
|
||||
CreatorChannelHomeSectionAdapter(
|
||||
onCommunityClick: (Long) -> Unit,
|
||||
onCommunityMoreClick: (CreatorChannelCommunityMenuItem) -> Unit
|
||||
)
|
||||
|
||||
CreatorChannelCommunityListAdapter(
|
||||
onPostClick: (CreatorChannelCommunityPostUiModel) -> Unit,
|
||||
onMoreClick: (CreatorChannelCommunityMenuItem) -> Unit
|
||||
)
|
||||
|
||||
fun onCreatorChannelCommunityMoreClicked(item: CreatorChannelCommunityMenuItem)
|
||||
```
|
||||
|
||||
- [x] **RED:** `FeedViewTest`에 `btn_feed_community_more` resource와 `setOnMoreClick`이 bound item만 전달하는 callback 케이스를 추가한다.
|
||||
- [x] **RED:** `CreatorChannelCommunityFragmentLayoutTest`와 `CreatorChannelActivitySourceTest`에 홈/리스트 adapter → Fragment Host의 동일 menu callback, list root 상세 click 유지, grid menu callback 부재 계약을 추가한다.
|
||||
- [x] **RED 확인:** 아래 명령으로 신규 resource/API/callback 미존재 실패를 확인한다.
|
||||
|
||||
```bash
|
||||
./gradlew :app:testDebugUnitTest \
|
||||
--tests "kr.co.vividnext.sodalive.v2.widget.feed.FeedViewTest" \
|
||||
--tests "kr.co.vividnext.sodalive.v2.creator.channel.community.CreatorChannelCommunityFragmentLayoutTest" \
|
||||
--tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"
|
||||
```
|
||||
|
||||
- [x] **GREEN:** `view_feed_community.xml` 작성자 row를 전체 폭으로 유지하고 우측 끝에 42dp `btn_feed_community_more`(`ic_seemore_vertical`, `read_more`)를 추가한다. `FeedCommunityView.bind()`는 `item.showMore`를 bind하고 별도 more click을 적용한다.
|
||||
- [x] **GREEN:** 홈 adapter는 `Communities.currentMemberId`로 menu item을 만들고 `FeedItem.showMore`, `setOnMoreClick`, `onCommunityMoreClick`을 연결한다. HomeFragment Host로 같은 menu item을 전달한다.
|
||||
- [x] **GREEN:** 커뮤니티 리스트 layout의 기존 top actions 끝에 42dp more 버튼을 추가하고 wrapper는 `showOwnerTopPrice || menuItem.showMore`일 때 표시한다. list adapter/Fragment Host에 `onMoreClick`을 연결한다.
|
||||
- [x] **GREEN:** root `onCommunityClick`/`onPostClick`은 상세 이동을 유지하고 more 버튼은 메뉴 callback만 호출한다.
|
||||
- [x] **GREEN:** grid layout/adapter에는 more id/callback을 추가하지 않는다.
|
||||
- [x] **GREEN 확인:** focused test와 `./gradlew :app:mergeDebugResources :app:compileDebugKotlin`이 PASS하는지 확인한다.
|
||||
- [x] **REFACTOR:** 이번 Task가 만든 listener/import/binding 중복만 정리하고 공유 View의 다른 호출부 동작은 변경하지 않는다.
|
||||
|
||||
- 검증 기록(2026-08-10): `btn_feed_community_more`, `btn_creator_channel_community_list_more`, `setOnMoreClick` 미존재로 `compileDebugUnitTestKotlin` RED 실패를 확인했다. 두 42dp 버튼과 홈/리스트의 동일 `CreatorChannelCommunityMenuItem` Host callback을 최소 연결한 뒤 지정된 focused test 119개가 모두 PASS했다. `:app:mergeDebugResources :app:compileDebugKotlin`도 PASS했으며 grid XML/adapter에는 more id·callback이 없음을 정적 확인했다.
|
||||
|
||||
### Task 16.3 Activity 공용 메뉴와 mutation 결과 전파
|
||||
|
||||
**Goal 실행 `P16-T3`:** 홈과 커뮤니티 리스트의 공용 callback이 상세와 같은 BottomSheet/Dialog/API를 실행하고 성공한 관리 작업만 두 목록을 갱신한다.
|
||||
|
||||
- **시작 조건:** `P16-T2` 완료, Phase 15 상세 메뉴/API 계약 유지.
|
||||
- **완료 증거:** Activity source/routing focused test와 전체 community 회귀, compile PASS.
|
||||
- **범위 밖:** 상세 ViewModel/Activity 메뉴 변경, 신고 후 목록 새로고침.
|
||||
|
||||
**Files:**
|
||||
|
||||
- Modify: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt`
|
||||
- Reuse: `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/data/CreatorChannelRepository.kt`
|
||||
- Reuse: 레거시 `CreatorCommunityPostMenuBottomSheetDialog`, `CreatorCommunityReportDialog`, `CreatorCommunityModifyActivity`, `CreatorCommunityRepository`
|
||||
- Test: `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivitySourceTest.kt`
|
||||
- Test: `app/src/test/java/kr/co/vividnext/sodalive/v2/community/action/CommunityChangeTest.kt`
|
||||
|
||||
**Interfaces:**
|
||||
|
||||
```kotlin
|
||||
override fun onCreatorChannelCommunityMoreClicked(item: CreatorChannelCommunityMenuItem)
|
||||
|
||||
private fun updateCreatorChannelCommunityPostFixed(item: CreatorChannelCommunityMenuItem)
|
||||
private fun deleteCreatorChannelCommunityPost(item: CreatorChannelCommunityMenuItem)
|
||||
private fun reportCreatorChannelCommunityPost(item: CreatorChannelCommunityMenuItem, reason: String)
|
||||
```
|
||||
|
||||
- Activity는 `CreatorCommunityRepository`와 기존 `CreatorChannelRepository.reportCommunityPost()`를 주입해 재사용한다.
|
||||
- 수정 launcher의 `RESULT_OK`, 삭제·고정 성공은 기존 `handleCommunityChange(CommunityChange.Updated)`로 홈+커뮤니티를 갱신한다.
|
||||
- 신고 성공은 API message 또는 `character_comment_report_submitted` Toast만 표시하고 새로고침하지 않는다.
|
||||
- `isCommunityPostMutating` 단일 guard로 고정·삭제·신고 중복 요청을 막고 성공/실패 모두 guard를 해제한다.
|
||||
|
||||
- [x] **RED:** `CreatorChannelActivitySourceTest`에 HomeFragment.Host와 CommunityFragment.Host의 동일 override 하나, 권한 guard, 기존 BottomSheet/Dialog/modify launcher 연결 계약을 추가한다.
|
||||
- [x] **RED:** 같은 test에 고정 `!item.isPinned`, 삭제 `ModifyCommunityPostRequest(isActive=false)`, 신고 `reportCommunityPost`, 성공 `CommunityChange.Updated`, 신고 성공 no-refresh, 중복 guard 계약을 추가한다.
|
||||
- [x] **RED 확인:** 아래 명령으로 Activity 공용 메뉴/mutation 연결 미존재 실패를 확인한다.
|
||||
|
||||
```bash
|
||||
./gradlew :app:testDebugUnitTest \
|
||||
--tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest" \
|
||||
--tests "kr.co.vividnext.sodalive.v2.community.action.CommunityChangeTest"
|
||||
```
|
||||
|
||||
- [x] **GREEN:** Activity에 modify launcher와 `CreatorCommunityPostMenuBottomSheetDialog`를 연결하고 `item.showMore`가 false면 menu를 시작하지 않는다.
|
||||
- [x] **GREEN:** 작성자 menu는 수정·삭제·고정/고정 해제, 일반 사용자 menu는 `CreatorCommunityReportDialog` 신고만 연결한다. mutation method는 메뉴 역할과 `item.isOwner`를 다시 확인한다.
|
||||
- [x] **GREEN:** 고정은 `updateCommunityPostFixed(item.postId, !item.isPinned, authToken())`, 삭제는 `ModifyCommunityPostRequest(creatorCommunityId = item.postId, isActive = false)` JSON `text/plain` 요청, 신고는 `CreatorChannelRepository.reportCommunityPost(item.postId, reason, authToken())`를 호출한다.
|
||||
- [x] **GREEN:** 수정 복귀·고정·삭제 성공만 `CommunityChange.Updated`로 홈+커뮤니티를 갱신하고 실패/신고는 목록 상태를 변경하지 않는다.
|
||||
- [x] **GREEN 확인:** focused test, `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*"`, `./gradlew :app:compileDebugKotlin`이 PASS하는지 확인한다.
|
||||
- [x] **REFACTOR:** 상세 메뉴 코드를 옮기거나 신규 coordinator를 만들지 않고 Activity의 공용 목록 처리만 유지한다.
|
||||
|
||||
- 검증 기록(2026-08-10): Activity 공용 메뉴와 mutation source 계약 3개를 먼저 추가한 뒤 focused test에서 기존 100개는 통과하고 신규 3개가 `item.showMore` guard 및 mutation method/guard 미존재로 RED 실패함을 확인했다. 기존 BottomSheet/Dialog/modify launcher와 legacy/V2 repository를 Activity에 직접 연결한 뒤 focused test 103개, community wildcard 회귀 86개가 모두 PASS했다. `:app:compileDebugKotlin`도 PASS했으며 수정·고정·삭제 성공만 `CommunityChange.Updated`를 호출하고 신고 성공/모든 실패 경로에는 refresh가 없음을 source test로 확인했다.
|
||||
- 리뷰 회귀 수정 검증 기록(2026-08-10): 게시물 작성자 권한은 채널 소유자 상태와 독립된 `item.isOwner`라는 PRD 계약에 맞춰 source test를 먼저 변경했고, 현재 `isCreatorChannelOwner()` 추가 조건 때문에 focused test 103개 중 권한 계약 3개가 RED 실패함을 확인했다. 수정·고정·삭제·신고 경로에서 채널 소유자 조건만 제거한 뒤 focused test 103개와 community wildcard 회귀 86개가 모두 PASS했고 `:app:compileDebugKotlin`도 PASS했다.
|
||||
|
||||
### Task 16.R1 Phase 완료 문서 정합성 복구
|
||||
|
||||
**Goal 실행 `P16-R1`:** 확정 review 항목 `REV-P16-001`에 따라 Phase 16 구현·Gate 완료 상태와 검증 증거를 문서에 누적한다.
|
||||
|
||||
- **시작 조건:** `P16-T1`~`P16-T3`, `P16-GATE` 실행 완료와 `REV-P16-001` 확정.
|
||||
- **대상 파일:** `docs/20260708_커뮤니티_게시물_상세_댓글_답글/plan-task.md`, `reviews/phase16-home-community-list-more-menu-review.md`.
|
||||
- **수정 범위:** 기존 계획 기록은 보존하고 구현·Gate 완료 기록, `Verification Log`, 리뷰 판정만 누적한다.
|
||||
- **회귀 검증:** `git diff --check`, 최종 리뷰 재검토.
|
||||
- **완료 증거:** 미시작 상태와 Gate 기록 누락 근거 → 완료 기록 누적 → diff check PASS → 5개 리뷰 lane 최종 판정.
|
||||
- **범위 밖:** production/test 코드 변경, Gate 재실행을 위한 테스트 완화, Git commit.
|
||||
|
||||
- [x] Phase 16 구현·검증 완료 기록을 기존 계획 기록 뒤에 누적한다.
|
||||
- [x] `Verification Log`에 focused test, resource merge, compile, ktlint, diff check 결과와 제외 범위를 누적한다.
|
||||
- [x] Phase 16 리뷰 보고서에 `REV-P16-001` 수정 및 재검토 결과를 누적한다.
|
||||
- [x] `git diff --check`와 최종 리뷰 재검토를 통과한다.
|
||||
|
||||
- 검증 기록(2026-08-10): Phase 16 완료 기록과 `Verification Log`를 누적한 뒤 `git diff --check`, `git diff HEAD --check`가 출력 없이 PASS했다. 최종 재검토에서 목표·실행 QA·코드 품질·보안·맥락 5개 lane이 모두 PASS했으며 추가 차단 이슈가 없음을 확인했다.
|
||||
|
||||
### Phase 16 Gate
|
||||
|
||||
**Goal 실행 `P16-GATE`:** 권한별 버튼·메뉴·mutation·새로고침과 grid 제외, 기존 상세/구매 회귀를 최종 판정한다.
|
||||
|
||||
- **시작 조건:** `P16-T1`~`P16-T3` 완료.
|
||||
- **완료 증거:** 아래 명령의 exit code 0, 정적 권한/클릭 대조, Task별 검증 기록과 `Verification Log` 누적.
|
||||
- **범위 밖:** Gate 통과를 위한 test 완화, 기기 UI 조작, Git commit.
|
||||
|
||||
```bash
|
||||
./gradlew :app:testDebugUnitTest \
|
||||
--tests "kr.co.vividnext.sodalive.v2.widget.feed.FeedItemTest" \
|
||||
--tests "kr.co.vividnext.sodalive.v2.widget.feed.FeedViewTest" \
|
||||
--tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelHomeMapperTest" \
|
||||
--tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"
|
||||
./gradlew :app:testDebugUnitTest \
|
||||
--tests "kr.co.vividnext.sodalive.v2.creator.channel.community.*" \
|
||||
--tests "kr.co.vividnext.sodalive.v2.community.action.*"
|
||||
./gradlew :app:mergeDebugResources
|
||||
./gradlew :app:compileDebugKotlin
|
||||
./gradlew :app:ktlintCheck
|
||||
git diff --check
|
||||
git diff HEAD --check
|
||||
```
|
||||
|
||||
**Expected:** 홈·커뮤니티 리스트형은 동일 권한 메뉴를 제공하고 card root 상세 이동을 유지한다. grid에는 메뉴가 없고, 미구매 유료 일반 사용자는 버튼이 숨겨진다. 수정·삭제·고정 성공은 홈+커뮤니티를 갱신하며 신고/실패는 갱신하지 않는다. 기존 상세 구매·메뉴 focused 회귀와 resource/compile/style/whitespace Gate가 모두 PASS한다.
|
||||
|
||||
### Phase 16 실행 순서
|
||||
|
||||
```text
|
||||
P16-T1 → P16-T2 → P16-T3 → P16-GATE
|
||||
```
|
||||
|
||||
### Phase 16 계획 기록 — 2026-08-10
|
||||
|
||||
- 상태: 계획 완료 / 구현 미시작
|
||||
- 무엇을: 승인된 홈·커뮤니티 리스트형 권한별 더보기 후속 요구를 `P16-T1`~`P16-T3`, `P16-GATE`로 분해했다.
|
||||
- 왜: 공용 권한 계산 → UI callback → Activity mutation 순으로 계약을 분리해 grid 제외와 상세 이동 회귀를 검증하기 위해서다.
|
||||
- 남은 항목: 사용자 계획 검토 승인 후 `P16-T1` RED부터 순차 실행한다.
|
||||
- Git commit: 사용자 지시에 따라 수행하지 않는다.
|
||||
|
||||
### Phase 16 구현·검증 기록 — 2026-08-10
|
||||
|
||||
- 상태: 구현 및 Gate 완료 / Git commit 미수행
|
||||
- 무엇을: `P16-T1`~`P16-T3`를 구현하고 리뷰 확정 항목 `REV-P16-001`을 `P16-R1`로 수정했다.
|
||||
- 왜: 홈과 커뮤니티 리스트형에서 상세과 동일한 권한별 메뉴를 제공하고, 성공한 관리 작업만 양쪽 목록에 반영하기 위해서다.
|
||||
- 어떻게:
|
||||
- 공용 `CreatorChannelCommunityMenuItem`으로 작성자/가격/구매 권한과 고정 상태를 전달했다.
|
||||
- 홈·리스트의 더보기 click을 card 상세 click과 분리하고 grid는 기존 상세 이동만 유지했다.
|
||||
- 기존 BottomSheet/Dialog/repository를 Activity에서 재사용하고 수정·삭제·고정 성공만 `CommunityChange.Updated`로 전파했다.
|
||||
- 최초 독립 명세 검토에서 채널 소유자 조건이 작성자 권한을 제한하는 문제를 확인해 `item.isOwner` 계약으로 회귀 수정했다.
|
||||
- 최종 Gate의 focused test, resource merge, Kotlin compile, ktlint, 두 diff check가 모두 통과했다.
|
||||
- 제외: `app/src/androidTest`, 기기·에뮬레이터 조작, 스크린샷·시각 QA, 실제 서버 mutation, 별도 worktree, Git commit.
|
||||
- 남은 항목: 없음.
|
||||
|
||||
## Verification Log
|
||||
- 2026-08-11: 사용자 요청에 따라 Phase 15·16 완료 체크를 PRD, production, test와 다시 역대조했다. 실제 Task 체크박스는 모두 완료 상태였고 체크 누락·미구현 항목은 없었다. Phase 15 홈 Response/공유 feed 회귀 test, Phase 16 홈·Feed·Activity focused test, community/action focused test와 필터 없는 전체 `:app:testDebugUnitTest`가 모두 `BUILD SUCCESSFUL`로 PASS했다. `:app:mergeDebugResources`, `:app:compileDebugKotlin`, `:app:ktlintCheck`, `git diff --check`, `git diff HEAD --check`도 PASS했다. 구매 호출은 상세에만 있고, 홈·리스트 root/more 분리와 grid 제외, 권한별 메뉴, 성공 관리 mutation의 홈+커뮤니티 갱신, 신고·실패 no-refresh, 공유 `FeedItem.Community` 기본값 보존을 정적으로 확인했다. 독립 재리뷰도 Critical/Important/Minor 이슈 없음과 승인 가능으로 판정했다. 새 확정 결함이 없어 억지로 회귀 수정 Task나 production/test 변경을 추가하지 않았고 Git commit도 수행하지 않았다.
|
||||
- 2026-08-10: Phase 16 `P16-T1`~`P16-T3`와 `P16-GATE`를 완료했다. 최종 working tree에서 홈·Feed·Activity focused test와 community/action 회귀 test가 `BUILD SUCCESSFUL`로 PASS했고, `:app:mergeDebugResources`, `:app:compileDebugKotlin`, `:app:ktlintCheck`도 모두 PASS했다. `git diff --check`, `git diff HEAD --check`는 출력 없이 통과했다. 허용된 실행 QA 재검증에서도 P0 시나리오 11/11과 focused 128개, community/action 96개가 PASS했다. 리뷰에서 확인된 작성자 권한 추가 제한은 `item.isOwner` 기준으로 회귀 수정했고, 완료 문서 누락 `REV-P16-001`은 `P16-R1`로 누적했다. 저장소 규칙과 사용자 지시에 따라 `app/src/androidTest`, 기기·에뮬레이터 조작, 스크린샷·시각 QA, 실제 서버 mutation, 별도 worktree, Git commit은 수행하지 않았다. `.editorconfig disabled_rules` 및 Gradle deprecated feature 경고는 기존 비차단 경고로 유지했다.
|
||||
- 2026-08-10: Phase 15 문서 대조·구현·독립 재리뷰를 완료했다. 미구현 체크리스트는 `P15-T1`~`P15-T5`로 구현했고, 리뷰에서 `REV-P15-001` 미사용 import, `REV-P15-002` reaction id 오배치, `REV-P15-003` 공유 피드 reaction 정책 범위 회귀, `REV-P15-004` 테스트 파일 미사용 import를 확정해 `P15-R1`~`P15-R4`로 수정했다. 최종 working tree에서 홈/공유 피드·커뮤니티 상세/action·상위 Activity focused test, `:app:mergeDebugResources`, `:app:compileDebugKotlin`, `:app:ktlintCheck`가 모두 `BUILD SUCCESSFUL`로 PASS했고 `git diff --check`, `git diff HEAD --check`는 출력 없이 PASS했다. 수정 후 독립 재리뷰에서도 새 Critical/Important/Minor 이슈가 없음을 확인했다. `.editorconfig disabled_rules` 및 기존 test deprecated API 경고는 실패가 아닌 기존 경고이며 범위 밖으로 유지했다. Git commit은 수행하지 않았다.
|
||||
- 2026-08-10: 승인된 후속 PRD와 Phase 15 구현 계획만 작성했다. placeholder·요구사항 충돌을 자체 검토했고 `git diff --check`, `./gradlew tasks --all`이 통과했다. 사용자 지시에 따라 production/test 코드 구현과 Git commit은 수행하지 않았다.
|
||||
- 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 검증을 실행하지 않았다.
|
||||
|
||||
Reference in New Issue
Block a user