Files
sam-docs/guides/menu-delete-verification-queries.md
hskwon 33ef01b2b4 docs: API 문서 및 테스트 시나리오 추가
- front/item-master-items-api.md - Items API 프론트엔드 연동 문서
- guides/menu-delete-verification-queries.md - 메뉴 삭제 검증 쿼리 가이드
- plans/flow-tests/item-delete-force-delete.json - 품목 삭제 테스트 시나리오
2025-12-12 08:51:54 +09:00

4.8 KiB

메뉴 삭제 검증 쿼리

메뉴 영구 삭제 전/후 연관 데이터 확인용 SQL 쿼리

삭제 전 확인 쿼리

1. 특정 메뉴의 연관 권한 조회

-- 메뉴 ID를 기준으로 연관 권한 조회
-- {MENU_ID}를 실제 메뉴 ID로 변경

SELECT
    p.id,
    p.name,
    p.guard_name,
    p.tenant_id
FROM permissions p
WHERE p.name LIKE 'menu:{MENU_ID}.%'
ORDER BY p.name;

2. 역할-권한 연결 조회

-- 해당 메뉴 권한이 어떤 역할에 할당되어 있는지 확인

SELECT
    r.id AS role_id,
    r.name AS role_name,
    r.tenant_id,
    p.name AS permission_name
FROM role_has_permissions rhp
JOIN roles r ON rhp.role_id = r.id
JOIN permissions p ON rhp.permission_id = p.id
WHERE p.name LIKE 'menu:{MENU_ID}.%'
ORDER BY r.name, p.name;

3. 사용자 직접 권한 조회

-- 해당 메뉴 권한이 어떤 사용자에게 직접 할당되어 있는지 확인

SELECT
    u.id AS user_id,
    u.name AS user_name,
    u.email,
    p.name AS permission_name
FROM model_has_permissions mhp
JOIN users u ON mhp.model_id = u.id AND mhp.model_type = 'App\\Models\\User'
JOIN permissions p ON mhp.permission_id = p.id
WHERE p.name LIKE 'menu:{MENU_ID}.%'
ORDER BY u.name, p.name;

4. 부서 권한 조회

-- 해당 메뉴 권한이 어떤 부서에 할당되어 있는지 확인

SELECT
    d.id AS dept_id,
    d.name AS dept_name,
    d.tenant_id,
    p.name AS permission_name
FROM model_has_permissions mhp
JOIN departments d ON mhp.model_id = d.id AND mhp.model_type = 'App\\Models\\Tenants\\Department'
JOIN permissions p ON mhp.permission_id = p.id
WHERE p.name LIKE 'menu:{MENU_ID}.%'
ORDER BY d.name, p.name;

5. 종합 영향도 조회 (삭제 전 확인용)

-- 삭제 시 영향받는 모든 데이터 요약

SELECT
    'permissions' AS table_name,
    COUNT(*) AS record_count
FROM permissions
WHERE name LIKE 'menu:{MENU_ID}.%'

UNION ALL

SELECT
    'role_has_permissions' AS table_name,
    COUNT(*) AS record_count
FROM role_has_permissions rhp
JOIN permissions p ON rhp.permission_id = p.id
WHERE p.name LIKE 'menu:{MENU_ID}.%'

UNION ALL

SELECT
    'model_has_permissions (users)' AS table_name,
    COUNT(*) AS record_count
FROM model_has_permissions mhp
JOIN permissions p ON mhp.permission_id = p.id
WHERE p.name LIKE 'menu:{MENU_ID}.%'
AND mhp.model_type = 'App\\Models\\User'

UNION ALL

SELECT
    'model_has_permissions (departments)' AS table_name,
    COUNT(*) AS record_count
FROM model_has_permissions mhp
JOIN permissions p ON mhp.permission_id = p.id
WHERE p.name LIKE 'menu:{MENU_ID}.%'
AND mhp.model_type = 'App\\Models\\Tenants\\Department';

삭제 후 확인 쿼리

1. 메뉴가 삭제되었는지 확인

-- 메뉴 테이블에서 해당 ID 확인 (soft delete 포함)
SELECT id, name, deleted_at FROM menus WHERE id = {MENU_ID};

-- 완전히 삭제된 경우 결과 없음

2. 연관 권한이 삭제되었는지 확인

-- 연관 권한이 모두 삭제되었는지 확인 (결과가 0이어야 함)
SELECT COUNT(*) AS remaining_permissions
FROM permissions
WHERE name LIKE 'menu:{MENU_ID}.%';

3. 역할-권한 연결이 삭제되었는지 확인

-- FK CASCADE로 자동 삭제되었는지 확인
SELECT COUNT(*) AS remaining_role_permissions
FROM role_has_permissions rhp
WHERE NOT EXISTS (
    SELECT 1 FROM permissions p WHERE p.id = rhp.permission_id
);

4. 아카이브에 저장되었는지 확인

-- archived_records에서 삭제 기록 조회
SELECT
    ar.id,
    ar.batch_id,
    ar.batch_description,
    ar.record_type,
    ar.original_id,
    ar.deleted_at,
    ar.notes,
    JSON_EXTRACT(ar.main_data, '$.name') AS menu_name
FROM archived_records ar
WHERE ar.record_type = 'menu'
AND ar.original_id = {MENU_ID}
ORDER BY ar.deleted_at DESC;

-- 연관 테이블 데이터도 확인
SELECT
    arr.table_name,
    arr.record_count,
    arr.data
FROM archived_record_relations arr
JOIN archived_records ar ON arr.archived_record_id = ar.id
WHERE ar.record_type = 'menu'
AND ar.original_id = {MENU_ID};

글로벌 메뉴용 쿼리

글로벌 메뉴의 경우 menu:{ID} 대신 global_menu:{ID} 패턴 사용:

-- 글로벌 메뉴 권한 조회
SELECT * FROM permissions WHERE name LIKE 'global_menu:{MENU_ID}.%';

-- 글로벌 메뉴 참조하는 테넌트 메뉴 확인
SELECT id, tenant_id, name, global_menu_id
FROM menus
WHERE global_menu_id = {MENU_ID};

-- 삭제 후 참조 해제 확인 (global_menu_id가 NULL이고 is_customized가 true)
SELECT id, tenant_id, name, global_menu_id, is_customized
FROM menus
WHERE is_customized = 1;

실행 예시

# MySQL 콘솔에서 실행
mysql -u root -p samdb

# 또는 Laravel Tinker에서 실행
php artisan tinker
>>> DB::select("SELECT * FROM permissions WHERE name LIKE 'menu:123.%'");

최종 업데이트: 2025-12-09