Test #470
@@ -10,7 +10,7 @@
|
||||
|
||||
## 현재 상태
|
||||
|
||||
- Phase 1 완료 기록 유지. Phase 2 generate-url 구현·새 HTTP3개·독립 리뷰·임시 자원 정리 완료. 활성 로컬 Goal 없음. 운영 배포/외부 게이트는 여전히 BLOCKED.
|
||||
- Phase 1/2 완료 이력 유지. Phase3 컬럼 매핑 수정·신규 테스트·독립 리뷰·소유 임시 자원 정리 완료. 활성 로컬 Goal 없음. 운영 DB/외부 게이트는 별도 검증 대상이다.
|
||||
- 실행: subagent-driven-development, 공유 Kotlin 구현은 단일 담당자가 순차 처리한다. 엔티티 계약이 확보된 additive DDL·운영 문서는 별도 담당자가 병렬 준비하고 마지막에 대조한다.
|
||||
- 새 worktree는 만들지 않는다. 기존 `test` 작업 트리는 조사 시 clean이며 main/master가 아니다.
|
||||
- commit/push/배포/DB 적용은 이 계획의 실행 항목이 아니다.
|
||||
@@ -141,7 +141,24 @@
|
||||
- [x] 기존 코드 변경은 DTO와 generateUrl 본문뿐임을 실제 전후 diff로 대조했다.
|
||||
- [x] 결과 보고를 보존하고 소유 테스트 PID/listener 및 임시 build/cache/root 부재를 확인했다.
|
||||
|
||||
## Phase 1 실행 검증 이력
|
||||
## Phase 3: Schema-validation 회귀 수정
|
||||
|
||||
### Task 3.R1: s3 컬럼 물리명 일치
|
||||
|
||||
**Goal `P3-R1`:** 기존 `subtitle.s3_bucket`/`s3_key` 테이블을 Hibernate가 검증하고 정상 저장·조회한다.
|
||||
|
||||
- 시작 조건: 실제 사용자 에러, 명시적 이름이 없는 엔티티와 DDL 차이 확인.
|
||||
- Files: `src/main/kotlin/kr/co/vividnext/sodalive/v2/subtitle/adapter/persistence/Subtitle.kt`.
|
||||
- Test: `src/test/kotlin/kr/co/vividnext/sodalive/v2/subtitle/SubtitleSchemaValidationTest.kt` 신규.
|
||||
- 범위 밖: DDL 수정·운영 DB 접속/컬럼 추가·자동 update·전역 naming strategy·JSON/property rename·기존 테스트 실행.
|
||||
- 시나리오: 독립적으로 만든 s3_bucket/s3_key 테이블에 실제 Boot 기본 naming strategy를 사용한 Hibernate validate 성공, 두 값의 persist/reload/JDBC column 확인 성공.
|
||||
- [x] **RED:** 엔티티 자동 DDL 생성 없이 기존 컬럼명의 H2 table을 준비하고 실제 schema validate를 수행하는 새 테스트를 작성했다.
|
||||
- [x] **RED 확인:** 사용자 보고와 동일한 missing s3bucket 에러로 1개 실패를 확인했다. 컴파일 오류가 아니다.
|
||||
- [x] **GREEN:** `@Column(name = "s3_bucket")`, `@Column(name = "s3_key")`를 기존 속성에 명시했다.
|
||||
- [x] **GREEN 확인:** 새 테스트1개만 실행해 validation 및 Hibernate 저장/새 Session 조회/JDBC 두 컬럼 조회 성공을 확인했다.
|
||||
- [x] **REFACTOR:** 변경 compile/bootJar/lint와 독립 리뷰 APPROVE, 검증 기록 보존 및 소유 임시 자원 제거·부재 확인을 완료했다.
|
||||
|
||||
## 이전 기능 실행 검증 이력
|
||||
|
||||
```bash
|
||||
./gradlew test --tests 'kr.co.vividnext.sodalive.v2.subtitle.*'
|
||||
@@ -152,6 +169,14 @@
|
||||
|
||||
## Progress
|
||||
|
||||
- 2026-11-11 `P3-R1` 종료: 작업 root를 참조하는 프로세스가 없고 실제 디렉터리/symlink 아님을 확인한 뒤 소유 `subtitle-schema-fix.XcftjN`만 제거했다. `test ! -e` exit0, 공유캐시 미변경. 결과/명령/리뷰는 문서로 보존했다. 운영 재시작/DB 변경/커밋은 하지 않았다.
|
||||
|
||||
- 2026-11-11 `P3-R1` 독립 리뷰 APPROVE: 명세/품질 blocker 없음. 두@Column만 바뀌었고 기존 SQL/JSON 계약은 유지된다. 독립DDL+actualvalidate+새Session/JDBC 조회와 RED/GREEN 증거가 확인됐다. 실제MySQL/전체Spring검증은 별도 게이트다.
|
||||
|
||||
- 2026-11-11 `P3-R1` RED/GREEN: 실제 Hibernate validation의 missing[s3bucket] 실패를 수정 전 재현했다(1fail, 3m49s). 두@Column만 수정한 뒤 신규 테스트1/0/0/0, Kotlin compile/bootJar/변경2파일 lint 성공(3m29s). 실제 운영 DB는 조회·변경하지 않았다. `schema-validation-report.md`에 원인과 기존 create-drop 검증 공백을 기록했다. 독립 한정 리뷰 진행 중.
|
||||
|
||||
- 2026-11-11 `P3-R1` 등록: 사용자 보고 missing `[s3bucket]` 재현/수정. 기존 기본 명명전략이 숫자-대문자 경계에서 underscore를 넣는다고 가정한 정적 대조와 엔티티 생성 H2 테스트의 검증 공백을 기록한다. 기존 DDL은 유지하고 실제 validate 회귀 검증으로 보완한다.
|
||||
|
||||
- 2026-11-11 별도 사용자 `/commit-with-validation` 요청으로 커밋 진행. 기능 연동 커밋의 pre-commit `ktlintCheck`가 기존 `AudioContentService.kt` EOF 빈 줄 1건으로 실패하여 해당 빈 줄만 제거했다. 재시도에서 staged Kotlin 대상 lint와 `git diff --staged --check`, 커밋 직전·직후 메시지 검증이 통과했다. 이번 커밋 작업에서는 기능/전체 테스트 및 bootJar를 재실행하지 않았으며 기존 실행 이력과 외부 배포 BLOCKED는 유지한다. 전체 테스트 사용자 명령은 `./gradlew test`다.
|
||||
|
||||
- 2026-11-11 `P2-GATE` 종료: 부모 직접 HTTP3개 재실행 성공과 독립 승인 후 소유 root `generate-url-subtitle.fSBkJM`의 디렉터리/symlink 여부를 확인해 제거했다. `test ! -e` exit0이며 공유 캐시/다른 dirty 파일은 건드리지 않았다. 원래 EOF lint1건은 별도 미해결 관찰로 남긴다. 검증 로그 경로는 과거 위치이며 결과/명령/실패 이력은 보고서에 보존했다.
|
||||
@@ -184,3 +209,9 @@
|
||||
- 2026-11-10: 고정 두 언어 metadata는 job의 nullable 컬럼으로 최소 저장하고 별도 번역/checkpoint 구조는 만들지 않는다. receipt eventId는 case-sensitive unique, callback/started는 동일 job lock을 사용한다. 다른 job 사이 eventId 경합은 rollback 후 receipt 재조회로 판정한다.
|
||||
- 2026-11-10: UUID 파일명 변경은 외부 MediaConvert의 ID 추출/output 명명 규칙 확인 전 **배포 BLOCKED**다. 현재 저장소에 외부 consumer의 운영 계약 증거가 없으며, 임의 prefix 완화로 숨기지 않는다. 자막 S3 bucket의 private CloudFront origin/서명 접근도 운영 확인 게이트다.
|
||||
- 2026-11-10: baseline 명령 `./gradlew test --tests 'kr.co.vividnext.sodalive.content.AudioContentServiceTest' --tests 'kr.co.vividnext.sodalive.member.MemberLoginResponseContractTest' --tests 'kr.co.vividnext.sodalive.jwt.TokenProviderTest'`는 `kaptGenerateStubsKotlin` 단계에서 200초 도구 제한으로 종료. 테스트 결과 없음. 기존 다른 Gradle 작업이 관찰되어 타 작업을 종료하지 않고 이 작업 전용 build/cache 경로로 검증을 격리한다.
|
||||
|
||||
## Schema-validation 커밋 전 재검증
|
||||
|
||||
- 2026-11-11 별도 `/commit-with-validation` 요청으로 `./gradlew --no-daemon test --tests 'kr.co.vividnext.sodalive.v2.subtitle.SubtitleSchemaValidationTest'`를 실행했다.
|
||||
- 결과: `BUILD SUCCESSFUL in 46s`, 테스트 1개, 실패/오류/건너뜀 0개. 기존 컬럼명의 Hibernate validation과 저장·재조회를 재확인했다.
|
||||
- 전체 테스트와 실제 MySQL 기동은 실행하지 않았다. 사용자 전체 테스트 명령은 `./gradlew test`다.
|
||||
|
||||
@@ -138,3 +138,13 @@ nullable `subtitle`을 추가한다. 기존 `ApiResponse` envelope와 `data.cont
|
||||
- `SubtitleJobService.subtitle`을 재사용해 요청 `LangContext`의 ko/ja, 최신 job, 완료/부분 완료 및 해당 언어 존재 여부를 처리한다.
|
||||
- 자막 미완료·누락·미지원 언어면 null이며 원문 fallback이나 새 자막 생성은 하지 않는다. 음원과 자막 서명 URL에는 같은 만료 기간을 전달한다.
|
||||
- 컨트롤러 URI/인증·DB 스키마·Lambda·재생성은 변경하지 않는다. 검증은 이번 후속 작업에서 새로 작성한 HTTP 테스트만 실행한다.
|
||||
|
||||
## 8. Schema-validation 회귀 수정
|
||||
|
||||
2026-11-11 실제 기동에서 `Schema-validation: missing column [s3bucket] in table [subtitle]`가 보고됐다.
|
||||
공개된 DDL의 `s3_bucket`/`s3_key`를 기준으로 엔티티의 물리 컬럼 이름을 명시한다.
|
||||
Kotlin 속성 및 JSON 이름 `s3Bucket`/`s3Key`는 바꾸지 않고 DB 컬럼 추가/rename이나 전역 naming strategy 변경도 하지 않는다.
|
||||
|
||||
기존 테스트의 `ddl-auto:create-drop`은 잘못 추론된 이름으로 테이블을 함께 생성해 이 불일치를 가렸다.
|
||||
신규 회귀 검증은 엔티티와 독립적으로 기존 DDL 컬럼 이름의 H2 테이블을 먼저 생성하고 실제 Hibernate
|
||||
`validate` 및 저장/재조회로 두 필드를 확인한다. 실제 운영 MySQL 재기동을 검증했다고 주장하지 않는다.
|
||||
|
||||
Reference in New Issue
Block a user