1.0.424.verify.sql 4.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. -- ===========================================================================
  2. -- UAT 租户占位菜单收口 VERIFY —— 全部 SELECT 真值标量断言
  3. --
  4. -- 约定(AutoVersionUpdate.RunVerifyScriptIfExists,AutoVersionUpdate.cs:225-248):
  5. -- 逐条 SqlQuerySingle<object> 取「首行首列」,非真值即抛异常 → 迁移 Failed
  6. -- → StopApplicationOnFailure 默认 true → 应用启动中止。
  7. -- 因此本文件:
  8. -- ① 不得出现 SET / 非 SELECT 语句(返回 null = 判失败)
  9. -- ② 每条必须是布尔标量,不能是多列报表(首列标签恒真 = 断言失效)
  10. -- ③ 不得断言本机计数(16 / 25 / 22 之类),否则在没有 UATTEST_CHL 的
  11. -- 环境上必然误判。以下全部写成**环境无关的不变量**:该租户不存在时
  12. -- 抑制清单为空,各断言自然成立。
  13. --
  14. -- 人工对账报表与回滚见同目录 UAT-PLACEHOLDER-MENU-HIDE.ops.sql
  15. -- (无版本号前缀 → Version.TryParse 失败 → AutoVersionUpdate 永不自动执行)。
  16. -- ===========================================================================
  17. -- ---------- A. 核心不变量:抑制清单中的每一对,在 SysTenantMenu 中都不存在 ----------
  18. SELECT COUNT(*) = 0 FROM SysTenantMenu tm
  19. JOIN ado_tenant_menu_suppression s ON s.TenantId = tm.TenantId AND s.MenuId = tm.MenuId;
  20. -- ---------- B. 租户隔离:抑制清单只允许出现 UATTEST_CHL 一个租户 ----------
  21. SELECT COUNT(*) = 0 FROM ado_tenant_menu_suppression s
  22. WHERE s.TenantId <> IFNULL(
  23. (SELECT t.Id FROM SysTenant t JOIN SysOrg o ON o.Id = t.OrgId
  24. WHERE o.Code = 'UATTEST_CHL' AND t.Status = 1 LIMIT 1), -1);
  25. -- ---------- C. 全局 SysMenu 零改动:被抑制的菜单必须仍存在于 SysMenu ----------
  26. SELECT COUNT(*) = 0 FROM ado_tenant_menu_suppression s
  27. LEFT JOIN SysMenu m ON m.Id = s.MenuId
  28. WHERE m.Id IS NULL;
  29. -- ---------- D. 绝不误伤真实功能:抑制对象只能是占位页或纯目录 ----------
  30. SELECT COUNT(*) = 0 FROM ado_tenant_menu_suppression s
  31. JOIN SysMenu m ON m.Id = s.MenuId
  32. WHERE m.Component <> '/aidop/planning/index' AND m.Component <> 'Layout';
  33. -- ---------- E. 被抑制的目录必须确实「非按钮子项 100% 是占位」----------
  34. SELECT COUNT(*) = 0 FROM ado_tenant_menu_suppression s
  35. JOIN SysMenu m ON m.Id = s.MenuId
  36. WHERE m.Component = 'Layout'
  37. AND EXISTS (SELECT 1 FROM SysMenu c
  38. WHERE c.Pid = m.Id AND c.Type <> 3
  39. AND (c.Component IS NULL OR c.Component <> '/aidop/planning/index'));
  40. -- ---------- F. 效果断言:S0/S5/S6/S7 占位菜单对该租户不可见 ----------
  41. -- S9 / S4 / M11-M16 本轮不处理,不纳入断言。
  42. SELECT COUNT(*) = 0 FROM SysMenu m
  43. JOIN SysTenantMenu tm ON tm.MenuId = m.Id
  44. AND tm.TenantId = IFNULL(
  45. (SELECT t.Id FROM SysTenant t JOIN SysOrg o ON o.Id = t.OrgId
  46. WHERE o.Code = 'UATTEST_CHL' AND t.Status = 1 LIMIT 1), -1)
  47. WHERE m.Component = '/aidop/planning/index'
  48. AND (m.Path LIKE '/aidop/s0/%' OR m.Path LIKE '/aidop/s5/%'
  49. OR m.Path LIKE '/aidop/s6/%' OR m.Path LIKE '/aidop/s7/%');
  50. -- ---------- G. 不留空壳父目录:该租户可见的 /aidop 目录必须仍有可见子菜单 ----------
  51. SELECT COUNT(*) = 0 FROM SysMenu p
  52. JOIN SysTenantMenu tm ON tm.MenuId = p.Id
  53. AND tm.TenantId = IFNULL(
  54. (SELECT t.Id FROM SysTenant t JOIN SysOrg o ON o.Id = t.OrgId
  55. WHERE o.Code = 'UATTEST_CHL' AND t.Status = 1 LIMIT 1), -1)
  56. WHERE p.Status = 1 AND p.Type = 1 AND p.Path LIKE '/aidop/%'
  57. AND NOT EXISTS (
  58. SELECT 1 FROM SysMenu c
  59. JOIN SysTenantMenu ctm ON ctm.MenuId = c.Id AND ctm.TenantId = tm.TenantId
  60. WHERE c.Pid = p.Id AND c.Status = 1 AND c.Type <> 3);
  61. -- ---------- H. 跨租户回归:这些菜单在其他租户仍有授权(证明未跨租户误删)----------
  62. -- 抑制清单为空时自然成立。
  63. SELECT (SELECT COUNT(*) FROM ado_tenant_menu_suppression) = 0
  64. OR (SELECT COUNT(*) FROM SysTenantMenu tm
  65. WHERE tm.MenuId IN (SELECT MenuId FROM ado_tenant_menu_suppression)
  66. AND tm.TenantId NOT IN (SELECT TenantId FROM ado_tenant_menu_suppression)) > 0;