docs(content-ranking): 커버 이미지 CDN 정책을 기록한다

This commit is contained in:
2026-06-25 16:03:10 +09:00
parent 4f3f8d1fa7
commit e411beb649
2 changed files with 36 additions and 0 deletions

View File

@@ -511,3 +511,27 @@ data class AudioRankingSnapshotRecord(
- 2026-06-24 Phase 6 트랜잭션 가시성 검증: `getRankings()``@Transactional`이 다시 붙지 않도록 회귀 테스트를 추가했다. RED 확인 후 수정했고, `./gradlew test --tests kr.co.vividnext.sodalive.v2.content.ranking.application.AudioRankingQueryServiceTest`, `./gradlew test --tests 'kr.co.vividnext.sodalive.v2.content.ranking.*'`, `./gradlew ktlintCheck` 통과.
- 2026-06-24 Phase 8 문서 확인: `rg -n "07:30|visibleFromAt|visible_from_at|ranking_type|크리에이터 랭킹" docs/20260608_크리에이터_랭킹 docs/20260623_메인_콘텐츠_랭킹_탭_API/plan-task.md`로 크리에이터 랭킹 현재 07:30 스케줄과 다음 범위의 `visible_from_at`, `ranking_type` DDL 검토 시작점을 확인했다.
- 2026-06-24 Phase 8 범위 확정: 크리에이터 랭킹 코드/DDL은 수정하지 않고, 다음 범위가 별도 PRD 문서 수정부터 시작되도록 Task 8.1 완료 상태와 검증 기록만 갱신했다.
### Phase 9: `coverImageUrl` CDN host 누락 버그 수정
- [x] **Task 9.1: `AudioRankingQueryService` 응답 변환 지점에서 CDN URL 정책 고정**
- Files:
- Modify: `src/main/kotlin/kr/co/vividnext/sodalive/v2/content/ranking/application/AudioRankingQueryService.kt`
- Modify: `src/test/kotlin/kr/co/vividnext/sodalive/v2/content/ranking/application/AudioRankingQueryServiceTest.kt`
- Modify: `docs/20260623_메인_콘텐츠_랭킹_탭_API/prd.md`
- Modify: `docs/20260623_메인_콘텐츠_랭킹_탭_API/plan-task.md`
- 버그 내용: 메인 콘텐츠 랭킹 탭 API는 스냅샷의 `coverImageUrl` 값을 `AudioRankingQueryService.toItem(...)`에서 그대로 `AudioRankingItem.coverImageUrl`로 옮기고 있었다. 스냅샷 생성 과정의 원천 값은 `audio_content.cover_image` 계열의 저장 path이므로, 공개 API 응답도 `cover-1.png`처럼 host 없는 path만 내려갔다.
- 영향 범위: `GET /api/v2/audio/rankings`의 item `coverImageUrl`만 대상이다. 순위 계산, 최신/직전 visible snapshot 조회, 19금 필터, 차단 필터, fallback job 실행, 스냅샷 저장 구조와 DDL은 변경하지 않는다.
- 원인: 콘텐츠 랭킹 조회 서비스가 크리에이터 랭킹의 `profileImageUrl.toCdnUrl(cloudFrontHost)` 패턴이나 v2 콘텐츠/크리에이터 조회 계층의 `toCdnUrl` 패턴을 적용하지 않았다. DTO 변환 계층은 domain item 값을 그대로 응답으로 내보내므로, domain item 조립 시점에 URL 변환이 누락되면 Response에서도 그대로 노출된다.
- RED: `AudioRankingQueryServiceTest.shouldReturnLatestVisibleSnapshotsWithRankChangesAndNewFlags`에 스냅샷 fixture의 `coverImageUrl = "cover-N.png"`가 응답 item에서는 `https://cdn.test/cover-N.png`로 변환되어야 한다는 assertion을 추가한다. 기존 구현에서는 path만 반환하므로 이 assertion이 실패해야 한다.
- GREEN: `AudioRankingQueryService` 생성자에 `@Value("\${cloud.aws.cloud-front.host}") private val cloudFrontHost: String`을 주입하고, `AudioRankingSnapshotRecord.toItem(...)`에서 `coverImageUrl.toCdnUrl(cloudFrontHost)`를 사용한다. 이 방식은 `null`/blank는 `null`, 이미 `http://` 또는 `https://`로 시작하는 값은 그대로 유지하는 기존 공통 확장 함수를 재사용한다.
- REFACTOR: 별도 URL helper를 새로 만들지 않는다. 스냅샷 저장 데이터를 full URL로 마이그레이션하지 않고, 공개 응답 조립 지점에서만 변환해 기존 데이터와 신규 데이터 모두 동일하게 처리한다.
- 기대 결과: `GET /api/v2/audio/rankings` 응답의 `items[*].coverImageUrl`은 path가 아니라 `cloud.aws.cloud-front.host`가 포함된 이미지 URL로 내려간다.
## Phase 9 검증 기록
- 2026-06-25 문서 갱신: 사용자 후속 요청에 따라 `prd.md``coverImageUrl` host 누락 버그, 공개 응답 URL 정책, `toCdnUrl` 기반 변환 규칙을 추가했다. `plan-task.md`에는 버그 내용, 영향 범위, 원인, RED/GREEN/REFACTOR 기준을 Phase 9로 누적 기록했다.
- 2026-06-25 focused 검증: `./gradlew test --tests kr.co.vividnext.sodalive.v2.content.ranking.application.AudioRankingQueryServiceTest` 실행 결과 `BUILD SUCCESSFUL in 30s`를 확인했다. 이 테스트는 스냅샷 fixture의 path 값(`cover-N.png`)이 응답 item에서는 `https://cdn.test/cover-N.png`로 변환되는지 검증한다.
- 2026-06-25 문서 명령 검증: `./gradlew tasks --all` 실행 결과 `BUILD SUCCESSFUL in 8s`를 확인했고, `rg -n "coverImageUrl|Phase 9|cdn|cloud-front|toCdnUrl|host 없는 path|CDN host" docs/20260623_메인_콘텐츠_랭킹_탭_API/prd.md docs/20260623_메인_콘텐츠_랭킹_탭_API/plan-task.md`로 PRD와 plan-task에 버그 내용 및 수정 정책이 반영된 위치를 확인했다.
- 2026-06-25 포맷 검증: `./gradlew ktlintCheck` 실행 결과 `BUILD SUCCESSFUL in 32s`를 확인했다.
- 2026-06-25 회귀 검증: `./gradlew test --tests 'kr.co.vividnext.sodalive.v2.api.content.ranking.*'` 실행 결과 `BUILD SUCCESSFUL in 1m 4s`를 확인했다. `./gradlew test --tests 'kr.co.vividnext.sodalive.v2.content.ranking.*'`를 API 테스트와 병렬 실행했을 때는 `build/test-results/test/TEST-*.xml` 파일 쓰기 충돌로 실패했으나, 동일 명령을 단독 재실행해 `BUILD SUCCESSFUL in 19s`를 확인했다.