From d8877b243a91e0768f763ee95785f9d39a48beb5 Mon Sep 17 00:00:00 2001 From: johngreen Date: Sat, 16 May 2026 14:30:39 +0900 Subject: [PATCH] =?UTF-8?q?chore(=ED=85=8C=EC=9D=B4=EB=B8=94=ED=83=80?= =?UTF-8?q?=EC=9E=85):=20legacy=20input=5Ftype=201,207=20row=20=ED=91=9C?= =?UTF-8?q?=EC=A4=80=208=EC=A2=85=EC=9C=BC=EB=A1=9C=20=ED=86=B5=ED=95=A9?= =?UTF-8?q?=20(V026=20/=20RUN=5F091)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 5/15 common-code 재설계가 화이트리스트를 8종으로 좁히면서 빠뜨린 운영 DB 데이터 정리. 90787d83 의 화이트리스트 확장 fix 는 회복용 보호막이었고, 본 PR 은 데이터를 표준으로 통합하는 후속 정리. 매핑: category/select/radio/checkbox/boolean → code textarea → text datetime → date 영향: 메타 DB 1,207 row 갱신. 테넌트 DB 들은 비어있어 0 row. WHERE input_type IN (...) 으로 멱등 (재실행 시 0 row). 화이트리스트 축소는 운영 안정 확인 후 별도 PR. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../erp/migration/StartupSchemaMigrator.java | 27 ++++++- db/migrations/RUN_091_MIGRATION.md | 81 +++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 db/migrations/RUN_091_MIGRATION.md diff --git a/backend-spring/src/main/java/com/erp/migration/StartupSchemaMigrator.java b/backend-spring/src/main/java/com/erp/migration/StartupSchemaMigrator.java index 02b60156..1655eece 100644 --- a/backend-spring/src/main/java/com/erp/migration/StartupSchemaMigrator.java +++ b/backend-spring/src/main/java/com/erp/migration/StartupSchemaMigrator.java @@ -281,7 +281,32 @@ public class StartupSchemaMigrator { // 를 쓰는데 DB 엔 매칭 unique 제약이 없어서 모든 쓰기 API 가 500. // 인덱스 형태로 등록하면 ON CONFLICT 가 인식하고 ADD CONSTRAINT 식의 // IF NOT EXISTS 누락 문제도 회피. - "CREATE UNIQUE INDEX IF NOT EXISTS UX_TABLE_TYPE_COLUMNS_TCC ON TABLE_TYPE_COLUMNS (TABLE_NAME, COLUMN_NAME, COMPANY_CODE)" + "CREATE UNIQUE INDEX IF NOT EXISTS UX_TABLE_TYPE_COLUMNS_TCC ON TABLE_TYPE_COLUMNS (TABLE_NAME, COLUMN_NAME, COMPANY_CODE)", + + // V026 / RUN_091: TABLE_TYPE_COLUMNS.INPUT_TYPE legacy → 표준 8종 정리. + // 5/15 common-code 재설계가 화이트리스트를 8종으로 좁혔지만 운영 DB 의 + // 옛 값(category 886, select 149, textarea 102, checkbox 55, radio 12, + // datetime 2, boolean 1) 을 정리하는 마이그레이션을 빠뜨림. + // 매핑: + // category / select / radio / checkbox / boolean → code (commonCode 통합 의도) + // textarea → text (single/multi line 구분 손실 — UI 동작 가벼움) + // datetime → date + // 메타 DB 1,207 row 갱신. 테넌트 DB 들은 비어있어 영향 0. + // WHERE 절로 멱등 (재실행 시 0 row). + """ + UPDATE TABLE_TYPE_COLUMNS + SET INPUT_TYPE = CASE INPUT_TYPE + WHEN 'category' THEN 'code' + WHEN 'select' THEN 'code' + WHEN 'radio' THEN 'code' + WHEN 'checkbox' THEN 'code' + WHEN 'boolean' THEN 'code' + WHEN 'textarea' THEN 'text' + WHEN 'datetime' THEN 'date' + END, + UPDATED_DATE = NOW() + WHERE INPUT_TYPE IN ('category','select','radio','checkbox','boolean','textarea','datetime') + """ ); @EventListener(ApplicationReadyEvent.class) diff --git a/db/migrations/RUN_091_MIGRATION.md b/db/migrations/RUN_091_MIGRATION.md new file mode 100644 index 00000000..2077c5db --- /dev/null +++ b/db/migrations/RUN_091_MIGRATION.md @@ -0,0 +1,81 @@ +# 091 마이그레이션 — TABLE_TYPE_COLUMNS.INPUT_TYPE legacy → 표준 8종 정리 + +작성일: 2026-05-16 +작성자: johngreen +관련: 5/15 common-code 재설계 (commit `2348800e`) 후속 데이터 마이그레이션. + +## 배경 + +5/15 PR 이 `InputTypeConstants.USER_SELECTABLE_INPUT_TYPES` 화이트리스트를 +표준 8종(`text/number/date/code/entity/numbering/file/image`) 으로 좁혔지만, +운영 DB 에 잔존하는 옛 input_type 값들을 정리하는 데이터 마이그레이션이 빠지고 +프론트엔드도 옛 값을 그대로 echo 했기 때문에 컬럼 설정 저장 batch 가 400 으로 거부됐다. + +긴급 회복은 `90787d83` 에서 화이트리스트에 legacy 7종을 다시 인정하는 방식으로 +끝냈고, 본 091 마이그레이션은 그 뒤로 **데이터를 표준으로 통합**하는 후속 정리. + +## 매핑 + +| Legacy | → | Standard | 사유 | +|---|---|---|---| +| `category` | → | `code` | commonCode 통합 의도와 일치 | +| `select` | → | `code` | 미리 정의된 코드 선택 = code 와 동등 | +| `radio` | → | `code` | enum 선택 | +| `checkbox` | → | `code` | enum/boolean → code 매핑 (표준에 boolean 없음) | +| `boolean` | → | `code` | 표준에 boolean 없음 — code 가 가장 근접 | +| `textarea` | → | `text` | single/multi line 구분 UI 손실 (가벼움) | +| `datetime` | → | `date` | 표준에 datetime 분리 없음 | + +## 영향 범위 (실측 2026-05-16) + +| DB | 갱신 row | +|---|---| +| meta `invyone` | 1,207 (category 886 + select 149 + textarea 102 + checkbox 55 + radio 12 + datetime 2 + boolean 1) | +| `siflex_invyone` | 0 (테이블 비어있음) | +| `test01_invyone` | 0 | +| `test02_invyone` | 0 | + +## SQL + +```sql +UPDATE TABLE_TYPE_COLUMNS + SET INPUT_TYPE = CASE INPUT_TYPE + WHEN 'category' THEN 'code' + WHEN 'select' THEN 'code' + WHEN 'radio' THEN 'code' + WHEN 'checkbox' THEN 'code' + WHEN 'boolean' THEN 'code' + WHEN 'textarea' THEN 'text' + WHEN 'datetime' THEN 'date' + END, + UPDATED_DATE = NOW() + WHERE INPUT_TYPE IN ('category','select','radio','checkbox','boolean','textarea','datetime'); +``` + +## 멱등성 + +`WHERE INPUT_TYPE IN (...)` 으로 두 번째 실행 시 매칭 row 0 → no-op. + +## 적용 방법 + +부팅 시 자동 적용. `StartupSchemaMigrator.MIGRATIONS` 리스트에 V026 / RUN_091 항목으로 +등록되어 있어서 backend 시작 시 메타 DB + 활성 테넌트 DB 전부에 idempotent 로 실행된다. + +## 검증 + +```sql +-- 화이트리스트 밖 row 0 이어야 함 +SELECT input_type, COUNT(*) FROM table_type_columns + WHERE input_type NOT IN ('text','number','date','code','entity','numbering','file','image') + GROUP BY 1; +-- → 0 rows +``` + +## 후속 cleanup (별도 PR 거리) + +본 마이그레이션이 모든 환경에 한 번 적용된 다음에는: +1. `InputTypeConstants.USER_SELECTABLE_INPUT_TYPES` 에서 legacy 7종 다시 제거. +2. 프론트엔드 input type 선택 UI 에서 legacy 옵션 제거 (이미 있을 수도). +3. mapper/Service 에서 legacy 값 참조 흔적 grep + 정리. + +이번 PR 은 데이터 정리만. 화이트리스트 축소는 운영 안정 확인 후.