# 추천 탭 배너 조회 조건 보정 Implementation Plan | 문서 항목 | 내용 | |---|---| | 상태 | 구현 완료 | | 작성일 | 2026-08-05 | | 요구사항 기준 | `docs/20260805_추천탭_배너_조회조건/prd.md` | | API 기준 | 기존 공개 API 계약 유지 | | 현재 Phase | Phase 1: 배너 조회 조건 보정 | | 현재 활성 Goal | 없음 | ## 목표 메인 홈 추천과 메인 콘텐츠 추천에서 화면별 탭과 회원의 성인 콘텐츠 조회 가능 여부에 맞는 배너만 조회한다. ## 현재 상태 | Phase | 상태 | 완료 Task | 활성/다음 Goal | 차단 또는 남은 조건 | |---:|---|---:|---|---| | 1 | 완료 | `2/2` | 없음 | 없음 | ## 범위 ### 포함 - 홈 추천 배너의 `tab_id IS NULL` 조건 유지 및 성인 배너 필터 추가 - 콘텐츠 추천 배너의 `tab_id = 2` 조건과 성인 배너 필터 추가 - application에서 계산한 성인 콘텐츠 조회 가능 여부를 persistence port까지 전달 - 관련 service/facade/Repository focused test와 직접 영향 범위 회귀 ### 제외 - 공개 API endpoint와 응답 DTO 변경 - 배너 언어/활성/차단/대상 유효성/정렬/limit 정책 변경 - DB 데이터 또는 스키마 변경 ## 기술적 제약 - Kotlin, Spring Boot 2.7.14, QueryDSL 기존 패턴을 유지한다. - 성인 콘텐츠 조회 가능 여부는 `MemberContentPreferenceService.canViewAdultContent(member)` 결과를 재사용한다. - 조회 가능 여부가 `false`이면 `audioContentBanner.isAdult.isFalse`, `true`이면 성인 조건을 추가하지 않는다. - 신규 공통 추상화나 의존성을 추가하지 않는다. ### Phase 1: 배너 조회 조건 보정 - [x] **Task 1.1: 추천 API별 탭 및 성인 배너 조회 조건 구현 (`P1-T1`)** - Objective: 두 추천 API의 배너가 확정된 탭과 성인 콘텐츠 조회 정책에 따라 반환된다. - 시작 조건: PRD `BANNER-001~004`가 확정되어 있다. - 완료 증거: 신규/보강 테스트가 RED 후 GREEN이고 관련 production/test 코드가 컴파일된다. - 범위 밖: 언어 필터와 공개 응답 스키마 변경. - Modify: - `src/main/kotlin/kr/co/vividnext/sodalive/v2/api/home/application/HomeRecommendationFacade.kt` - `src/main/kotlin/kr/co/vividnext/sodalive/v2/recommendation/application/HomeRecommendationQueryService.kt` - `src/main/kotlin/kr/co/vividnext/sodalive/v2/recommendation/port/out/HomeRecommendationQueryPort.kt` - `src/main/kotlin/kr/co/vividnext/sodalive/v2/recommendation/adapter/out/persistence/DefaultHomeRecommendationQueryRepository.kt` - `src/main/kotlin/kr/co/vividnext/sodalive/v2/content/recommendation/adapter/out/persistence/DefaultAudioRecommendationQueryRepository.kt` - `src/test/kotlin/kr/co/vividnext/sodalive/v2/api/home/application/HomeRecommendationFacadeTest.kt` - `src/test/kotlin/kr/co/vividnext/sodalive/v2/recommendation/application/HomeRecommendationQueryServiceTest.kt` - `src/test/kotlin/kr/co/vividnext/sodalive/v2/recommendation/adapter/out/persistence/DefaultHomeRecommendationQueryRepositoryTest.kt` - `src/test/kotlin/kr/co/vividnext/sodalive/v2/content/recommendation/adapter/out/persistence/DefaultAudioRecommendationQueryRepositoryTest.kt` - RED: 홈 성인 조회 플래그 전달, 홈 비성인 필터, 콘텐츠 `tab_id = 2` 및 비성인 필터를 검증하는 테스트를 먼저 작성하고 실패를 확인한다. - GREEN: 기존 QueryDSL 조건에 필요한 탭/성인 조건만 추가하고 홈 application 경로에 플래그를 전달한다. - REFACTOR: 중복되지 않는 기존 조건 helper 패턴을 따르고 불필요한 변경이 없는지 확인한다. - Verify: - `./gradlew test --tests kr.co.vividnext.sodalive.v2.api.home.application.HomeRecommendationFacadeTest --tests kr.co.vividnext.sodalive.v2.recommendation.application.HomeRecommendationQueryServiceTest --tests kr.co.vividnext.sodalive.v2.recommendation.adapter.out.persistence.DefaultHomeRecommendationQueryRepositoryTest --tests kr.co.vividnext.sodalive.v2.content.recommendation.adapter.out.persistence.DefaultAudioRecommendationQueryRepositoryTest` - 검증 기록: - RED: 두 Repository 테스트를 실행해 `shouldExcludeAdultHomeBannersWhenAdultContentIsNotVisible`, `shouldFindBannersForContentRecommendationTabWithAdultVisibility` 두 건의 기대값 실패를 확인했다. - RED: 홈 service 테스트는 `includeAdultBanners` 미구현 컴파일 실패, Facade 테스트는 플래그 미전달 assertion 실패를 각각 확인했다. - GREEN: 위 4개 focused test class를 함께 실행해 `BUILD SUCCESSFUL`을 확인했다. - [x] **Task 1.2: 영향 범위 회귀 및 문서 검증 (`P1-GATE`)** - Objective: 추천 배너 변경이 기존 API 계약과 코드 품질 규칙을 깨지 않았음을 확인한다. - 시작 조건: `P1-T1`이 완료되어 있다. - 완료 증거: focused test, `ktlintCheck`, `tasks --all`, `git diff --check`가 통과하고 결과가 기록되어 있다. - 범위 밖: 전체 회귀 테스트. 변경이 배너 조회 경로 두 곳에 한정되어 targeted test로 직접 영향 범위를 판단할 수 있으므로 생략한다. - Verify: - `./gradlew test --tests kr.co.vividnext.sodalive.v2.api.home.application.HomeRecommendationFacadeTest --tests kr.co.vividnext.sodalive.v2.recommendation.application.HomeRecommendationQueryServiceTest --tests kr.co.vividnext.sodalive.v2.recommendation.adapter.out.persistence.DefaultHomeRecommendationQueryRepositoryTest --tests kr.co.vividnext.sodalive.v2.content.recommendation.adapter.out.persistence.DefaultAudioRecommendationQueryRepositoryTest` - `./gradlew ktlintCheck` - `./gradlew tasks --all` - `git diff --check` - 검증 기록: - `HomeRecommendationControllerTest`, `AudioRecommendationControllerTest`, `AudioRecommendationEndToEndTest`를 함께 실행해 `BUILD SUCCESSFUL`을 확인했다. - `./gradlew ktlintCheck`: `BUILD SUCCESSFUL`. - `./gradlew tasks --all`: `BUILD SUCCESSFUL`. - `git diff --check`: 출력 없음. ## 검증 기록 - 최초 Gradle 실행은 sandbox의 `~/.gradle` wrapper lock 접근 제한으로 실패했으며, 승인된 동일 명령을 재실행해 검증을 완료했다. - 전체 회귀 테스트는 실행하지 않았다. 변경이 두 배너 조회 조건과 홈 플래그 전달에 한정되어 focused Repository/application 테스트와 두 API의 controller/E2E 회귀로 직접 영향 범위를 검증했다.