diff --git a/backend-node/src/services/menuCopyService.ts b/backend-node/src/services/menuCopyService.ts index c0fda30c..2ba39c2f 100644 --- a/backend-node/src/services/menuCopyService.ts +++ b/backend-node/src/services/menuCopyService.ts @@ -2445,6 +2445,15 @@ export class MenuCopyService { const ruleParams = rulesToCopy.flatMap((r) => { const newMenuObjid = menuIdMap.get(r.menu_objid); + // scope_type = 'menu'인 경우 menu_objid가 반드시 필요함 (check 제약조건) + // menuIdMap에 없으면 원본 menu_objid가 복사된 메뉴 범위 밖이므로 + // scope_type을 'table'로 변경하거나, 매핑이 없으면 null 처리 + const finalMenuObjid = newMenuObjid !== undefined ? newMenuObjid : null; + const finalScopeType = + r.scope_type === "menu" && finalMenuObjid === null + ? "table" // 메뉴 매핑이 없으면 table 스코프로 변경 + : r.scope_type; + return [ r.newRuleId, r.rule_name, @@ -2456,8 +2465,8 @@ export class MenuCopyService { r.column_name, targetCompanyCode, userId, - newMenuObjid, - r.scope_type, + finalMenuObjid, + finalScopeType, null, ]; }); @@ -2478,8 +2487,11 @@ export class MenuCopyService { // 4-1. 기존 채번 규칙의 menu_objid 업데이트 (새 메뉴와 연결) - 배치 처리 if (rulesToUpdate.length > 0) { // CASE WHEN을 사용한 배치 업데이트 + // menu_objid는 numeric 타입이므로 ::numeric 캐스팅 필요 const caseWhen = rulesToUpdate - .map((_, i) => `WHEN rule_id = $${i * 2 + 1} THEN $${i * 2 + 2}`) + .map( + (_, i) => `WHEN rule_id = $${i * 2 + 1} THEN $${i * 2 + 2}::numeric` + ) .join(" "); const ruleIdsForUpdate = rulesToUpdate.map((r) => r.ruleId); const params = rulesToUpdate.flatMap((r) => [r.ruleId, r.newMenuObjid]);