feat: 화면 그룹 삭제 시 메뉴 및 플로우 데이터 정리 로직 개선

- 화면 그룹 삭제 시 연결된 메뉴를 정리하는 로직을 추가하여, 삭제될 그룹에 연결된 메뉴를 자동으로 삭제하도록 하였습니다.
- 메뉴 삭제 시 관련된 화면 및 플로우 데이터도 함께 정리하여 데이터 일관성을 유지하였습니다.
- 복제 화면 모달에서 원본 회사와 동일한 회사 선택 시 자동으로 다른 회사로 변경하는 기능을 추가하였습니다.
- 삭제 확인 다이얼로그에 경고 메시지를 추가하여 사용자에게 삭제 작업의 영향을 명확히 안내하였습니다.
This commit is contained in:
DDD1542
2026-02-02 20:18:47 +09:00
parent 8c96b2d185
commit 257174d0c6
16 changed files with 472 additions and 442 deletions

View File

@@ -1461,11 +1461,8 @@ async function cleanupMenuRelatedData(menuObjid: number): Promise<void> {
[menuObjid]
);
// 4. numbering_rules에서 menu_objid를 NULL로 설정
await query(
`UPDATE numbering_rules SET menu_objid = NULL WHERE menu_objid = $1`,
[menuObjid]
);
// 4. numbering_rules: 새 스키마에서는 메뉴와 연결되지 않음 (스킵)
// 새 스키마: table_name + column_name + company_code 기반
// 5. rel_menu_auth에서 관련 권한 삭제
await query(

View File

@@ -344,13 +344,65 @@ export const deleteScreenGroup = async (req: AuthenticatedRequest, res: Response
childGroupIds: groupIdsToDelete
});
// 2. menu_info에서 삭제될 screen_group 참조를 NULL로 정리
// 2. 삭제될 그룹에 연결된 메뉴 정리
if (groupIdsToDelete.length > 0) {
await client.query(`
UPDATE menu_info
SET screen_group_id = NULL
// 2-1. 삭제할 메뉴 objid 수집
const menusToDelete = await client.query(`
SELECT objid FROM menu_info
WHERE screen_group_id = ANY($1::int[])
`, [groupIdsToDelete]);
AND company_code = $2
`, [groupIdsToDelete, targetCompanyCode]);
const menuObjids = menusToDelete.rows.map((r: any) => r.objid);
if (menuObjids.length > 0) {
// 2-2. screen_menu_assignments에서 해당 메뉴 관련 데이터 삭제
await client.query(`
DELETE FROM screen_menu_assignments
WHERE menu_objid = ANY($1::bigint[])
AND company_code = $2
`, [menuObjids, targetCompanyCode]);
// 2-3. menu_info에서 해당 메뉴 삭제
await client.query(`
DELETE FROM menu_info
WHERE screen_group_id = ANY($1::int[])
AND company_code = $2
`, [groupIdsToDelete, targetCompanyCode]);
logger.info("그룹 삭제 시 연결된 메뉴 삭제", {
groupIds: groupIdsToDelete,
deletedMenuCount: menuObjids.length,
companyCode: targetCompanyCode
});
}
// 2-4. 해당 회사의 채번 규칙 삭제 (최상위 그룹 삭제 시)
// 삭제되는 그룹이 최상위인지 확인
const isRootGroup = await client.query(
`SELECT 1 FROM screen_groups WHERE id = $1 AND parent_group_id IS NULL`,
[id]
);
if (isRootGroup.rows.length > 0) {
// 최상위 그룹 삭제 시 해당 회사의 채번 규칙도 삭제
// 먼저 파트 삭제
await client.query(
`DELETE FROM numbering_rule_parts
WHERE rule_id IN (SELECT rule_id FROM numbering_rules WHERE company_code = $1)`,
[targetCompanyCode]
);
// 규칙 삭제
const deletedRules = await client.query(
`DELETE FROM numbering_rules WHERE company_code = $1 RETURNING rule_id`,
[targetCompanyCode]
);
if (deletedRules.rowCount && deletedRules.rowCount > 0) {
logger.info("그룹 삭제 시 채번 규칙 삭제", {
companyCode: targetCompanyCode,
deletedCount: deletedRules.rowCount
});
}
}
}
// 3. screen_groups 삭제 (해당 그룹만 - 하위 그룹은 프론트엔드에서 순차 삭제)