# 通知目标与真实派发链路审计 日期:2026-07-23 范围:事件中心 → 自动化执行动作 → 通知记录 → 外部渠道派发 ## 健康度 已从“规则只保存渠道名、外部通知重新入队后无人消费”提升为端到端可审计链路。自动化只能选择服务端声明就绪的渠道和接收组;站内信写入即送达,外部通知由独立派发器租约领取,只有可信网关返回非空服务商消息 ID 才标记发送成功。生产短信、邮件和企业通讯仍需配置真实网关并完成签名 canary,本轮没有伪造第三方送达结论。 ## 发现与修复 1. 原动作页只有“仅记录 / 站内通知 / 高优先级通知”,没有接收人或接收组,却显示“真实可用”;现在改为渠道与接收组矩阵,未配置网关的渠道不可选择。 2. 规则新增 `notificationTargets[]`,保存 `{channel, recipientId, label}` 引用;旧 `notificationChannels` 继续作为兼容字段并由目标归一化生成。外部渠道没有目标时服务端拒绝发布。 3. 目标目录由 `ALERT_NOTIFICATION_TARGETS_JSON` 提供,前端只读取不含手机号、邮箱、网关 URL 和密钥的安全引用目录。 4. 新增独立 `alert-notification-dispatcher`:使用 `FOR UPDATE SKIP LOCKED`、有界批次和过期租约领取 `reserved` 记录,避免多实例重复发送。 5. 网关请求包含 HMAC-SHA256 签名、时间戳、通知 ID 和“通知 + 尝试序号”幂等键;租约令牌不会进入外部载荷。 6. 网关 2xx 但没有 `messageId` 或 `X-Provider-Message-ID` 时仍按失败保存,防止把“HTTP 接收”误报成真实送达。 7. 通知记录新增队列健康条,5 秒展示待发送、失败、需人工处置、活动租约以及各渠道就绪状态;死信沿用三次受控尝试上限,不额外制造另一套状态机。 8. 自动化动作配置在桌面端改为四列紧凑渠道卡,移动端隐藏重复技术说明并保留清晰目标选择;自动恢复在 390 × 844 首屏内可见,固定主操作不随内容滚动。 9. 迁移 `035_alert_notification_dispatch.sql`、systemd 服务、发布安装器、构建命令、环境变量和接口契约已同步,发布器会继承或原子替换派发器二进制。 ## 证据 - 改造前只有通知模式且没有目标:`01-before-action-without-targets.png` - 桌面端渠道与接收组:`02-after-target-routing-desktop.png` - 桌面端选择短信与夜班负责人:`03-after-external-target-selected.png` - 390 × 844 移动端目标配置:`04-after-target-routing-mobile.png` - 移动端队列健康:`05-notification-health-mobile.png` - 桌面端队列健康与送达列表:`06-notification-health-desktop.png` ## 验证 - `go test ./...`:通过,包含派发批次、租约结果、HMAC、幂等键和模糊 2xx 拒绝测试 - Web 正式套件:78 个测试文件、518 项测试通过 - 事件中心专项:45 项测试通过 - Web 正式构建、完整根构建与发布安装器测试:通过 - 真实浏览器:1440 × 900 与 390 × 844;只修改未发布草稿并主动放弃,没有写入规则或发送通知 ## 无障碍与限制 - 渠道使用具名复选框,目标选择器按渠道提供可访问名称;必选目标缺失时在固定页脚给出阻断原因。队列健康是独立 region,刷新按钮与指标具有可访问文本。 - 桌面与移动端均保持单一编辑内容滚动和固定主要操作,没有新增横向滚动;颜色之外同时使用文字与数值表达渠道/失败状态。 - 本轮未执行屏幕阅读器人工走查,也没有第三方生产凭据、限流策略、异步回调或真实 SLO 数据。生产启用前必须逐渠道验证签名、防重、超时、服务商消息 ID 和失败告警。