diff --git a/backend-node/src/services/menuScreenSyncService.ts b/backend-node/src/services/menuScreenSyncService.ts index 9bda49d0..12873f47 100644 --- a/backend-node/src/services/menuScreenSyncService.ts +++ b/backend-node/src/services/menuScreenSyncService.ts @@ -124,7 +124,10 @@ export async function syncScreenGroupsToMenu( // 모든 메뉴의 objid 집합 (삭제 확인용) const existingMenuObjids = new Set(existingMenusResult.rows.map((m: any) => Number(m.objid))); - // 3. 사용자 메뉴의 루트 찾기 (parent_obj_id = 0인 사용자 메뉴) + // 3. objid 충돌 방지: 순차 카운터 사용 + let nextObjid = Date.now(); + + // 4. 사용자 메뉴의 루트 찾기 (parent_obj_id = 0인 사용자 메뉴) // 없으면 생성 let userMenuRootObjid: number | null = null; const rootMenuQuery = ` @@ -138,19 +141,18 @@ export async function syncScreenGroupsToMenu( if (rootMenuResult.rows.length > 0) { userMenuRootObjid = Number(rootMenuResult.rows[0].objid); } else { - // 루트 메뉴가 없으면 생성 - const newObjid = Date.now(); + const rootObjid = nextObjid++; const createRootQuery = ` INSERT INTO menu_info (objid, parent_obj_id, menu_name_kor, menu_name_eng, seq, menu_type, company_code, writer, regdate, status) VALUES ($1, 0, '사용자', 'User', 1, 1, $2, $3, NOW(), 'active') RETURNING objid `; - const createRootResult = await client.query(createRootQuery, [newObjid, companyCode, userId]); + const createRootResult = await client.query(createRootQuery, [rootObjid, companyCode, userId]); userMenuRootObjid = Number(createRootResult.rows[0].objid); logger.info("사용자 메뉴 루트 생성", { companyCode, objid: userMenuRootObjid }); } - // 4. screen_groups ID → menu_objid 매핑 (순차 처리를 위해) + // 5. screen_groups ID → menu_objid 매핑 (순차 처리를 위해) const groupToMenuMap: Map = new Map(); // screen_groups의 부모 이름 조회를 위한 매핑 @@ -280,7 +282,7 @@ export async function syncScreenGroupsToMenu( } else { // 새 메뉴 생성 - const newObjid = Date.now() + groupId; // 고유 ID 보장 + const newObjid = nextObjid++; // 부모 메뉴 objid 결정 // 우선순위: groupToMenuMap > parent_menu_objid (존재 확인 필수)