Files
railwaysystem/RuoYi-Vue/sql/system/kingbase/015_dms_package_a_hardening.sql
T

120 lines
5.2 KiB
PL/PgSQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- ============================================================================
-- Migration: 015_dms_package_a_hardening.sql
-- Description: Package A.1 DMS 一致性加固与最小权限拆分
-- 1. 权限最小化拆分:新增 2194 (train:access:credential),从 train_admin 移除 2192 (train:access:manage)
-- 2. 床位唯一性约束:检测无重复记录时创建有效床位部分唯一索引
-- 3. 幂等与断言校验
-- ============================================================================
\set ON_ERROR_STOP on
BEGIN;
-- 1. 注册 2194 (train:access:credential) 门禁凭据下发与注销专用权限
INSERT INTO public.sys_menu
(menu_id, menu_name, parent_id, order_num, path, component, query, is_frame, is_cache,
menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
SELECT 2194, '门禁凭据操作', 2060, 4, '#', '', '', 1, 0,
'F', '0', '0', 'train:access:credential', '#', 'admin', CURRENT_TIMESTAMP, '', NULL, '门禁凭据下发与注销权限'
WHERE NOT EXISTS (SELECT 1 FROM public.sys_menu WHERE menu_id = 2194);
-- 2. 超级管理员角色 (role_id = 1) 授予 2194
INSERT INTO public.sys_role_menu (role_id, menu_id)
SELECT 1, 2194
WHERE NOT EXISTS (SELECT 1 FROM public.sys_role_menu WHERE role_id = 1 AND menu_id = 2194);
-- 3. 培训管理员角色 (role_id = 3) 调整权限 (MIN-09):
-- 授予 2194 (train:access:credential)
INSERT INTO public.sys_role_menu (role_id, menu_id)
SELECT 3, 2194
WHERE NOT EXISTS (SELECT 1 FROM public.sys_role_menu WHERE role_id = 3 AND menu_id = 2194);
-- 从 train_admin (role_id = 3) 回收 2192 (train:access:manage,硬件映射与维护权限)
DELETE FROM public.sys_role_menu
WHERE role_id = 3 AND menu_id = 2192;
-- 从 train_admin (role_id = 3) 回收 2263 (train:accommodation:remove,物理删除住宿历史权限)
DELETE FROM public.sys_role_menu
WHERE role_id = 3 AND menu_id = 2263;
-- 4. 有效床位唯一性约束 (Section 17)
-- 先只读检查是否存在已有的活跃床位重复数据
DO $$
DECLARE
v_dup_groups INTEGER;
BEGIN
SELECT COUNT(*) INTO v_dup_groups FROM (
SELECT dorm_id, bed_no
FROM train_accommodation
WHERE accommodation_status IN (0, 1)
AND bed_no IS NOT NULL
GROUP BY dorm_id, bed_no
HAVING COUNT(*) > 1
) t;
IF v_dup_groups = 0 THEN
IF NOT EXISTS (
SELECT 1 FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname = 'idx_train_acc_dorm_bed_active_uniq'
) THEN
CREATE UNIQUE INDEX idx_train_acc_dorm_bed_active_uniq
ON train_accommodation (dorm_id, bed_no)
WHERE accommodation_status IN (0, 1) AND bed_no IS NOT NULL;
RAISE NOTICE 'Created partial unique index idx_train_acc_dorm_bed_active_uniq successfully.';
END IF;
ELSE
RAISE NOTICE 'ACTIVE_BED_DUPLICATE_GROUP_COUNT = %, skipping unique index creation to prevent business data destruction.', v_dup_groups;
END IF;
END $$;
-- 5. 状态机约束兼容性检查 (train_external_operation)
-- 确保 operation_status 允许 DISPATCHING 与 AMBIGUOUS
DO $$
DECLARE
v_conname TEXT;
BEGIN
SELECT conname INTO v_conname
FROM pg_constraint
WHERE conrelid = 'train_external_operation'::regclass
AND contype = 'c'
AND pg_get_constraintdef(oid) LIKE '%operation_status%';
IF v_conname IS NOT NULL THEN
EXECUTE 'ALTER TABLE train_external_operation DROP CONSTRAINT ' || quote_ident(v_conname);
EXECUTE 'ALTER TABLE train_external_operation ADD CONSTRAINT chk_external_operation_status ' ||
'CHECK (operation_status IN (''CREATED'',''DISPATCHING'',''REQUESTED'',''ACCEPTED'',''PENDING'',''RETRY_WAIT'',''AMBIGUOUS'',''SUCCESS'',''FAILED'',''TIMEOUT''))';
END IF;
END $$;
-- 6. 后置断言验证
DO $$
BEGIN
-- 断言 1: 2194 已正确注册
IF (SELECT count(*) FROM public.sys_menu WHERE menu_id = 2194 AND perms = 'train:access:credential' AND status = '0') <> 1 THEN
RAISE EXCEPTION 'Assertion failed: menu 2194 train:access:credential not found or invalid';
END IF;
-- 断言 2: train_admin (role_id = 3) 拥有 2194 (train:access:credential)
IF (SELECT count(*) FROM public.sys_role_menu WHERE role_id = 3 AND menu_id = 2194) <> 1 THEN
RAISE EXCEPTION 'Assertion failed: role 3 not granted menu 2194';
END IF;
-- 断言 3: train_admin (role_id = 3) 不得拥有 2192 (train:access:manage)
IF (SELECT count(*) FROM public.sys_role_menu WHERE role_id = 3 AND menu_id = 2192) <> 0 THEN
RAISE EXCEPTION 'Assertion failed: role 3 still has menu 2192 (train:access:manage)';
END IF;
-- 断言 4: train_admin (role_id = 3) 不得拥有 2263 (train:accommodation:remove)
IF (SELECT count(*) FROM public.sys_role_menu WHERE role_id = 3 AND menu_id = 2263) <> 0 THEN
RAISE EXCEPTION 'Assertion failed: role 3 has forbidden menu 2263 (train:accommodation:remove)';
END IF;
-- 断言 5: train_admin 拥有 2264 (train:accommodation:add)
IF (SELECT count(*) FROM public.sys_role_menu WHERE role_id = 3 AND menu_id = 2264) <> 1 THEN
RAISE EXCEPTION 'Assertion failed: role 3 missing menu 2264 (train:accommodation:add)';
END IF;
END $$;
COMMIT;