docs(creator): 채널 라이브 Phase 2 기록을 갱신한다
This commit is contained in:
@@ -41,7 +41,7 @@
|
||||
- `PRICE_HIGH`: `price desc`, `releaseDate desc`, random
|
||||
- `PRICE_LOW`: `price asc`, `releaseDate desc`, random
|
||||
- 인기순 매출은 대여/소장 여부와 관계없이 순수하게 결제된 캔 매출인 `orders.can` 합계를 사용한다. `orders.point`는 포함하지 않고, `orders.is_active = true`인 주문만 포함한다. 환불/비활성 주문은 제외한다.
|
||||
- page/size validation은 service에서 명시적으로 수행한다. `page < 0` 또는 `size < 1`이면 기존 `common.error.invalid_request` 계열 오류를 사용한다.
|
||||
- page/size validation은 service에서 명시적으로 수행한다. `page < 0`, `size < 20`, `size > 50`이면 기존 `common.error.invalid_request` 계열 오류를 사용한다.
|
||||
|
||||
---
|
||||
|
||||
@@ -246,20 +246,21 @@ private fun LocalDateTime.toUtcIso(): String {
|
||||
|
||||
### Phase 2: 라이브 탭 domain/application 정책
|
||||
|
||||
- [ ] **Task 2.1: 라이브 탭 domain model과 page 정책 추가**
|
||||
- [x] **Task 2.1: 라이브 탭 domain model과 page 정책 추가**
|
||||
- Files:
|
||||
- Create: `src/main/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/live/domain/CreatorChannelLiveTab.kt`
|
||||
- Create: `src/main/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/live/domain/CreatorChannelPage.kt`
|
||||
- Create: `src/main/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/live/domain/CreatorChannelLiveReplayQueryPolicy.kt`
|
||||
- Test: `src/test/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/live/domain/CreatorChannelLiveReplayQueryPolicyTest.kt`
|
||||
- RED: `page=0,size=20`이면 offset `0`, fetch limit `21`, 응답 items limit `20`, `hasNext == true` 판정이 되는 테스트를 작성한다.
|
||||
- RED: `page < 0`, `size < 1`이면 정책이 예외를 던지는 테스트를 작성한다.
|
||||
- RED: `page < 0`, `size < 20`, `size > 50`이면 정책이 예외를 던지는 테스트를 작성한다.
|
||||
- 실패 확인: `./gradlew test --tests kr.co.vividnext.sodalive.v2.creator.channel.live.domain.CreatorChannelLiveReplayQueryPolicyTest`
|
||||
- GREEN: `CreatorChannelPage(page: Int, size: Int)`와 `CreatorChannelLiveReplayQueryPolicy`를 추가한다. `offset = page * size`, `fetchLimit = size + 1`, `items = fetched.take(size)`, `hasNext = fetched.size > size`를 제공한다.
|
||||
- GREEN: `CreatorChannelPage(page: Int, size: Int)`와 `CreatorChannelLiveReplayQueryPolicy`를 추가한다. `offset = page * size`, `fetchLimit = size + 1`, `items = fetched.take(size)`, `hasNext = fetched.size > size`를 제공한다. `size`는 20 이상 50 이하로 검증해 `fetchLimit` overflow를 방지한다.
|
||||
- 통과 확인: `./gradlew test --tests kr.co.vividnext.sodalive.v2.creator.channel.live.domain.CreatorChannelLiveReplayQueryPolicyTest`
|
||||
- REFACTOR: page/size 계산은 service나 repository에 중복 구현하지 않는다.
|
||||
- 검증 기록(2026-06-17): RED 단계에서 `CreatorChannelLiveReplayQueryPolicy` 미존재 컴파일 실패를 확인했다. GREEN 단계에서 `CreatorChannelPage`, `CreatorChannelLiveTab`, `CreatorChannelLiveReplayQueryPolicy`를 추가하고 `./gradlew test --tests kr.co.vividnext.sodalive.v2.creator.channel.live.domain.CreatorChannelLiveReplayQueryPolicyTest` 성공을 확인했다. 추가 리뷰 반영으로 `size < 20`, `size > 50`, `size = Int.MAX_VALUE`가 `common.error.invalid_request`를 던지고 `size = 50`의 `fetchLimit`이 51인지 검증했다.
|
||||
|
||||
- [ ] **Task 2.2: `CreatorChannelLiveQueryService` 골격 추가**
|
||||
- [x] **Task 2.2: `CreatorChannelLiveQueryService` 골격 추가**
|
||||
- Files:
|
||||
- Create: `src/main/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/live/application/CreatorChannelLiveQueryService.kt`
|
||||
- Create: `src/main/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/live/port/out/CreatorChannelLiveQueryPort.kt`
|
||||
@@ -270,18 +271,21 @@ private fun LocalDateTime.toUtcIso(): String {
|
||||
- GREEN: 기존 `CreatorChannelHomeQueryService`의 인증 회원 기준 정책을 따라 creator 검증, 차단 검증, adult visibility, effective gender 계산을 구현한다.
|
||||
- 통과 확인: `./gradlew test --tests kr.co.vividnext.sodalive.v2.creator.channel.live.application.CreatorChannelLiveQueryServiceTest`
|
||||
- REFACTOR: `CreatorChannelHomeQueryService`와 중복되는 private 변환/검증 코드가 과도해지면 같은 phase 안에서는 복사 유지하고, 추후 별도 공용 validator 추출은 구현 범위 밖으로 둔다.
|
||||
- 검증 기록(2026-06-17): RED 단계에서 `CreatorChannelLiveQueryService`와 `CreatorChannelLiveQueryPort` 미존재 컴파일 실패를 확인했다. GREEN 단계에서 홈 API 서비스의 creator 검증, 차단 검증, adult visibility, effective gender 전달 패턴을 반영하고 `./gradlew test --tests kr.co.vividnext.sodalive.v2.creator.channel.live.application.CreatorChannelLiveQueryServiceTest` 성공을 확인했다.
|
||||
|
||||
- [ ] **Task 2.3: 라이브 탭 service 응답 조립 완성**
|
||||
- [x] **Task 2.3: 라이브 탭 service 응답 조립 완성**
|
||||
- Files:
|
||||
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/live/application/CreatorChannelLiveQueryService.kt`
|
||||
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/live/domain/CreatorChannelLiveTab.kt`
|
||||
- Test: `src/test/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/live/application/CreatorChannelLiveQueryServiceTest.kt`
|
||||
- RED: fake port가 `size + 1`개 콘텐츠를 반환하면 service 응답의 `liveReplayContents.size == size`, `hasNext == true`, `page == 0`, `size == 20`, `sort == LATEST`인지 검증한다.
|
||||
- RED: invalid `page`/`size` 요청은 port bean 조회 전에 `common.error.invalid_request`를 던지는지 검증한다.
|
||||
- RED: `page` 범위에 콘텐츠가 없으면 `liveReplayContents`는 빈 배열이고 count는 port count 값을 유지하는지 검증한다.
|
||||
- 실패 확인: `./gradlew test --tests kr.co.vividnext.sodalive.v2.creator.channel.live.application.CreatorChannelLiveQueryServiceTest`
|
||||
- GREEN: service에서 policy로 page를 검증하고, count와 `size + 1` 조회 결과를 조립해 `CreatorChannelLiveTab`을 반환한다.
|
||||
- GREEN: service에서 policy로 page/size를 먼저 검증하고, 검증 후 port를 조회해 count와 `size + 1` 조회 결과를 조립해 `CreatorChannelLiveTab`을 반환한다.
|
||||
- 통과 확인: `./gradlew test --tests kr.co.vividnext.sodalive.v2.creator.channel.live.application.CreatorChannelLiveQueryServiceTest`
|
||||
- REFACTOR: `ContentSort` 기본값은 controller가 기본값을 넣되, service 테스트에서도 명시 인자를 사용해 정책 위치를 분리한다.
|
||||
- 검증 기록(2026-06-17): RED 단계에서 service 조립 대상 domain/port/service 미존재 컴파일 실패를 확인했다. GREEN 단계에서 count, 현재 라이브, `size + 1` 다시듣기 목록을 `CreatorChannelLiveTab`으로 조립하고 `hasNext`, page, sort, 소장/대여 상태 보존을 `./gradlew test --tests kr.co.vividnext.sodalive.v2.creator.channel.live.application.CreatorChannelLiveQueryServiceTest`로 확인했다. 추가 리뷰 반영으로 invalid `page`/`size` 요청이 `ObjectProvider.getObject()`보다 먼저 `common.error.invalid_request`로 중단되는지 검증했다.
|
||||
|
||||
---
|
||||
|
||||
@@ -480,3 +484,4 @@ private fun LocalDateTime.toUtcIso(): String {
|
||||
|
||||
- 아직 구현 전 계획 문서 작성 단계다. 구현 task 완료 후 각 task 아래에 무엇을, 왜, 어떻게 검증했는지 실행 명령과 결과를 누적 기록한다.
|
||||
- 2026-06-17 문서 갱신 검증: 라이브 탭 신규 구현을 `v2.api.creator.channel.live` 조립 계층과 `v2.creator.channel.live` 도메인 조회 계층으로 진행하도록 PRD/plan-task를 갱신했다. 기존 홈 API 구조 정렬은 Phase 6 후속 프롬프트로 분리했다. `git diff --check`로 whitespace 오류가 없음을 확인했고, `./gradlew tasks --all`로 Gradle 명령 유효성 확인에 성공했다.
|
||||
- 2026-06-17 Phase 2 검증: `CreatorChannelLiveReplayQueryPolicyTest`와 `CreatorChannelLiveQueryServiceTest`를 먼저 추가해 RED 단계에서 Phase 2 production 클래스 미존재 컴파일 실패를 확인했다. GREEN 단계에서 라이브 탭 domain/page 정책, port, service 조립을 추가하고 `./gradlew test --tests kr.co.vividnext.sodalive.v2.creator.channel.live.domain.CreatorChannelLiveReplayQueryPolicyTest --tests kr.co.vividnext.sodalive.v2.creator.channel.live.application.CreatorChannelLiveQueryServiceTest`, `./gradlew ktlintCheck`, `git diff --check` 성공을 확인했다. Phase 3 port 구현 전 Spring context가 깨지지 않도록 service는 `ObjectProvider<CreatorChannelLiveQueryPort>`로 port를 지연 조회하게 했고, `./gradlew test --tests kr.co.vividnext.sodalive.support.SpringBootIntegrationSampleTest` 성공으로 대표 context 기동을 확인했다. 추가 리뷰 반영으로 `page >= 0`, `20 <= size <= 50` 검증과 invalid 요청 시 port 조회 전 중단을 보강했고, 동일 targeted 테스트와 `ktlintCheck`, `git diff --check` 성공을 확인했다. 전체 `./gradlew test`는 실행 중 기존 SpringBoot 통합 테스트들의 bean/OOM 계열 실패와 timeout이 발생해 완료하지 못했으며, Phase 2 직접 변경 범위는 위 targeted/context 검증으로 확인했다.
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
#### Edge Cases
|
||||
- 조회자 본인이 크리에이터인 경우에도 같은 응답 스키마를 사용한다.
|
||||
- 알 수 없는 `sort` 값은 Spring enum binding 실패 또는 기존 validation 오류 흐름에 맞춰 400 계열 오류로 처리한다.
|
||||
- `page`가 0보다 작거나 `size`가 1보다 작으면 기존 validation 오류 흐름에 맞춰 400 계열 오류로 처리한다.
|
||||
- `page`가 0보다 작거나 `size`가 20보다 작거나 50보다 크면 기존 validation 오류 흐름에 맞춰 400 계열 오류로 처리한다.
|
||||
|
||||
### Feature B. 응답 스키마
|
||||
|
||||
|
||||
Reference in New Issue
Block a user