From a0a4dc3bf5389f097d06ccca8ae4c7885e2932ab Mon Sep 17 00:00:00 2001 From: johngreen Date: Fri, 15 May 2026 19:26:38 +0900 Subject: [PATCH] =?UTF-8?q?fix(=ED=85=8C=EC=9D=B4=EB=B8=94=ED=83=80?= =?UTF-8?q?=EC=9E=85):=20TABLE=5FTYPE=5FCOLUMNS.CODE=5FCATEGORY=20?= =?UTF-8?q?=E2=86=92=20CODE=5FINFO=20DB=20rename=20=EB=88=84=EB=9D=BD=20?= =?UTF-8?q?=EB=B3=B4=EC=99=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 5/15 common-code 재설계(commit 2348800e) 가 mapper SQL 6 군데 컬럼 참조를 CODE_INFO 로 바꾸면서 DB 컬럼 rename 마이그레이션을 빠뜨려, 모든 테넌트 사이트에서 테이블타입관리 > 테이블 클릭 시 GET /api/table-management/tables/{name}/columns 가 500 (column "code_info" does not exist) 을 반환. - StartupSchemaMigrator MIGRATIONS 에 V024 항목 추가 DO 블록으로 information_schema 확인 후 rename — 멱등. - RUN_089_MIGRATION.md 신설 (V023 IS_SOLUTION_ONLY 운영 가이드도 합본). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../erp/migration/StartupSchemaMigrator.java | 27 ++++ db/migrations/RUN_089_MIGRATION.md | 143 ++++++++++++++++++ 2 files changed, 170 insertions(+) create mode 100644 db/migrations/RUN_089_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 87c743fe..e0a0c5bb 100644 --- a/backend-spring/src/main/java/com/erp/migration/StartupSchemaMigrator.java +++ b/backend-spring/src/main/java/com/erp/migration/StartupSchemaMigrator.java @@ -223,6 +223,33 @@ public class StartupSchemaMigrator { '/admin/userMng/companyList', '/admin/audit-log' ) + """, + + // V024 / RUN_089: TABLE_TYPE_COLUMNS.CODE_CATEGORY → CODE_INFO rename. + // 5/15 common-code 재설계(commit 2348800e) 가 mapper SQL 의 컬럼 참조명만 + // 바꾸고 DB rename 을 빠뜨려, 테이블타입관리 컬럼 조회 API 가 500 반환. + // PostgreSQL 은 RENAME COLUMN 에 IF EXISTS 가 없어서 DO 블록으로 멱등 처리: + // - CODE_CATEGORY 만 있는 기존 테넌트: rename 수행 + // - 이미 CODE_INFO 인 신규 테넌트: no-op + // - 둘 다 있거나 둘 다 없는 비정상 상태: no-op (방어적) + """ + DO $$ + BEGIN + IF EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = 'public' + AND table_name = 'table_type_columns' + AND column_name = 'code_category' + ) AND NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = 'public' + AND table_name = 'table_type_columns' + AND column_name = 'code_info' + ) THEN + ALTER TABLE TABLE_TYPE_COLUMNS + RENAME COLUMN CODE_CATEGORY TO CODE_INFO; + END IF; + END $$ """ ); diff --git a/db/migrations/RUN_089_MIGRATION.md b/db/migrations/RUN_089_MIGRATION.md new file mode 100644 index 00000000..b1c5c56e --- /dev/null +++ b/db/migrations/RUN_089_MIGRATION.md @@ -0,0 +1,143 @@ +# 089 마이그레이션 — IS_SOLUTION_ONLY 메뉴 플래그 + TABLE_TYPE_COLUMNS.CODE_CATEGORY rename + +작성일: 2026-05-15 +작성자: johngreen +관련: +- (V023) 멀티테넌시 메뉴 격리 — 5/15 fix (commit c530a67c) +- (V024) common-code 마스터-디테일 재설계 — 5/15 refactor (commit 2348800e) + +## 목적 + +V023 과 V024 두 건의 누락된 운영 문서를 합본 처리. +앱 부팅 시 `StartupSchemaMigrator` 가 idempotent 로 메타 DB + 활성 테넌트 DB 전부에 자동 적용한다. + +### V023 — MENU_INFO.IS_SOLUTION_ONLY 컬럼 (회상) + +테넌트 사이트(`*.invyone.com`)에서 솔루션 전용 관리자 메뉴(회사관리/회사 프로비저닝/감사로그)를 숨기기 위한 플래그. +- 메뉴 mapper SQL(`selectAdminMenuList`, `selectUserMenuList`)이 `is_management_host` 파라미터를 보고 `IS_SOLUTION_ONLY=TRUE` 행을 제외. +- 이미 부팅 마이그레이션으로는 적용 중이지만 RUN_*.md 운영 문서가 빠져있어 이번 089 에 합본. + +### V024 — TABLE_TYPE_COLUMNS.CODE_CATEGORY → CODE_INFO (★ 신규, 본 PR 의 핵심) + +5/15 의 commonCode 마스터-디테일 재설계(commit `2348800e`)가 mapper SQL 6 군데에서 +`CL.CODE_CATEGORY` → `CL.CODE_INFO` 로 컬럼 참조명을 바꿨지만, **DB 컬럼 rename SQL 을 빠뜨린 채 머지**됨. +그 결과 모든 테넌트 DB 의 `테이블 타입관리 > 테이블 클릭 > 컬럼 목록` API +(`GET /api/table-management/tables/{name}/columns`) 가 **500** 반환: + +``` +ERROR: column cl.code_info does not exist +``` + +본 089 마이그레이션이 `CODE_CATEGORY` → `CODE_INFO` 로 컬럼명을 안전하게 변경한다. + +## 스키마 + +### MENU_INFO (V023) + +| 컬럼 | 타입 | 제약 | 설명 | +|---|---|---|---| +| `IS_SOLUTION_ONLY` | BOOLEAN | NOT NULL DEFAULT FALSE | TRUE 인 메뉴는 솔루션 관리 호스트에서만 노출 | + +### TABLE_TYPE_COLUMNS (V024) + +| 변경 | 설명 | +|---|---| +| `CODE_CATEGORY` → `CODE_INFO` | 컬럼 RENAME (값/타입/제약 그대로) | + +## SQL + +```sql +-- ================================================================= +-- 089-V023: MENU_INFO.IS_SOLUTION_ONLY (idempotent) +-- ================================================================= + +ALTER TABLE MENU_INFO + ADD COLUMN IF NOT EXISTS IS_SOLUTION_ONLY BOOLEAN DEFAULT FALSE NOT NULL; + +UPDATE MENU_INFO + SET IS_SOLUTION_ONLY = TRUE + WHERE IS_SOLUTION_ONLY = FALSE + AND MENU_URL IN ( + '/admin/sysMng/subdomainList', + '/admin/userMng/companyList', + '/admin/audit-log' + ); + +-- ================================================================= +-- 089-V024: TABLE_TYPE_COLUMNS.CODE_CATEGORY → CODE_INFO (idempotent) +-- ================================================================= +-- PostgreSQL 은 RENAME COLUMN 에 IF EXISTS 가 없으므로 DO 블록으로 +-- 멱등성 보장 (이미 CODE_INFO 면 no-op, CODE_CATEGORY 만 존재할 때만 rename). + +DO $$ +BEGIN + IF EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = 'public' + AND table_name = 'table_type_columns' + AND column_name = 'code_category' + ) AND NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = 'public' + AND table_name = 'table_type_columns' + AND column_name = 'code_info' + ) THEN + ALTER TABLE TABLE_TYPE_COLUMNS + RENAME COLUMN CODE_CATEGORY TO CODE_INFO; + END IF; +END $$; +``` + +## 멱등성 + +- V023: `ADD COLUMN IF NOT EXISTS` + UPDATE `WHERE IS_SOLUTION_ONLY = FALSE` 로 중복 실행 안전. +- V024: DO 블록 안에서 information_schema 로 현재 상태 확인 후 분기. + - 신규 테넌트 DB (이미 CODE_INFO 면): no-op + - 기존 테넌트 DB (CODE_CATEGORY 만 있으면): rename 수행 + - 둘 다 있거나 둘 다 없으면: no-op (방어적) + +## 적용 방법 + +부팅 시 자동 적용 — 별도 작업 불필요. +`backend-spring/src/main/java/com/erp/migration/StartupSchemaMigrator.java` 의 MIGRATIONS 리스트에 +위 SQL 이 등록되어 있어서 앱이 시작할 때 모든 활성 테넌트 DB 에 idempotent 로 실행된다. + +수동 적용이 필요한 경우 (예: 새 환경 부트스트랩 전): +```bash +psql -h -U -d -f - <<'SQL' +-- 위 SQL 본문 붙여넣기 +SQL +``` + +## 검증 + +```sql +-- V023 +SELECT COLUMN_NAME FROM information_schema.columns + WHERE TABLE_NAME = 'menu_info' AND COLUMN_NAME = 'is_solution_only'; +-- → 1 row + +SELECT MENU_URL, IS_SOLUTION_ONLY FROM MENU_INFO + WHERE MENU_URL IN ('/admin/sysMng/subdomainList', '/admin/userMng/companyList', '/admin/audit-log'); +-- → 모두 IS_SOLUTION_ONLY = TRUE + +-- V024 +SELECT COLUMN_NAME FROM information_schema.columns + WHERE TABLE_NAME = 'table_type_columns' AND COLUMN_NAME IN ('code_category', 'code_info'); +-- → 1 row: code_info (code_category 는 존재하면 안 됨) +``` + +## 영향 범위 + +- 테이블 타입관리 페이지 컬럼 조회 500 에러 해소. +- common-code 재설계 후속 (mapper/Service/Frontend 는 이미 5/15 에 머지됨). +- 부팅 시점 1회 실행 — 런타임 트래픽에는 영향 없음. + +## 롤백 + +V024 rename 을 되돌리려면 mapper SQL 도 같이 되돌려야 하므로 일반적으로 권장하지 않음. +만약 필요하면: +```sql +ALTER TABLE TABLE_TYPE_COLUMNS RENAME COLUMN CODE_INFO TO CODE_CATEGORY; +``` ++ `mapper/tableManagement.xml`, `commonCode.xml`, FE `commonCode.ts` 등 5/15 변경분 revert.