7.8 KiB
7.8 KiB
추천 탭 배너 접속 국가별 언어 필터 PRD
문서 정보
| 항목 | 내용 |
|---|---|
| 문서 상태 | 구현 기준 확정 |
| 작성일 | 2026-08-19 |
| 최종 수정일 | 2026-08-19 |
| 대상 제품 | 메인 홈 추천 탭, 메인 콘텐츠 추천 탭 |
| 작성자·결정권자 | 사용자 |
| 관련 API Contract | 신규 없음. 기존 공개 API 계약 유지 |
| 관련 구현 계획 | docs/20260819_추천탭_배너_접속국가별_언어필터/plan-task.md |
| 관련 기존 문서 | docs/20260805_추천탭_배너_조회조건/prd.md, docs/20260529_메인_홈_추천_API/prd.md, docs/20260623_메인_콘텐츠_추천_탭_API/prd.md |
1. Overview
메인 홈 추천 API와 메인 콘텐츠 추천 API에서 접속 국가에 맞는 언어의 배너만 반환한다. 로그인 회원은 기존 강제 국가 매핑을 포함한 국가 판정 결과를 사용하고, 비로그인 사용자는 CloudFront-Viewer-Country 요청 헤더를 기준으로 판정한다.
2. Problem Statement
- 두 추천 API의 현재 배너 QueryDSL 조회에는
content_banner.lang조건이 없다. - 그 결과 한국어·일본어·영어 배너가 같은 응답에 섞일 수 있다.
- 언어 필터가 조회 후 적용되면 다른 언어 배너가 limit을 차지해 필요한 배너가 누락될 수 있다.
문제를 해결했다는 판단은 두 API가 배너 정렬과 limit 적용 전에 확정된 언어 조건을 적용하고, 기존 배너 조회 조건과 공개 응답 스키마를 유지하는 것으로 한다.
3. Goals
- 접속 국가 판정 결과가
JP이면Lang.JA배너만 반환한다. JP이외의 국가와 국가 정보가 없는 경우에는Lang.KO배너만 반환한다.- 로그인 회원은
MemberContentPreferenceService.resolveCountryCode의 기존 강제 국가 매핑을 유지한다. - 비로그인 사용자도 요청 국가를 판정할 수 있도록 동일한 국가 정규화와 기본값 정책을 사용한다.
- 언어 조건을 DB 조회 단계에서 정렬·limit보다 먼저 적용한다.
4. Non-Goals
Lang.EN배너를 반환하는 국가 정책을 추가하지 않는다.Accept-Language를 배너 언어 판정에 사용하지 않는다.CloudFront-Viewer-Country헤더 계약이나CountryInterceptor를 변경하지 않는다.- 공개 API endpoint, request/response DTO와 응답 스키마를 변경하지 않는다.
- 기존 배너의 탭·성인·활성·차단·대상 유효성·정렬·limit 정책을 변경하지 않는다.
- DB 스키마, 배너 데이터, 관리자 배너 API와 기존 v1 배너 조회를 변경하지 않는다.
- 배너 이외의 추천 섹션에 국가 또는 언어 필터를 추가하지 않는다.
5. 대상 사용자와 국가 판정
| 사용자 | 국가 판정 | 언어 선택 |
|---|---|---|
| 강제 JP 매핑 로그인 회원 | 기존 강제 매핑 결과 JP |
Lang.JA |
| 강제 KR 매핑 로그인 회원 | 기존 강제 매핑 결과 KR |
Lang.KO |
| 일반 로그인 회원 | 정규화한 CloudFront-Viewer-Country, 누락 시 KR |
JP이면 JA, 그 외 KO |
| 비로그인 사용자 | 정규화한 CloudFront-Viewer-Country, 누락 시 KR |
JP이면 JA, 그 외 KO |
국가 코드는 기존 정책처럼 앞뒤 공백을 제거하고 대문자로 정규화한다.
6. 핵심 조회 흐름
CountryInterceptor가CloudFront-Viewer-Country를CountryContext에 저장한다.HomeRecommendationFacade.getHomeRecommendations와AudioRecommendationQueryService.getRecommendations가 회원과 요청 국가로 국가 코드를 판정한다.- 국가 코드가
JP이면Lang.JA, 그 외에는Lang.KO를 선택한다. - 선택한
Lang을 기존 application → port → persistence 경로로 전달한다. - Repository가
content_banner.lang = :lang을 기존 조건과 함께 적용한 뒤 정렬하고 limit을 적용한다.
7. 기능 요구사항
| ID | 상태 | 요구사항 | 수용 기준 | Goal 연결 |
|---|---|---|---|---|
BANNER-LANG-001 |
확정 | GET /api/v2/home/recommendations는 판정 국가가 JP이면 JA, 그 외에는 KO 홈 배너만 반환한다. |
tab_id IS NULL인 활성 배너 중 선택 언어와 일치하는 배너만 응답한다. |
P1-T2 |
BANNER-LANG-002 |
확정 | GET /api/v2/audio/recommendations는 판정 국가가 JP이면 JA, 그 외에는 KO 콘텐츠 추천 배너만 반환한다. |
tab_id = 2인 활성 배너 중 선택 언어와 일치하는 배너만 응답한다. |
P1-T3 |
BANNER-LANG-003 |
확정 | 로그인 회원의 국가 판정은 기존 강제 KR/JP 매핑을 요청 헤더보다 우선한다. | 강제 JP 회원은 비JP 헤더에서도 JP, 강제 KR 회원은 JP 헤더에서도 KR로 판정된다. |
P1-T1 |
BANNER-LANG-004 |
확정 | 비로그인 사용자는 요청 국가를 정규화해 사용하고, 헤더가 없거나 비어 있으면 KR로 판정한다. |
JP·jp·공백 포함 JP는 JP, null·blank는 KR로 판정된다. |
P1-T1 |
BANNER-LANG-005 |
확정 | 언어 필터는 정렬·limit 전에 DB 조회 조건으로 적용한다. | 다른 언어 배너가 limit을 차지하지 않고, Repository 테스트가 언어별 결과를 검증한다. | P1-T2, P1-T3 |
BANNER-LANG-006 |
확정 | 기존 배너 조회 정책과 공개 API 계약을 유지한다. | 기존 탭·성인·활성·차단·대상 유효성·정렬·limit 테스트와 controller/E2E 회귀가 통과한다. | P1-GATE |
8. API 계약
| Method | Path | 변경 내용 |
|---|---|---|
GET |
/api/v2/home/recommendations |
응답 스키마 변경 없이 접속 국가별 배너 언어 조회 조건만 추가한다. |
GET |
/api/v2/audio/recommendations |
응답 스키마 변경 없이 접속 국가별 배너 언어 조회 조건만 추가한다. |
- 신규 request header는 추가하지 않는다.
- 기존
CloudFront-Viewer-Country처리 경로를 재사용한다. - 배너가 없으면 기존처럼 빈 목록을 반환한다.
9. 성능과 품질 요구사항
content_banner.lang조건은 QueryDSLwhere에 포함하고 메모리 후처리를 사용하지 않는다.- 신규 dependency, 캐시, 공통 resolver abstraction을 추가하지 않는다.
- 기존
Lang,CountryContext,MemberContentPreferenceService를 재사용한다. - application 전달 테스트와 두 Repository 조회 테스트를 TDD로 보강한다.
- 직접 영향 controller/E2E 회귀와
ktlintCheck를 Phase Gate에서 검증한다.
10. 성공 기준
- 강제 매핑을 포함한 판정 국가가
JP이면 두 API의 배너가 모두JA로 제한된다. (BANNER-LANG-001~003) - 일반 국가와 국가 정보가 없는 경우 두 API의 배너가 모두
KO로 제한된다. (BANNER-LANG-001,BANNER-LANG-002,BANNER-LANG-004) - 다른 언어 배너가 정렬·limit 대상에 포함되지 않는다. (
BANNER-LANG-005) - 기존 배너 필터와 공개 응답 계약이 유지된다. (
BANNER-LANG-006)
11. Open Questions
- 없음.
12. Decision Log
| 날짜 | ID | 상태 | 결정 | 근거 | 영향 요구사항·Goal |
|---|---|---|---|---|---|
| 2026-08-19 | DEC-001 |
확정 | JP는 JA, 그 외 국가는 KO 배너만 조회한다. |
사용자 인터뷰 답변 B | BANNER-LANG-001, BANNER-LANG-002, BANNER-LANG-005 |
| 2026-08-19 | DEC-002 |
확정 | 로그인 회원은 기존 강제 국가 매핑을 포함한 국가 판정을 사용한다. | 사용자 인터뷰 답변 B | BANNER-LANG-003, P1-T1 |
| 2026-08-19 | DEC-003 |
확정 | 비로그인은 요청 국가를 사용하고 국가 정보가 없으면 기존 기본값 KR을 사용한다. |
승인된 설계 | BANNER-LANG-004, P1-T1 |
| 2026-08-19 | DEC-004 |
확정 | 언어 필터는 Repository 조회 조건으로 적용한다. | limit 이전 필터링과 기존 QueryDSL 패턴 유지 | BANNER-LANG-005, P1-T2, P1-T3 |