docs(banner): 예약 기간 계약과 검증 결과를 기록한다

This commit is contained in:
2026-10-27 20:49:42 +09:00
parent 69e6b7d24c
commit 70eaf39475
4 changed files with 472 additions and 0 deletions
@@ -0,0 +1,46 @@
# 콘텐츠 배너 예약 최종 리뷰
## 리뷰 정보
| 항목 | 내용 |
|---|---|
| 대상 | P1-T2와 전체 working tree 변경, P1-GATE |
| 일자 | 2026-10-27 |
| 리뷰어 | Oracle 독립 통합 리뷰, parent 실행 검증 |
| 기준 | `../prd.md`, `../plan-task.md`, `admin-reservation-review.md` |
| 상태 | 판정 완료 |
## 목적과 범위
관리자 예약 설정에서 공개 배너 노출 판정까지 승인된 계약이 연결되는지 확인했다. 관리자 DTO/service/repository/응답·entity, 네 공개 query와 공유 predicate, 관련 테스트·DDL을 검토했다. 새로운 기능 설계나 다른 배너 도메인, 전역 보안·시간대 설정 변경은 범위 밖이다.
## 검토 근거
- 공개 query: `AudioContentQueryRepositoryImpl.getAudioContentMainBannerList`, `AudioContentBannerQueryRepositoryImpl.getAudioContentMainBannerList`, `DefaultHomeRecommendationQueryRepository.findHomeBanners`, `DefaultAudioRecommendationQueryRepository.findBanners` 모두 기존 조건에 공유 `isVisibleAt(now)`를 AND 적용한다. v2는 limit 전에 예약을 제외한다.
- 경계: NULL 제한 없음과 양 끝 포함, 초 단위 UTC now, 종료 분 마지막 초의 나노초·자정 경계를 확인했다. 네 생성자의 optional nowProvider는 기존 호출과 Spring 주입을 유지한다.
- 관리자: 엄격한 문자열/JSON 타입 및 effective 기간 검증이 S3·entity 변경보다 앞선다. update 생략 유지/명시 null 해제, KST 입력/응답·UTC 저장, 관리자 날짜 무관 조회와 기존 active/tab 조건을 확인했다.
- 응답: QueryProjection 보조 생성자와 생성 Q 타입의 `LocalDateTime` 인자 일치 및 UTC→KST 문자열 변환을 확인했다. 공개 서비스의 기존 DTO 매핑은 예약 필드를 공개 응답에 추가하지 않는다.
- 테스트: 공유 16-case matrix × 4 query, 실제 H2 `TIMESTAMP(0)` 저장/flush/clear/재조회, v2 limit 충족 및 관리자 multipart HTTP 계약을 확인했다.
## 실행 증거
parent가 다음 명령을 실행했다. Oracle은 같은 테스트를 중복 실행하지 않고 정적 검토를 수행했다.
```bash
./gradlew test --rerun --tests '*AdminContentBannerControllerIntegrationTest' --tests '*AdminContentBannerServiceTest' --tests '*AudioContentBannerRepositoryTest' --tests '*AudioContentRepositoryBannerTest' --tests '*DefaultHomeRecommendationQueryRepositoryTest' --tests '*DefaultAudioRecommendationQueryRepositoryTest' ktlintCheck bootJar tasks --all --console=plain
```
- exit 0, `BUILD SUCCESSFUL in 46s`; test 강제 재실행, ktlint 통과와 실행 JAR 패키징 성공.
- XML 직접 집계: 72 + 1 + 19 + 18 + 98 + 29 = 237건, failures/errors/skipped 모두 0.
- `git diff --check` exit 0. LSP 도구가 없어 main/test Kotlin 컴파일과 ktlint로 정적 검증을 대체했다.
- 관리자 surface는 MockMvc POST/PUT/GET, 공개 persistence surface는 실제 QueryDSL/JPA/H2로 실행했다. 별도 공개 live HTTP/curl과 운영 DB는 검증하지 않았다.
## 발견 사항과 종료 판정
**확정 발견 사항 없음.** 명세 준수와 코드 품질 모두 APPROVE다. P1-T2/전체 변경을 함께 검토했으며 누락된 조회 경로나 Gate를 막는 테스트 공백을 발견하지 못했다. 신규 회귀 Task 전환 항목은 없다.
앞선 관리자 JSON 객체/배열 오류는 P1-T1-R1로 수정·검증됐으며 이번 전체 검토에서도 유지됨을 확인했다. parent의 fresh 실행 결과와 함께 P1-GATE 완료 근거로 사용한다.
## 잔여 검증 경계
전체 test/check/build는 실행하지 않았고, 직접 영향받는 여섯 클래스 회귀와 bootJar 패키징만 실행했다. 운영 MySQL의 TIMESTAMP 허용 범위, JDBC/session timezone 및 실제 DDL 왕복은 미검증이며 입증된 코드 결함으로 판정하지 않았다. nullable 컬럼 추가 DDL은 backfill 없이 기존 NULL 노출을 유지하며, 앱 rollout 전에 별도 승인 절차로 적용해야 한다.