1.0.500.sql 4.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. -- =====================================================================================
  2. -- 1.0.500 S8-NOTIFY-RECIPIENT-1 · 通知收件人模型
  3. --
  4. -- 取代 ado_s8_notification_layer 成为「这个事件通知谁」的 CURRENT AUTHORITY。
  5. --
  6. -- 旧表为什么不够用(真库取证):
  7. -- · 它按 (scene_code, severity, level_code) 组织,**不按规则** —— 无法回答
  8. -- 「这条规则出事通知谁」,而 P1-C 已经把责任落到了规则级;
  9. -- · level_code 的 L1/L2/L3 三档在库里只有 L1_OPERATOR 被真正用过(16 行全是它,
  10. -- 另有 1 行 level_code 为空),且「主管 / 总监」在系统中没有对应实体
  11. -- (SysOrg.DirectorId 与 SysUser.ManagerUserId 填充率均为 0);
  12. -- · 收件人只支持 Role 一种,无法表达「通知当前处理人」「通知责任池」这类真实诉求。
  13. --
  14. -- 旧表**不删**,降级为 LEGACY fallback:仅当新表对该 (租户, 规则, 事件) 没有任何配置
  15. -- 时才使用。优先级单一、可解释 —— 不是两个平级 authority。这样现网既有通知不会被
  16. -- 这批改动打断,管理员可以按规则逐步迁移。
  17. --
  18. -- 表由 CodeFirst(InitTables) 创建;本脚本只补索引 + postcheck,不写任何收件人数据
  19. -- (收件人是 per-tenant / per-rule 的人工配置,写死既不适配新租户也会覆盖管理员的选择)。
  20. -- =====================================================================================
  21. CREATE TABLE IF NOT EXISTS `ado_s8_notification_recipient` (
  22. `id` BIGINT NOT NULL AUTO_INCREMENT,
  23. `tenant_id` BIGINT NOT NULL COMMENT '租户(唯一安全边界)',
  24. `rule_code` VARCHAR(128) NOT NULL COMMENT "规则编码;'*' = 租户级默认(无来源规则的异常)",
  25. `event_code` VARCHAR(64) NOT NULL COMMENT '事件码,须在 S8NotificationCatalog.Events 内',
  26. `recipient_type` VARCHAR(32) NOT NULL COMMENT 'HANDLER_POOL / ASSIGNEE / REVIEWER / SPECIFIC_USER',
  27. `recipient_user_ids` VARCHAR(2000) NULL COMMENT '仅 SPECIFIC_USER 使用,逗号分隔 SysUser.Id',
  28. `created_at` DATETIME NOT NULL,
  29. `created_by` VARCHAR(64) NULL,
  30. PRIMARY KEY (`id`)
  31. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='S8 通知收件人配置';
  32. -- 唯一索引:同一 (租户, 规则, 事件, 收件人类型) 只允许一行。
  33. -- 没有它,重复行会让"取消某个收件人类型"变成删一行、剩一行 ——
  34. -- 页面显示已取消,实际还在发。
  35. SET @has_uk := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
  36. WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME='ado_s8_notification_recipient'
  37. AND INDEX_NAME='uk_s8_notify_recipient');
  38. SET @sql := IF(@has_uk = 0, '
  39. DELETE a FROM `ado_s8_notification_recipient` a
  40. JOIN `ado_s8_notification_recipient` b
  41. ON a.`tenant_id` = b.`tenant_id` AND a.`rule_code` = b.`rule_code`
  42. AND a.`event_code` = b.`event_code` AND a.`recipient_type` = b.`recipient_type`
  43. AND a.`id` > b.`id`', 'DO 0');
  44. PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
  45. SET @sql := IF(@has_uk = 0,
  46. 'ALTER TABLE `ado_s8_notification_recipient` ADD UNIQUE INDEX `uk_s8_notify_recipient` (`tenant_id`,`rule_code`,`event_code`,`recipient_type`)',
  47. 'DO 0');
  48. PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
  49. -- 旧表打上 LEGACY 标记(只改注释,不动任何数据行)——
  50. -- 让直接看库的人也能立刻知道哪张才是当前 authority。
  51. ALTER TABLE `ado_s8_notification_layer`
  52. COMMENT='[LEGACY · 1.0.500 起降级] S8 通知分层配置;CURRENT AUTHORITY = ado_s8_notification_recipient,本表仅在新表无配置时作为 fallback';
  53. -- ── POSTCHECK ──
  54. SET @cols := (SELECT COUNT(*) FROM information_schema.STATISTICS
  55. WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME='ado_s8_notification_recipient'
  56. AND INDEX_NAME='uk_s8_notify_recipient'
  57. AND COLUMN_NAME IN ('tenant_id','rule_code','event_code','recipient_type'));
  58. DROP TABLE IF EXISTS `tmp_s8_500_guard`;
  59. CREATE TABLE `tmp_s8_500_guard` (
  60. probe BIGINT NOT NULL,
  61. CONSTRAINT s8_500_BLOCKED_unique_index_missing CHECK (probe = 0)
  62. ) COMMENT '1.0.500 断言门禁;通过后自动删除';
  63. INSERT INTO `tmp_s8_500_guard` (probe) VALUES ((4 - @cols));
  64. DROP TABLE IF EXISTS `tmp_s8_500_guard`;
  65. -- 旧表一行都不能少:本批只降级、不清理。
  66. SET @legacy := (SELECT COUNT(*) FROM `ado_s8_notification_layer`);
  67. DROP TABLE IF EXISTS `tmp_s8_500_guard`;
  68. CREATE TABLE `tmp_s8_500_guard` (
  69. probe BIGINT NOT NULL,
  70. CONSTRAINT s8_500_BLOCKED_legacy_layer_wiped CHECK (probe = 0)
  71. ) COMMENT '1.0.500 断言门禁;通过后自动删除';
  72. INSERT INTO `tmp_s8_500_guard` (probe) VALUES (IF(@legacy = 0, 1, 0));
  73. DROP TABLE IF EXISTS `tmp_s8_500_guard`;
  74. -- 幂等:第二次执行建表跳过、索引已存在跳过、注释重复设置无副作用、断言仍成立。