docs(banner): 언어 필터 계약과 검증 결과를 기록한다
This commit is contained in:
@@ -4,9 +4,9 @@
|
||||
|
||||
| 항목 | 내용 |
|
||||
|---|---|
|
||||
| 문서 상태 | 소프트 삭제·두 추천 API 통합 및 전체 검증 완료, 미배포 |
|
||||
| 문서 상태 | Phase 7 언어 필터 후속 구현·전체 검증·독립 리뷰 완료, 미배포 |
|
||||
| 작성일 | 2026-10-29 |
|
||||
| 최종 수정일 | 2026-10-29 |
|
||||
| 최종 수정일 | 2026-11-03 |
|
||||
| 대상 기능 | 가로형 서브 배너 백엔드 및 영속성 |
|
||||
| 관련 API 계약 | [api-contract.md](api-contract.md), 구현·실제 HTTP 검증 기준 |
|
||||
| 구현 계획 | [plan-task.md](plan-task.md) |
|
||||
@@ -43,6 +43,7 @@
|
||||
- **G2:** 관리자 API는 ADMIN만 사용하고 이미지 multipart 포함 CRUD를 제공하며, payload 검증이 업로드와 영속화보다 먼저 이뤄진다. (`SB-004`~`SB-007`, `SB-011`)
|
||||
- **G3:** 공개 GET은 placement와 유효 기간으로 필터링하고 전체 목록을 id 오름차순으로 반환하며, 날짜 없는 공개 DTO와 공통 응답 envelope를 유지한다. (`SB-008`~`SB-009`)
|
||||
- **G4:** 배포 DDL은 적용·롤백 영향을 명시하며 기존 콘텐츠 배너 테이블과 데이터를 변경하지 않는다. (`SB-010`)
|
||||
- **G5 (2026-11-02 승인 후속):** 서브 배너는 기존 `Lang`으로 저장되고 두 추천 API는 회원 접속 국가에 맞는 언어만 반환하며, 관리자는 모든 언어 항목을 조회·관리할 수 있다. (`SB-013`)
|
||||
|
||||
### 포함 범위
|
||||
|
||||
@@ -82,6 +83,7 @@
|
||||
| `SB-010` | 작성자 데이터 안전 제안 | 신규 테이블 DDL과 적용 전후 안전성을 제공한다. | `docs/20261029_가로형서브배너/create-sub-banner.sql`에 모든 column/table COMMENT, nullable UTC `TIMESTAMP` 기간 컬럼, 필요 시 기존 audit timestamp 관례를 포함한다. 계획에 적용 조건과 rollback 절차를 적고 자동 live DDL은 하지 않는다. | §1, `P2-T1` |
|
||||
| `SB-011` | 작성자 API/오류 제안 | 성공 envelope와 계약된 응답 shape를 일관되게 유지한다. | 성공은 `ApiResponse<T>` 4필드, HTTP 200, 관리자 빈 목록 `[]`, 관리자 POST/PUT 객체, DELETE `null`, 공개 날짜 미포함. 잘못된 입력/없음 상태의 status는 API 계약 검토 후 기존 handler를 활용하거나 endpoint 경계에서 처리한다. | `api-contract.md` §1, §5, `P3-T1`, `P4-T1` |
|
||||
| `SB-012` | 사용자 후속 확정 | 관리자 삭제는 `is_active=false` 소프트 삭제다. | DB 행·이미지 key·주소·기간·생성 시각을 보존한다. 관리자/공개 목록과 id 조회에서 비활성 행을 제외하며 삭제된 id 수정·재삭제는 404다. 응답에 isActive를 추가하지 않고 S3는 보존한다. 복구/활성 토글/cleanup은 범위 밖이다. | §3, `P5-T1` |
|
||||
| `SB-013` | 사용자 후속 확정, 2026-11-02 | 서브 배너 언어는 기존 `Lang`의 `KO`, `EN`, `JA` 중 하나로 저장한다. 관리자 생성에서 생략하면 KO, 수정에서 생략하면 기존 값을 유지하고 응답에는 `lang`을 포함한다. 공개 추천은 기존 회원 국가 판정 JP→JA, 그 외→KO를 적용한다. | 명시적 null·비문자열·잘못된 코드는 HTTP 400이며 업로드/저장 전 거부된다. 관리자 목록은 언어 미필터 전체 조회다. public repository에는 필수 `Lang` 조건을 전달하고 public `SubBanner` DTO는 변경하지 않는다. 기존 행은 KO로 backfill하며 JA 분류 및 연결 이벤트와의 언어 정합성은 운영 담당자가 수동 확인한다. | §3, `P7-T1`, `P7-GATE` |
|
||||
|
||||
## API 및 데이터 계약
|
||||
|
||||
@@ -125,6 +127,7 @@
|
||||
- [x] payload 검증 실패의 이미지 upload/DB mutation 0회와 실제 오류 응답을 검증했다.
|
||||
- [x] 전체 2,676 tests, lint, bootJar 및 독립 최종 리뷰 통과. 운영 DB 적용·배포는 별도이며 완료로 표시하지 않는다.
|
||||
- [x] 후속 P5·P6는 전체 2,682 tests(실패·무시 0), lint·bootJar와 독립 리뷰를 통과했다. 비로그인 두 추천 응답의 subBanners와 standalone handler 제거, 소프트 삭제 행 보존 및 동시 비복원을 실제 HTTP/DB로 검증했다. 앞선 2,676건은 초기 구현 이력이다.
|
||||
- [x] 후속 `SB-013`: 기존 `Lang` 필드, 관리자 생성 KO 기본값·수정 생략 유지·잘못된 값의 부작용 전 HTTP 400, 관리자 전체 언어 목록, 두 공개 추천 API의 회원 국가별 언어 필터와 public DTO 불변을 검증했다. (`P7-T1`, `P7-GATE`; 2026-11-03 전체 2,928개 및 영향 HTTP 재검증 완료)
|
||||
|
||||
## Decision Log
|
||||
|
||||
@@ -141,6 +144,7 @@
|
||||
| 2026-10-29 | DEC-009 | 사용자 구현 승인 | 문서대로 백엔드 코드와 DDL 파일을 구현한다. 운영 DB 적용·배포는 승인 범위에 포함하지 않는다. 기존 기간·독립 API 모델을 사용하며 검증 시 H2·테스트 JWT·S3 대체 객체로 외부 부작용을 격리한다. | 후속 사용자 요청 및 ulw 실행 |
|
||||
| 2026-10-29 | DEC-010 | 사용자 후속 확정·정정 | `is_active BOOLEAN NOT NULL DEFAULT TRUE`를 추가하고 DELETE는 false 갱신으로 변경한다. 삭제된 행은 모든 소비자 조회에서 제외하며 응답·권한·기간·S3 정책은 유지한다. 앞선 하드 삭제 완료 기록은 당시 이력으로 보존한다. | "is_active를 두고 소프트 삭제로 하자" |
|
||||
| 2026-10-29 | DEC-011 | 사용자 후속 확정·정정 | 별도 앱 GET을 제거하고 두 추천 GET에 `data.subBanners`를 추가한다. 두 GET 모두 비로그인 접근을 유지하고 앱 프롬프트도 함께 변경한다. 관리자 CRUD·소프트 삭제·기간·응답 항목은 유지한다. | 두 추천 API 통합 및 앱 프롬프트 수정 요청 |
|
||||
| 2026-11-02 | DEC-012 | 사용자 후속 확정 | 서브 배너에 기존 `Lang` enum 필드를 추가한다. 관리자 생성 누락은 KO, 수정 누락은 유지, 명시적 null·비문자열·invalid는 HTTP 400이며 upload/write 전 검증한다. 관리자 목록은 언어 전체 조회, 공개 두 추천은 회원 국가 기준 JP→JA/그 외→KO로 필터링한다. public DTO는 유지한다. | 승인된 최소 이벤트/서브 배너 언어 후속 수정 |
|
||||
|
||||
## 후속 사용자 요구사항: 관리자 노출 기간
|
||||
|
||||
@@ -150,3 +154,13 @@
|
||||
- 공개 조회는 현재 기간 안에 있는 항목 전체를 반환한다. 앱은 그 결과에 기존 웹 URL/현재 OS 딥링크 필터를 적용하며 앱 로컬 시계로 기간을 계산하지 않는다.
|
||||
- 공개 DTO에는 날짜·활성 필드를 추가하지 않는다. 관리자 목록은 삭제되지 않은 활성 행의 미래·현재·만료·무제한 상태를 모두 포함한다.
|
||||
- 기존 근거는 `docs/20261027_콘텐츠배너예약기간/prd.md` §6-8, `AdminContentBannerService.kt` 및 `GetAdminContentBannerResponse.kt`다. 신규 계약의 승인이나 구현을 뜻하지 않는다.
|
||||
|
||||
## 후속 사용자 요구사항: 서브 배너 언어 — 2026-11-02
|
||||
|
||||
- `SubBanner` domain, JPA entity/storage, admin request와 admin response에 기존 `Lang`의 `KO`, `EN`, `JA`를 추가한다. 새 enum은 만들지 않는다.
|
||||
- 관리자 create에서 `lang`을 생략하면 KO로 저장한다. update에서 생략하면 기존 언어를 보존한다. 명시적 null, JSON 비문자열 또는 유효하지 않은 코드는 HTTP 400으로 거부하고 S3 upload와 DB write 이전에 검증한다.
|
||||
- 관리자 목록은 기존 placement 조건 외 언어 필터를 추가하지 않으며 응답마다 `lang`을 반환한다. public `SubBannerResponse`에는 `lang`을 노출하지 않는다.
|
||||
- 공개 조회 service는 member를 받아 기존 `MemberContentPreferenceService.resolveCountryCode(member)`로 JP→JA, 그 외→KO를 선택하고 이를 필수 Lang으로 repository에 전달한다. 두 추천 facade는 기존 member를 service에 전달한다.
|
||||
- 기존 테이블 CREATE SQL에는 `lang VARCHAR(10) NOT NULL DEFAULT 'KO'`를 포함한다. 별도 신규 migration SQL은 기존 테이블에 언어 컬럼을 안전하게 추가하고 null 값을 KO로 backfill한 뒤 NOT NULL DEFAULT KO를 적용한다.
|
||||
- KO backfill은 기존 행의 언어를 자동 추론하지 않는다. 운영 적용 전에 배너 소재를 검토해 JA 배너와 연결 이벤트의 언어를 운영 담당자가 수동 분류·정합성 확인해야 한다. 운영 DB에 DDL을 실행하지 않는다.
|
||||
- 제외: 앱/관리자 UI, event link parsing, event detail/adult 정책 변경, 새 dependency, public DTO 변경, 운영 DB·DDL 실행.
|
||||
|
||||
Reference in New Issue
Block a user