refactor(subbanner): 언어 이관을 정적 SQL로 단순화한다
This commit is contained in:
@@ -2,11 +2,11 @@
|
||||
|
||||
| 문서 항목 | 내용 |
|
||||
|---|---|
|
||||
| 상태 | P7 언어 후속 구현·전체 검증·독립 리뷰 완료, 미배포 |
|
||||
| 상태 | P7 언어 기능·P8 정적 이관 SQL 검증 및 리뷰 완료, 미배포 |
|
||||
| 작성일 | 2026-10-29 |
|
||||
| 요구사항 기준 | [prd.md](prd.md) |
|
||||
| API 기준 | [api-contract.md](api-contract.md), 실제 구현·HTTP 검증 계약 |
|
||||
| 현재 Phase | Phase 2~7 완료 |
|
||||
| 현재 Phase | Phase 2~8 완료 |
|
||||
| 현재 활성 Goal | 없음 |
|
||||
| 다음 Goal | 없음 |
|
||||
|
||||
@@ -588,7 +588,7 @@ export TMPDIR=/tmp/soda-banner-impl.CfAkhD NODE_COMPILE_CACHE=/tmp/soda-banner-i
|
||||
./gradlew test ktlintCheck bootJar --continue --console=plain
|
||||
```
|
||||
|
||||
**DDL requirements:** both SQL artifacts define `lang VARCHAR(10) NOT NULL DEFAULT 'KO'` with a column comment. The migration safely adds a missing column, backfills NULL rows to KO, then enforces NOT NULL/default, following the existing project SQL pattern. Before production application, warn that KO is only a safe placeholder: operations must manually identify JA banners and verify language consistency against linked events. No event link parser or automatic classification is allowed. Production DB/DDL execution is not part of this goal.
|
||||
**DDL requirements:** both SQL artifacts define `lang VARCHAR(10) NOT NULL DEFAULT 'KO'` with a column comment. DEC-013 supersedes the original guarded migration with one static ALTER TABLE for an existing table without lang. Existing rows receive KO; do not rerun when lang exists. Before production application, operations must manually identify JA banners and verify language consistency against linked events. No event link parser or automatic classification is allowed. Production DB/DDL execution is not part of this goal.
|
||||
|
||||
### Phase 7 Gate `P7-GATE`
|
||||
|
||||
@@ -616,3 +616,32 @@ export TMPDIR=/tmp/soda-banner-impl.CfAkhD NODE_COMPILE_CACHE=/tmp/soda-banner-i
|
||||
- 원본 `/tmp/soda-banner-ulw.HDkpg4/full-verification.log`, `final-verification.log` 및 구현자 임시 증거는 작업 종료 시 정리한다. 재현 테스트 소스, 최신 build reports, 본 검증 기록과 [공동 리뷰](reviews/banner-language-review.md)를 남긴다.
|
||||
- 독립 Oracle 리뷰는 명세·코드·시나리오 APPROVE, 후속 공백 delta 및 최종 검증 Gate도 APPROVE했다. 미해결 발견 사항 없음. `P7-T1/P7-GATE` 완료이며 운영 DDL·배포는 별도다.
|
||||
- 서브 배너 구현·SQL·테스트 커밋 `c4c61e36`, hook/메시지 검사 통과. 소유 임시 자료·QA 프로세스 정리와 build 산출물 보존은 공동 리뷰의 종료 증거에 기록했다. 운영 DDL·배포·push는 하지 않았다.
|
||||
|
||||
## Phase 8: 정적 이관 SQL
|
||||
|
||||
### Task 8.1 단일 ALTER TABLE 전환 (`P8-T1`)
|
||||
|
||||
- Objective: 저장 프로시저·동적 SQL 없이 기존 lang 미존재 테이블에 KO 기본 언어 컬럼을 추가한다.
|
||||
- 시작 조건: DEC-013 사용자 요청, 기존 SQL 및 MySQL ALTER 문법 확인.
|
||||
- Files: `docs/20261029_가로형서브배너/20261102_add_sub_banner_lang.sql`, `prd.md`, `api-contract.md`, `plan-task.md`.
|
||||
- 범위 밖: 앱 코드·신규 CREATE 변경, 이미 존재하는 컬럼 정정, 자동 재실행, 운영 DB 접속·실행.
|
||||
- TDD 예외: 애플리케이션 로직 변경 없이 배포 SQL 표현을 단순화한다. H2에서 기존 MySQL PREPARE가 실패하는 것을 기능 RED로 가장하지 않는다.
|
||||
- 대체 검증: 실제 SQL 파일을 독립 H2 MySQL 모드에 적용하는 임시 JDBC assertion으로 기존 행 보존/KO 초기값, 새 행 기본값, JA/EN 보존, NULL 거부, 재실행 실패 후 값 불변을 확인한다. native MySQL 실행 증거와 구분한다.
|
||||
- [x] 단일 정적 SQL 및 실행 전제/재실행 제한을 관련 계약에 반영했다.
|
||||
- [x] 독립 DB 확인, 문서 대조와 `git diff --check`를 수행했다.
|
||||
|
||||
### Phase 8 Gate (`P8-GATE`)
|
||||
|
||||
- 완료 증거: S1 기존 행/컬럼, S2 신규 기본값·명시 언어·NULL 거부, S3 재실행 실패·값 보존이 통과하고 scoped 리뷰가 승인한다.
|
||||
- [x] 실제 SQL 검증·독립 리뷰 APPROVE를 기록하고 소유 임시 자원을 정리했다. 애플리케이션 변경이 없어 Gradle 전체 suite는 반복하지 않았다.
|
||||
|
||||
### Phase 8 검증 기록 — 2026-11-03
|
||||
|
||||
- MySQL 8.0 공식 [ALTER TABLE 문법](https://dev.mysql.com/doc/refman/8.0/en/alter-table.html)의 정적 `ADD COLUMN column_definition [AFTER col_name]`를 확인했다. 직접 fetch는 403으로 실패해 검색 결과의 공식 문법을 확인했다. MySQL에 MariaDB의 `ADD COLUMN IF NOT EXISTS` 문법을 가정하지 않았다.
|
||||
- 실제 변경한 SQL 파일을 캐시된 H2 2.1.214의 MySQL 모드에서 임시 Java/JDBC driver로 실행했다. 명령: `java --class-path /Users/klaus/.gradle/caches/modules-2/files-2.1/com.h2database/h2/2.1.214/d5c2005c9e3279201e12d4776c948578b16bf8b2/h2-2.1.214.jar /tmp/soda-banner-sql.CIhdCg/VerifyMigration.java docs/20261029_가로형서브배너/20261102_add_sub_banner_lang.sql`. exit 0, 모든 assertion PASS.
|
||||
- S1: 기존 활성·비활성 두 행의 ID/이미지/활성값 보존, 두 행의 새 lang=KO, VARCHAR(10)/NOT NULL 확인.
|
||||
- S2: 새 행의 언어 생략 KO, 명시적 JA/EN 저장 유지, 명시적 NULL 거부(SQLState 23502) 확인.
|
||||
- S3: 같은 SQL 재실행은 duplicate column(SQLState 42S21)으로 실패하고 JA/EN/KO 값이 바뀌지 않음을 확인했다. 이는 재실행 허용이 아니라 한 번만 실행해야 한다는 계약 검증이다.
|
||||
- Native MySQL·운영 DB에는 실행하지 않았으며, H2 결과를 MySQL 실행 증거로 표현하지 않는다. 앱 소스·CREATE SQL 변경이 없어 Gradle 테스트/빌드/린트는 반복하지 않았다. 임시 driver는 결과 기록 후 정리한다.
|
||||
- 독립 scoped 리뷰 `ses_e630f286affevZ6Rc77rxuL3Dn`: APPROVE, 문서화된 1회 실행 전제 아래 데이터 손실 회귀·차단 사항 없음. 기존 Phase 7의 동적 SQL 검토 기록은 당시 이력이며 현재 계약은 DEC-013/P8이다.
|
||||
- Teardown: Java 검증 프로세스 잔존 없음 확인, 소유 `/tmp/soda-banner-sql.CIhdCg`와 `/tmp/soda-sql-review.439u9H`의 내용·실경로를 확인한 뒤 삭제하고 부재를 확인했다. 임시 notepad도 삭제했다. 공유 H2/Gradle 캐시는 보존했다.
|
||||
|
||||
Reference in New Issue
Block a user