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