From 574319811ca257b30e0d78f24a40422dbb86c3d6 Mon Sep 17 00:00:00 2001 From: johngreen Date: Wed, 13 May 2026 14:43:41 +0900 Subject: [PATCH] =?UTF-8?q?refactor(=ED=85=8C=EC=9D=B4=EB=B8=94=ED=83=80?= =?UTF-8?q?=EC=9E=85):=20backend=20INSERT/UPDATE=208=EA=B0=9C=20validate?= =?UTF-8?q?=20=EB=B0=B1=EC=8A=A4=ED=86=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - TableManagementService.normalizeInputType(value, context) 오버로드 — user-insert/user-update-type 만 8개 검증, user-update-other/system-normalize 는 skip - TableManagementService.updateColumnSettings: payload 의 input_type 키 존재 여부로 context 분기 (input_type 자체 변경 vs 다른 속성 변경) - DdlService.addColumn / saveColumnMetadata: convertToInputType 결과를 USER_SELECTABLE_INPUT_TYPES (8개) 와 대조, 외이면 IllegalArgumentException mapper XML 5곳 (categoryTree / entityJoin / tableCategoryValue / screenManagement / tableManagement / entityReference) 무변경 — READ 경로 12개 그대로. spec: .omc/specs/deep-dive-table-type-storage-ui-separation.md (v3.2 §6.3) Co-Authored-By: Claude Opus 4.7 (1M context) --- .../main/java/com/erp/service/DdlService.java | 21 +++++++++++- .../erp/service/TableManagementService.java | 32 +++++++++++++++++-- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/backend-spring/src/main/java/com/erp/service/DdlService.java b/backend-spring/src/main/java/com/erp/service/DdlService.java index 182174d5..543983c2 100644 --- a/backend-spring/src/main/java/com/erp/service/DdlService.java +++ b/backend-spring/src/main/java/com/erp/service/DdlService.java @@ -39,6 +39,12 @@ public class DdlService extends BaseService { "id", "created_date", "updated_date", "company_code" ); + /** 사용자가 신규 추가하는 컬럼에 허용되는 INPUT_TYPE 8종 (백엔드 백스톱) */ + private static final Set USER_SELECTABLE_INPUT_TYPES = Set.of( + "text", "number", "date", "code", "entity", + "numbering", "file", "image" + ); + public DdlService(JdbcTemplate jdbcTemplate, PlatformTransactionManager transactionManager) { this.jdbcTemplate = jdbcTemplate; this.transactionTemplate = new TransactionTemplate(transactionManager); @@ -140,6 +146,12 @@ public class DdlService extends BaseService { transactionTemplate.execute(status -> { jdbcTemplate.execute(ddlQuery); String inputType = convertToInputType(column); + if (!USER_SELECTABLE_INPUT_TYPES.contains(inputType)) { + throw new IllegalArgumentException( + "INPUT_TYPE 은 다음 8개 중 하나여야 합니다: " + USER_SELECTABLE_INPUT_TYPES + + " (받은 값: " + inputType + ")" + ); + } String detailSettings = column.containsKey("detail_settings") ? column.get("detail_settings").toString() : "{}"; Integer maxOrder = jdbcTemplate.queryForObject( @@ -408,10 +420,17 @@ public class DdlService extends BaseService { // 사용자 정의 컬럼 for (int i = 0; i < columns.size(); i++) { Map col = columns.get(i); + String inputType = convertToInputType(col); + if (!USER_SELECTABLE_INPUT_TYPES.contains(inputType)) { + throw new IllegalArgumentException( + "INPUT_TYPE 은 다음 8개 중 하나여야 합니다: " + USER_SELECTABLE_INPUT_TYPES + + " (받은 값: " + inputType + ")" + ); + } String detailSettings = col.containsKey("detail_settings") ? col.get("detail_settings").toString() : "{}"; saveColumnMeta(tableName, (String) col.get("name"), companyCode, - convertToInputType(col), detailSettings, i); + inputType, detailSettings, i); } } diff --git a/backend-spring/src/main/java/com/erp/service/TableManagementService.java b/backend-spring/src/main/java/com/erp/service/TableManagementService.java index eb8d0d1e..832e3d4a 100644 --- a/backend-spring/src/main/java/com/erp/service/TableManagementService.java +++ b/backend-spring/src/main/java/com/erp/service/TableManagementService.java @@ -26,6 +26,12 @@ public class TableManagementService extends BaseService { private static final String NS = "tableManagement."; + /** 사용자가 직접 선택 가능한 INPUT_TYPE 8종 (INSERT/UPDATE-type 검증용) */ + private static final Set USER_SELECTABLE_INPUT_TYPES = Set.of( + "text", "number", "date", "code", "entity", + "numbering", "file", "image" + ); + // ────────────────────────────────────────────────── // 테이블 목록 // ────────────────────────────────────────────────── @@ -145,7 +151,9 @@ public class TableManagementService extends BaseService { Map settings, String companyCode) { ensureTableInLabels(tableName); - String inputType = normalizeInputType((String) settings.get("input_type")); + boolean inputTypeChanged = settings.containsKey("input_type"); + String ctx = inputTypeChanged ? "user-update-type" : "user-update-other"; + String inputType = normalizeInputType((String) settings.get("input_type"), ctx); Map params = new HashMap<>(); params.put("table_name", tableName); params.put("column_name", columnName); @@ -202,7 +210,7 @@ public class TableManagementService extends BaseService { public void updateColumnInputType(String tableName, String columnName, String inputType, String companyCode, Map detailSettings) { - String finalType = normalizeInputType(inputType); + String finalType = normalizeInputType(inputType, "user-update-type"); Map params = new HashMap<>(); params.put("table_name", tableName); params.put("column_name", columnName); @@ -853,7 +861,7 @@ public class TableManagementService extends BaseService { return name.replaceAll("[^a-zA-Z0-9_]", ""); } - /** "direct" / "auto" → "text" 변환 */ + /** "direct" / "auto" → "text" 변환 (legacy 호출처 보호 — system-normalize 동작) */ private String normalizeInputType(String inputType) { if ("direct".equals(inputType) || "auto".equals(inputType)) { log.warn("잘못된 inputType 값 감지: {} → 'text'로 변환", inputType); @@ -862,6 +870,24 @@ public class TableManagementService extends BaseService { return inputType != null ? inputType : "text"; } + /** + * context 에 따라 INPUT_TYPE 정규화 및 검증. + * @param context "user-insert" | "user-update-type" | "user-update-other" | "system-normalize" + */ + private String normalizeInputType(String value, String context) { + if ("user-insert".equals(context) || "user-update-type".equals(context)) { + if (value == null || !USER_SELECTABLE_INPUT_TYPES.contains(value)) { + throw new IllegalArgumentException( + "INPUT_TYPE 은 다음 8개 중 하나여야 합니다: " + USER_SELECTABLE_INPUT_TYPES + + " (받은 값: " + value + ")" + ); + } + return value; + } + // user-update-other / system-normalize: 기존 동작 그대로 + return normalizeInputType(value); + } + private String toJsonString(Object obj) { if (obj == null) return "{}"; if (obj instanceof String s) return s.isBlank() ? "{}" : s;