修复:收紧托盘业务权限与数据契约

This commit is contained in:
焦龙言
2026-07-27 17:40:24 +08:00
parent 9b1a807098
commit 4a321098f8
16 changed files with 823 additions and 59 deletions
@@ -1258,6 +1258,79 @@ class SqlContractTest(unittest.TestCase):
self.assertLess(dict_type_cleanup.start(), external_link_cleanup.start())
self.assertNotRegex(sql, r'\bdelete\s+from\s+(?:[a-z0-9_]+\.)?(?:biz|ai)_[a-z0-9_]+\b')
def test_patch_cleanup_fails_closed_before_deleting_legacy_seed_ids(self) -> None:
sql = _strip_sql_comments(PATCH_PATH.read_text(encoding='utf-8')).replace('`', '').lower()
guard_create = re.search(
r'create\s+temporary\s+table\s+pallet_workflow_legacy_seed_guard\b',
sql,
)
guard_insert = re.search(
r'insert\s+into\s+pallet_workflow_legacy_seed_guard\b[\s\S]+?;',
sql,
)
guard_drops = list(
re.finditer(
r'drop\s+temporary\s+table(?:\s+if\s+exists)?\s+pallet_workflow_legacy_seed_guard\b',
sql,
)
)
guard_drop = guard_drops[-1] if guard_drops else None
role_cleanup = re.search(r'delete\s+from\s+sys_role_menu\b', sql)
for statement in (guard_create, guard_insert, guard_drop, role_cleanup):
self.assertIsNotNone(statement)
self.assertLess(guard_create.start(), guard_insert.start())
self.assertLess(guard_insert.start(), guard_drop.start())
self.assertLess(guard_drop.start(), role_cleanup.start())
guard_sql = guard_insert.group()
expected_menu_identities = (
(4, 'ai 管理', 0, 'ai', None, '', 'm'),
(99, '施尔丰仓库', 0, 'https://git.yujiangrubber.cn/niuniu/shierfeng', None, '', 'm'),
(118, '模型管理', 4, 'model', 'ai/model/index', 'ai:model:list', 'c'),
(119, 'ai 对话', 4, 'chat', 'ai/chat/index', 'ai:chat:list', 'c'),
(1061, '模型查询', 118, '#', '', 'ai:model:query', 'f'),
(1062, '模型新增', 118, '#', '', 'ai:model:add', 'f'),
(1063, '模型修改', 118, '#', '', 'ai:model:edit', 'f'),
(1064, '模型删除', 118, '#', '', 'ai:model:remove', 'f'),
)
for menu_id, name, parent_id, path, component, permission, menu_type in expected_menu_identities:
with self.subTest(menu_id=menu_id):
component_pattern = (
r'component\s*<=>\s*null' if component is None else rf"component\s*<=>\s*'{re.escape(component)}'"
)
identity_pattern = (
rf'menu_id\s*=\s*{menu_id}\b[\s\S]+?'
rf"menu_name\s*<=>\s*'{re.escape(name)}'[\s\S]+?"
rf'parent_id\s*<=>\s*{parent_id}\b[\s\S]+?'
rf"path\s*<=>\s*'{re.escape(path)}'[\s\S]+?"
rf'{component_pattern}[\s\S]+?'
rf"perms\s*<=>\s*'{re.escape(permission)}'[\s\S]+?"
rf"menu_type\s*<=>\s*'{menu_type}'"
)
self.assertRegex(guard_sql, identity_pattern)
self.assertRegex(
guard_sql,
r'from\s+sys_dict_data[\s\S]+?dict_code\s+between\s+33\s+and\s+69'
r"[\s\S]+?dict_type\s*<=>\s*'ai_provider_type'",
)
self.assertRegex(
guard_sql,
r'from\s+sys_dict_type[\s\S]+?dict_id\s*=\s*12\b'
r"[\s\S]+?dict_type\s*<=>\s*'ai_provider_type'",
)
dict_data_cleanup = re.search(r'delete\s+from\s+sys_dict_data\s+where\s+[^;]+', sql)
dict_type_cleanup = re.search(r'delete\s+from\s+sys_dict_type\s+where\s+[^;]+', sql)
self.assertRegex(
dict_data_cleanup.group(),
r'dict_code\s+between\s+33\s+and\s+69\s+and\s+dict_type\s*=\s*\'ai_provider_type\'',
)
self.assertRegex(
dict_type_cleanup.group(),
r'dict_id\s*=\s*12\s+and\s+dict_type\s*=\s*\'ai_provider_type\'',
)
if __name__ == '__main__':
unittest.main()