Files
sodalive-backend-spring-boot/docs/20260629_커뮤니티_게시글_좋아요_상태/plan-task.md

298 lines
26 KiB
Markdown

# 커뮤니티 게시글 좋아요 상태 응답 추가 Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use `superpowers:subagent-driven-development` or `superpowers:executing-plans` to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** v2 커뮤니티 게시글 item 응답에 조회자 기준 `isLiked` 상태를 추가한다.
**Architecture:** 공개 API DTO에는 `@JsonProperty("isLiked")`가 붙은 Boolean 필드를 추가한다. 홈 인기 커뮤니티는 `HomePopularCommunityRecommendationRecord` projection에서 조회자 활성 좋아요 존재 여부를 전달하고, 크리에이터 채널 홈/커뮤니티 탭은 공통 `CreatorChannelCommunityPostRecord``CreatorChannelCommunityPost``isLiked`를 통과시킨다. 기존 좋아요 수, 구매 여부, 댓글 수, 성인 필터, 차단 정책은 변경하지 않는다.
**Tech Stack:** Kotlin, Spring Boot 2.7.14, QueryDSL, JPA, JUnit 5, MockMvc, Gradle Wrapper
---
## 파일 구조
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/api/home/dto/recommendation/HomeRecommendationResponse.kt`
- `HomePopularCommunityPostItem``isLiked` 응답 필드를 추가한다.
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/api/home/application/HomeRecommendationFacade.kt`
- `HomePopularCommunityRecommendationRecord.isLiked``HomePopularCommunityPostItem.isLiked`로 매핑한다.
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/recommendation/port/out/HomeRecommendationQueryPort.kt`
- `HomePopularCommunityRecommendationRecord``isLiked`를 추가한다.
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/recommendation/adapter/out/persistence/DefaultHomeRecommendationQueryRepository.kt`
- 인기 커뮤니티 상세 projection에서 `memberId` 기준 활성 좋아요 존재 여부를 계산한다.
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/community/port/out/CreatorChannelCommunityQueryPort.kt`
- `CreatorChannelCommunityPostRecord``isLiked`를 추가한다.
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/community/domain/CreatorChannelCommunityTab.kt`
- `CreatorChannelCommunityPost``isLiked`를 추가한다.
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/community/application/CreatorChannelCommunityQueryService.kt`
- record의 `isLiked`를 domain post로 매핑한다.
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/community/adapter/out/persistence/DefaultCreatorChannelCommunityQueryRepository.kt`
- 응답 post id 목록에 대해 조회자 활성 좋아요 post id를 bulk 조회한다.
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/api/creator/channel/home/dto/CreatorChannelHomeResponse.kt`
- 채널 홈 공지/커뮤니티 게시글 응답에 `isLiked`를 추가한다.
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/api/creator/channel/community/dto/CreatorChannelCommunityTabResponse.kt`
- 커뮤니티 탭 게시글 응답에 `isLiked`를 추가한다.
- Modify: 관련 테스트 파일
- 홈 추천: `HomeRecommendationQueryServiceTest`, `DefaultHomeRecommendationQueryRepositoryTest`, `HomeRecommendationControllerTest`
- 채널 커뮤니티: `CreatorChannelCommunityQueryPolicyTest`, `CreatorChannelCommunityQueryServiceTest`, `DefaultCreatorChannelCommunityQueryRepositoryTest`
- 채널 API DTO/controller: `CreatorChannelCommunityFacadeTest`, `CreatorChannelCommunityControllerTest`, `CreatorChannelHomeFacadeTest`, `CreatorChannelHomeControllerTest`
---
### Phase 1: 홈 인기 커뮤니티 `isLiked` 추가
- [x] **Task 1.1: 홈 인기 커뮤니티 repository 테스트에 조회자 좋아요 상태를 고정한다**
- Files:
- Modify: `src/test/kotlin/kr/co/vividnext/sodalive/v2/recommendation/adapter/out/persistence/DefaultHomeRecommendationQueryRepositoryTest.kt`
- RED: `shouldFindPopularCommunityRecommendationDetailsWithEligibilityAndCounts`에서 현재 조회자 활성 좋아요와 다른 회원 좋아요를 구분하는 assertion을 먼저 추가한다.
- 추가할 검증:
- `detailById[eligible.id]!!.isLiked == true`
- `detailById[paid.id]!!.isLiked == false`
- 비회원 테스트 `shouldReturnFalseOrderStatusForAnonymousPopularCommunityDetails`에서 `details.map { it.isLiked } == listOf(false)`
- 다른 회원 좋아요 검증을 위해 `paid` 게시글에는 다른 회원의 활성 좋아요를 저장하되, 현재 조회자의 좋아요로 계산되지 않음을 확인한다.
- 실패 확인 명령:
- `./gradlew test --tests kr.co.vividnext.sodalive.v2.recommendation.adapter.out.persistence.DefaultHomeRecommendationQueryRepositoryTest`
- 기대 결과:
- `HomePopularCommunityRecommendationRecord``isLiked`가 없어 `compileTestKotlin` 실패한다.
- GREEN: `HomePopularCommunityRecommendationRecord``DefaultHomeRecommendationQueryRepository.findPopularCommunityRecommendationDetails(...)`를 수정한다.
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/recommendation/port/out/HomeRecommendationQueryPort.kt`
- `HomePopularCommunityRecommendationRecord` 생성자 마지막에 `val isLiked: Boolean`을 추가한다.
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/recommendation/adapter/out/persistence/DefaultHomeRecommendationQueryRepository.kt`
- projection 마지막에 `likedCommunityPostCondition(memberId)`를 추가한다.
- helper를 추가한다.
```kotlin
private fun likedCommunityPostCondition(memberId: Long?): BooleanExpression {
if (memberId == null) return Expressions.FALSE
return JPAExpressions
.selectOne()
.from(creatorCommunityLike)
.where(
creatorCommunityLike.creatorCommunity.id.eq(creatorCommunity.id),
creatorCommunityLike.member.id.eq(memberId),
creatorCommunityLike.isActive.isTrue
)
.exists()
}
```
- 통과 확인 명령:
- `./gradlew test --tests kr.co.vividnext.sodalive.v2.recommendation.adapter.out.persistence.DefaultHomeRecommendationQueryRepositoryTest`
- REFACTOR: 기존 `likeCount`, `commentCount`, `existOrdered`, adult filter, block filter assertion이 그대로 남아 있는지 확인한다.
- 회귀 명령:
- `./gradlew test --tests kr.co.vividnext.sodalive.v2.recommendation.application.HomeRecommendationQueryServiceTest`
- [x] **Task 1.2: 홈 추천 service/facade/응답 DTO에 `isLiked`를 통과시킨다**
- Files:
- Modify: `src/test/kotlin/kr/co/vividnext/sodalive/v2/recommendation/application/HomeRecommendationQueryServiceTest.kt`
- Modify: `src/test/kotlin/kr/co/vividnext/sodalive/v2/api/home/HomeRecommendationControllerTest.kt`
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/api/home/dto/recommendation/HomeRecommendationResponse.kt`
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/api/home/application/HomeRecommendationFacade.kt`
- RED:
- `HomeRecommendationQueryServiceTest``HomePopularCommunityRecommendationRecord(...)` fixture에 `isLiked`를 넣고, 결과가 유지되는지 assertion을 추가한다.
- `HomeRecommendationControllerTest`에는 `popularCommunityPosts[0].isLiked` JSON assertion을 추가한다. 비회원 통합 조회에서 데이터가 비어 있으면 별도 fixture 생성이 부담되므로, 이미 인기 커뮤니티 데이터가 있는 테스트가 없을 경우 repository/facade 단위 테스트를 우선 검증하고 controller 테스트는 DTO 직렬화가 걸리는 기존 fixture가 있는 위치만 갱신한다.
- 실패 확인 명령:
- `./gradlew test --tests kr.co.vividnext.sodalive.v2.recommendation.application.HomeRecommendationQueryServiceTest --tests kr.co.vividnext.sodalive.v2.api.home.HomeRecommendationControllerTest`
- 기대 결과:
- DTO 또는 fixture 생성자 인자 불일치로 `compileTestKotlin` 또는 JSON assertion 실패가 발생한다.
- GREEN:
- `HomePopularCommunityPostItem`에 아래 필드를 추가한다.
```kotlin
@JsonProperty("isLiked")
val isLiked: Boolean
```
- `HomeRecommendationFacade.HomePopularCommunityRecommendationRecord.toItem()`에서 `isLiked = isLiked`를 추가한다.
- 모든 `HomePopularCommunityRecommendationRecord(...)` 테스트 fixture에 `isLiked = false` 또는 검증 목적에 맞는 값을 명시한다.
- 통과 확인 명령:
- `./gradlew test --tests kr.co.vividnext.sodalive.v2.recommendation.application.HomeRecommendationQueryServiceTest --tests kr.co.vividnext.sodalive.v2.api.home.HomeRecommendationControllerTest`
- REFACTOR:
- `rg -n "HomePopularCommunityRecommendationRecord\\(" src/test/kotlin src/main/kotlin`로 모든 생성자 호출이 `isLiked`를 명시하는지 확인한다.
- `rg -n "JsonProperty\\(\"isLiked\"\\).*HomePopularCommunityPostItem|val isLiked" src/main/kotlin/kr/co/vividnext/sodalive/v2/api/home/dto/recommendation/HomeRecommendationResponse.kt`로 직렬화 필드명을 확인한다.
---
### Phase 2: 크리에이터 채널 커뮤니티 공통 모델과 조회에 `isLiked` 추가
- [x] **Task 2.1: 채널 커뮤니티 repository 테스트에 조회자 좋아요 상태를 고정한다**
- Files:
- Modify: `src/test/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/community/adapter/out/persistence/DefaultCreatorChannelCommunityQueryRepositoryTest.kt`
- RED:
- `shouldCountActiveLikesAndZeroCommentsWhenUnavailable`에 현재 조회자 활성 좋아요를 저장하고 `record.isLiked == true`를 검증한다.
- 같은 테스트 또는 별도 테스트에서 다른 회원 활성 좋아요만 있는 게시글은 `isLiked == false`, 비활성 좋아요는 `isLiked == false`를 검증한다.
- `findHomeCommunityPosts` 검증이 있는 테스트에 홈 요약 조회도 `isLiked`를 반환하는 assertion을 추가한다.
- 실패 확인 명령:
- `./gradlew test --tests kr.co.vividnext.sodalive.v2.creator.channel.community.adapter.out.persistence.DefaultCreatorChannelCommunityQueryRepositoryTest`
- 기대 결과:
- `CreatorChannelCommunityPostRecord``isLiked`가 없어 `compileTestKotlin` 실패한다.
- GREEN:
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/community/port/out/CreatorChannelCommunityQueryPort.kt`
- `CreatorChannelCommunityPostRecord``val isLiked: Boolean`을 추가한다.
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/community/adapter/out/persistence/DefaultCreatorChannelCommunityQueryRepository.kt`
- `toCommunityPostRecords(...)`에서 `val likedPostIds = likedCommunityPostIds(viewerId, postIds)`를 계산한다.
- record 생성 시 `isLiked = postId in likedPostIds`를 추가한다.
- helper를 추가한다.
```kotlin
private fun likedCommunityPostIds(viewerId: Long, postIds: List<Long>): Set<Long> {
if (postIds.isEmpty()) return emptySet()
return queryFactory
.select(creatorCommunityLike.creatorCommunity.id)
.distinct()
.from(creatorCommunityLike)
.where(
creatorCommunityLike.member.id.eq(viewerId),
creatorCommunityLike.creatorCommunity.id.`in`(postIds),
creatorCommunityLike.isActive.isTrue
)
.fetch()
.toSet()
}
```
- 통과 확인 명령:
- `./gradlew test --tests kr.co.vividnext.sodalive.v2.creator.channel.community.adapter.out.persistence.DefaultCreatorChannelCommunityQueryRepositoryTest`
- REFACTOR:
- `likedCommunityPostIds``postIds.isEmpty()`를 처리해 불필요한 query를 만들지 않는지 확인한다.
- 기존 `communityLikeCounts(postIds)`는 그대로 유지하고 `isLiked` 계산에 재사용하지 않는다. 좋아요 수와 조회자 좋아요 여부는 다른 의미다.
- [x] **Task 2.2: 채널 커뮤니티 domain/service에 `isLiked`를 통과시킨다**
- Files:
- Modify: `src/test/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/community/domain/CreatorChannelCommunityQueryPolicyTest.kt`
- Modify: `src/test/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/community/application/CreatorChannelCommunityQueryServiceTest.kt`
- Modify: `src/test/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/home/application/CreatorChannelHomeQueryServiceTest.kt`
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/community/domain/CreatorChannelCommunityTab.kt`
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/community/application/CreatorChannelCommunityQueryService.kt`
- RED:
- `CreatorChannelCommunityQueryServiceTest.shouldAssembleCommunityPostAssetsByAccessPolicy`에서 첫 게시글 `isLiked=true`, 다른 게시글 `isLiked=false` fixture를 만들고 domain 결과를 검증한다.
- `shouldAssembleHomeCommunityPostsWithoutTabValidation`에서도 home post의 `isLiked`가 유지되는지 검증한다.
- `CreatorChannelCommunityQueryPolicyTest``CreatorChannelHomeQueryServiceTest`의 생성자 fixture에 `isLiked`를 명시한다.
- 실패 확인 명령:
- `./gradlew test --tests kr.co.vividnext.sodalive.v2.creator.channel.community.application.CreatorChannelCommunityQueryServiceTest --tests kr.co.vividnext.sodalive.v2.creator.channel.community.domain.CreatorChannelCommunityQueryPolicyTest --tests kr.co.vividnext.sodalive.v2.creator.channel.home.application.CreatorChannelHomeQueryServiceTest`
- 기대 결과:
- `CreatorChannelCommunityPost` 생성자 인자 불일치 또는 `isLiked` 미구현으로 실패한다.
- GREEN:
- `CreatorChannelCommunityPost``val isLiked: Boolean`을 추가한다.
- `CreatorChannelCommunityQueryService.CreatorChannelCommunityPostRecord.toDomain(...)`에서 `isLiked = isLiked`를 추가한다.
- 테스트 helper `communityPostRecord(...)`에는 기본값 `isLiked: Boolean = false`를 추가하고 record 생성 시 전달한다.
- 통과 확인 명령:
- `./gradlew test --tests kr.co.vividnext.sodalive.v2.creator.channel.community.application.CreatorChannelCommunityQueryServiceTest --tests kr.co.vividnext.sodalive.v2.creator.channel.community.domain.CreatorChannelCommunityQueryPolicyTest --tests kr.co.vividnext.sodalive.v2.creator.channel.home.application.CreatorChannelHomeQueryServiceTest`
- REFACTOR:
- `rg -n "CreatorChannelCommunityPostRecord\\(|CreatorChannelCommunityPost\\(" src/main/kotlin src/test/kotlin`로 모든 생성자 호출이 컴파일 가능한지 확인한다.
---
### Phase 3: 크리에이터 채널 공개 API DTO에 `isLiked` 추가
- [x] **Task 3.1: 커뮤니티 탭 응답 DTO와 controller JSON을 갱신한다**
- Files:
- Modify: `src/test/kotlin/kr/co/vividnext/sodalive/v2/api/creator/channel/community/application/CreatorChannelCommunityFacadeTest.kt`
- Modify: `src/test/kotlin/kr/co/vividnext/sodalive/v2/api/creator/channel/community/adapter/in/web/CreatorChannelCommunityControllerTest.kt`
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/api/creator/channel/community/dto/CreatorChannelCommunityTabResponse.kt`
- RED:
- `CreatorChannelCommunityFacadeTest.shouldMapCommunityTabDomainToPublicResponse`에서 `response.communityPosts.first().isLiked == true`를 검증한다.
- ObjectMapper JSON 검증에 `json["communityPosts"][0]["isLiked"].asBoolean()`을 추가한다.
- `CreatorChannelCommunityControllerTest.shouldReturnCreatorChannelCommunityTabForAuthenticatedMember``jsonPath("$.data.communityPosts[0].isLiked").value(true)`를 추가한다.
- 실패 확인 명령:
- `./gradlew test --tests kr.co.vividnext.sodalive.v2.api.creator.channel.community.application.CreatorChannelCommunityFacadeTest --tests kr.co.vividnext.sodalive.v2.api.creator.channel.community.adapter.in.web.CreatorChannelCommunityControllerTest`
- 기대 결과:
- DTO에 `isLiked`가 없어 컴파일 또는 JSON assertion이 실패한다.
- GREEN:
- 커뮤니티 탭 `CreatorChannelCommunityPostResponse`에 아래 필드를 추가한다.
```kotlin
@JsonProperty("isLiked")
val isLiked: Boolean
```
- `CreatorChannelCommunityPostResponse.from(post)``isLiked = post.isLiked`를 추가한다.
- 테스트 fixture의 `CreatorChannelCommunityPost``CreatorChannelCommunityPostResponse` 생성자에 `isLiked`를 명시한다.
- 통과 확인 명령:
- `./gradlew test --tests kr.co.vividnext.sodalive.v2.api.creator.channel.community.application.CreatorChannelCommunityFacadeTest --tests kr.co.vividnext.sodalive.v2.api.creator.channel.community.adapter.in.web.CreatorChannelCommunityControllerTest`
- REFACTOR:
- `isCommentAvailable`, `isPinned`, `isLiked` 모두 `is` prefix가 유지되는지 ObjectMapper 테스트로 확인한다.
- [x] **Task 3.2: 크리에이터 채널 홈 응답 DTO와 controller JSON을 갱신한다**
- Files:
- Modify: `src/test/kotlin/kr/co/vividnext/sodalive/v2/api/creator/channel/home/application/CreatorChannelHomeFacadeTest.kt`
- Modify: `src/test/kotlin/kr/co/vividnext/sodalive/v2/api/creator/channel/home/adapter/in/web/CreatorChannelHomeControllerTest.kt`
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/api/creator/channel/home/dto/CreatorChannelHomeResponse.kt`
- RED:
- `CreatorChannelHomeFacadeTest.shouldMapHomeQueryResultToPublicResponse``response.notices.first().isLiked == true`, `response.communities.first().isLiked == true` 검증을 추가한다.
- `CreatorChannelHomeControllerTest.shouldReturnCreatorChannelHomeForAuthenticatedMember``jsonPath("$.data.notices[0].isLiked").value(true)``jsonPath("$.data.communities[0].isLiked").value(true)`를 추가한다.
- 실패 확인 명령:
- `./gradlew test --tests kr.co.vividnext.sodalive.v2.api.creator.channel.home.application.CreatorChannelHomeFacadeTest --tests kr.co.vividnext.sodalive.v2.api.creator.channel.home.adapter.in.web.CreatorChannelHomeControllerTest`
- 기대 결과:
- 홈 DTO에 `isLiked`가 없어 컴파일 또는 JSON assertion이 실패한다.
- GREEN:
-`CreatorChannelCommunityPostResponse`에 아래 필드를 추가한다.
```kotlin
@JsonProperty("isLiked")
val isLiked: Boolean
```
- `CreatorChannelCommunityPostResponse.from(post)``isLiked = post.isLiked`를 추가한다.
- 테스트 fixture의 `CreatorChannelCommunityPost` 생성자에 `isLiked = true` 또는 `false`를 명시한다.
- 통과 확인 명령:
- `./gradlew test --tests kr.co.vividnext.sodalive.v2.api.creator.channel.home.application.CreatorChannelHomeFacadeTest --tests kr.co.vividnext.sodalive.v2.api.creator.channel.home.adapter.in.web.CreatorChannelHomeControllerTest`
- REFACTOR:
- 홈 공지와 홈 일반 커뮤니티가 같은 domain post 필드를 사용하므로 별도 계산 로직을 추가하지 않았는지 확인한다.
---
### Phase 4: 통합 회귀와 문서 검증
- [x] **Task 4.1: 관련 테스트 묶음을 실행하고 fixture 누락을 정리한다**
- Files:
- Verify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/api/home/dto/recommendation/HomeRecommendationResponse.kt`
- Verify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/api/creator/channel/home/dto/CreatorChannelHomeResponse.kt`
- Verify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/api/creator/channel/community/dto/CreatorChannelCommunityTabResponse.kt`
- Verify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/recommendation/port/out/HomeRecommendationQueryPort.kt`
- Verify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/community/port/out/CreatorChannelCommunityQueryPort.kt`
- RED:
- 이 task는 앞선 task가 모두 GREEN인 뒤 전체 fixture 누락을 찾는 회귀 task다.
- 실행 명령:
- `./gradlew test --tests 'kr.co.vividnext.sodalive.v2.recommendation.*' --tests 'kr.co.vividnext.sodalive.v2.api.home.*' --tests 'kr.co.vividnext.sodalive.v2.creator.channel.community.*' --tests 'kr.co.vividnext.sodalive.v2.api.creator.channel.community.*' --tests 'kr.co.vividnext.sodalive.v2.api.creator.channel.home.*' --tests 'kr.co.vividnext.sodalive.v2.creator.channel.home.application.CreatorChannelHomeQueryServiceTest'`
- 기대 결과:
- 관련 테스트가 모두 `BUILD SUCCESSFUL`이어야 한다.
- GREEN:
- 컴파일 실패가 남으면 생성자 호출 누락을 `rg -n "isLiked|HomePopularCommunityRecommendationRecord\\(|CreatorChannelCommunityPostRecord\\(|CreatorChannelCommunityPost\\(" src/main/kotlin src/test/kotlin`로 찾아 보정한다.
- REFACTOR:
- `isLiked`를 계산하기 위해 기존 `likeCount` 쿼리의 의미를 바꾸지 않았는지 diff로 확인한다.
- `isLiked`가 응답 DTO 3곳에 모두 `@JsonProperty("isLiked")`로 선언되어 있는지 확인한다.
- [x] **Task 4.2: ktlint와 전체 명령 유효성을 확인한다**
- Files:
- Verify: `build.gradle.kts`
- Verify: `docs/20260629_커뮤니티_게시글_좋아요_상태/plan-task.md`
- RED:
- 이 task는 문서와 포맷 검증 task이므로 실패 테스트 작성 대상이 아니다.
- TDD 예외 사유: 코드 동작 변경이 아니라 전체 포맷/명령 검증이다.
- 대체 검증 방법: Gradle verification task를 실행한다.
- 실행 명령:
- `./gradlew ktlintCheck`
- `./gradlew tasks --all`
- 기대 결과:
- 두 명령 모두 `BUILD SUCCESSFUL`이어야 한다.
- REFACTOR:
- `build.gradle.kts`를 변경하지 않았으면 실행 명령 문서 갱신은 필요 없다.
- plan-task 검증 기록에는 실행한 명령과 결과를 누적한다.
---
## 검증 기록
- 2026-06-29: plan-task 작성 전 PRD `docs/20260629_커뮤니티_게시글_좋아요_상태/prd.md`와 관련 v2 DTO/record/repository/test 파일을 확인했다.
- 2026-06-29: 문서 자체 검토로 placeholder 금지 패턴 검색을 실행했고 결과가 없음을 확인했다. `./gradlew tasks --all`은 sandbox에서 `~/.gradle` lock 파일 접근 제한으로 1차 실패했으며, 승인 권한으로 재실행해 `BUILD SUCCESSFUL`을 확인했다.
- 2026-06-30: Task 1.1 RED로 `./gradlew test --tests kr.co.vividnext.sodalive.v2.recommendation.adapter.out.persistence.DefaultHomeRecommendationQueryRepositoryTest`를 실행했고 `HomePopularCommunityRecommendationRecord.isLiked` 미구현으로 `compileTestKotlin` 실패를 확인했다.
- 2026-06-30: Task 1.1/1.2 GREEN으로 홈 인기 커뮤니티 record/projection/DTO/facade/fixture를 반영한 뒤 `./gradlew test --tests kr.co.vividnext.sodalive.v2.recommendation.adapter.out.persistence.DefaultHomeRecommendationQueryRepositoryTest``./gradlew test --tests kr.co.vividnext.sodalive.v2.recommendation.application.HomeRecommendationQueryServiceTest --tests kr.co.vividnext.sodalive.v2.api.home.HomeRecommendationControllerTest`가 모두 `BUILD SUCCESSFUL`임을 확인했다.
- 2026-06-30: Task 2.1 RED로 `./gradlew test --tests kr.co.vividnext.sodalive.v2.creator.channel.community.adapter.out.persistence.DefaultCreatorChannelCommunityQueryRepositoryTest`를 실행했고 `CreatorChannelCommunityPostRecord.isLiked` 미구현으로 `compileTestKotlin` 실패를 확인했다.
- 2026-06-30: Task 2.1/2.2 GREEN으로 채널 커뮤니티 record/domain/service/repository bulk liked post id 조회와 fixture를 반영한 뒤 `./gradlew test --tests kr.co.vividnext.sodalive.v2.creator.channel.community.adapter.out.persistence.DefaultCreatorChannelCommunityQueryRepositoryTest``./gradlew test --tests kr.co.vividnext.sodalive.v2.creator.channel.community.application.CreatorChannelCommunityQueryServiceTest --tests kr.co.vividnext.sodalive.v2.creator.channel.community.domain.CreatorChannelCommunityQueryPolicyTest --tests kr.co.vividnext.sodalive.v2.creator.channel.home.application.CreatorChannelHomeQueryServiceTest`가 모두 `BUILD SUCCESSFUL`임을 확인했다.
- 2026-06-30: Task 3.1/3.2 GREEN으로 커뮤니티 탭/채널 홈 공개 DTO와 controller JSON fixture를 반영한 뒤 `./gradlew test --tests kr.co.vividnext.sodalive.v2.api.creator.channel.community.application.CreatorChannelCommunityFacadeTest --tests kr.co.vividnext.sodalive.v2.api.creator.channel.community.adapter.in.web.CreatorChannelCommunityControllerTest``./gradlew test --tests kr.co.vividnext.sodalive.v2.api.creator.channel.home.application.CreatorChannelHomeFacadeTest --tests kr.co.vividnext.sodalive.v2.api.creator.channel.home.adapter.in.web.CreatorChannelHomeControllerTest`가 모두 `BUILD SUCCESSFUL`임을 확인했다.
- 2026-06-30: Task 4.1 회귀 명령 `./gradlew test --tests 'kr.co.vividnext.sodalive.v2.recommendation.*' --tests 'kr.co.vividnext.sodalive.v2.api.home.*' --tests 'kr.co.vividnext.sodalive.v2.creator.channel.community.*' --tests 'kr.co.vividnext.sodalive.v2.api.creator.channel.community.*' --tests 'kr.co.vividnext.sodalive.v2.api.creator.channel.home.*' --tests 'kr.co.vividnext.sodalive.v2.creator.channel.home.application.CreatorChannelHomeQueryServiceTest'`를 실행했고 199개 중 1개 실패를 확인했다. 실패는 `kr.co.vividnext.sodalive.v2.api.home.following.adapter.in.web.HomeFollowingEndToEndTest.shouldAssembleFollowingTabForMember``$.data.monthlySchedules[1].scheduleId` JSON path 누락으로, 이번 `isLiked` 변경 대상이 아닌 `api.home.following` 경로의 기존 회귀로 분리했다.
- 2026-06-30: Task 4.2로 `./gradlew ktlintCheck``./gradlew tasks --all`을 실행했고 모두 `BUILD SUCCESSFUL`임을 확인했다.
- 2026-06-30: Reviewer gate에서 채널 커뮤니티 repository 테스트의 다른 회원 활성 좋아요 전용 시나리오 누락을 지적받아 `otherMemberOnlyLikedPost` 검증을 추가했다. 이후 `./gradlew test --tests kr.co.vividnext.sodalive.v2.creator.channel.community.adapter.out.persistence.DefaultCreatorChannelCommunityQueryRepositoryTest`, focused 테스트 묶음, `./gradlew ktlintCheck`를 재실행해 모두 `BUILD SUCCESSFUL`을 확인했고, reviewer gate 재검토에서 unconditional approval을 받았다.