Files
lislgosms/docs/signature-retirement-alert-design.md
T

15 KiB
Raw Blame History

签名清退预警与运营商级报备改造设计(本地实现稿)

状态:2026-08-10已按最终确认口径由提交2ecb24cf8d09dd428dfab0c682b33581959618ea发布到预生产,第85条自动转换migration已完成。严格运营商级发送门禁保持默认关闭;兼容命中清零核验、门禁切换和预警运营启用仍必须分阶段执行。

0. 实施状态(2026-08-10

  • 原签名清退预警功能已经过本地PostgreSQL迁移、专项与全量测试、真实聚合SQL、TypeScript、生产构建及授权后的真实验证码登录浏览器验收;本次最终口径已删除历史人工确认功能,并将自动转换migration发布到预生产。
  • 旧报备任务通过后续一次性迁移自动转为运营商级任务:按通道能力集合分别建任务,旧状态为approved时对应运营商全部记为已通过且approvedAt取迁移执行时间;其他状态原样复制且不写通过时间。已有运营商级任务优先保留、不覆盖;旧任务退出兼容范围并保留历史记录。
  • 本地实现未发送真实短信,未修改生产通道、账号、密码、启停状态、企业余额或客户连接;也未提交、推送或部署。

1. 目标与范围

本项目解决运营商因签名长期无真实发送而清退的问题,并将通道能力和签名报备状态细化到真实运营商。最终形成以下闭环:

  1. 通道支持移动、联通、电信多选,三个全选等价于现行“三网”。
  2. 签名报备事实由“签名 × 通道”升级为“签名 × 通道 × 运营商”。
  3. 发送选路只使用支持目标运营商且该签名在该运营商报备通过的通道。
  4. 每日按“企业签名 × 运营商”和“签名 × 通道 × 运营商”检测清退风险。
  5. 提供站内消息、临时/永久抑制、企业微信/飞书 Webhook 和近30日检测数据。

本项目不改造引流信息报备。引流信息任务、任务详情、状态汇总和历史记录继续保持现有“签名 × 引流信息 × 通道”口径,不新增运营商维度。

2. 已确认业务口径

  • 多运营商通道继续共用一个通道单价,不增加分运营商价格。
  • 一个签名最多关联一个企业应用;未绑定应用的签名只使用通用规则。
  • “部分成功”按运营商分别判断:任一运营商存在报备通过,就只将该运营商纳入监控,不等待三网全部成功。
  • 清退活跃量使用“至少有一次上游接受的去重业务短信数”。企业维度按业务短信去重;通道维度按messageRecordId + channelId去重。同一通道因断连、超时或重试产生多次提交只计一个活跃量;切换到另一个通道后,两个通道各计一次。
  • 提交尝试数、上游接受业务短信数和最终送达成功数分别展示,不把SubmitResp status=0描述为最终送达成功。
  • 每天按北京时间完整自然日检测T-XT-1,当天数据不参与。当前连续报备通过时间未满X个完整日时不预警。
  • 规则修改从下一检测日生效;恢复正常后再次低于阈值形成新的预警周期。
  • 临时抑制天数可配置;永久抑制可以在“抑制管理”中取消。取消后从下一检测日恢复提醒,不补发历史通知。
  • 右上角预警数字为“今日未读且未抑制数”。抑制只影响提醒和Webhook,不停止检测快照生成。
  • 到达率颜色复用现有统一六档色阶。
  • “签名质量检测”页面删除企业应用发送排行、通道占比、当天发送量和当天成功率模块。

3. 数据模型与事实来源

3.1 通道运营商能力

通道能力从旧单值mobile/unicom/telecom/all升级为非空运营商集合。通道组、通道组成员、路由规则和短信号码识别结果继续保持单运营商;只有通道能力集合包含目标运营商时,才能加入对应通道组并参与选路。

3.2 签名报备任务

继续以ChannelSignatureReportTask作为当前报备事实,以ChannelSignatureReportRecord作为不可变状态轨迹,不另建与任务重复的报备事实表。签名任务的业务唯一维度升级为:

签名 × 通道 × 运营商

签名任务增加运营商、当前连续通过时间和历史兼容范围。任务每次从非通过状态进入approved时写入新的approvedAt;离开approved时清空。记录表继续保存每次状态变化、操作人、时间、来源和原因。

reportTypedrainageItemId只是现有共享表的技术字段,不属于本需求业务维度;引流信息任务不增加运营商。

3.3 企业运营商报备汇总

“企业签名 × 运营商”不是另一套可编辑事实,而是运营商级签名任务的只读汇总:

  • 至少一个当前运营商级任务为approved时,该签名的该运营商进入监控。
  • 监控起点取当前仍有效的通过任务中最早的approvedAt
  • 当前有效任务全部退出通过时,该运营商退出监控;后续重新通过形成新的连续周期。

4. 现有生产数据兼容

旧单运营商通道能力无损迁移为单元素集合,旧all迁移为移动、联通、电信三元素集合。按2026-08-10最终业务口径,不再提供“历史待确认”页签或人工拆分API;历史签名任务统一按通道能力集合自动形成运营商级事实:

  • 旧任务为approved:通道支持的全部运营商均创建为approvedapprovedAt使用迁移当天实际执行时间;三网通道即三网均通过。
  • 旧任务为其他状态:通道支持的全部运营商继承该状态,approvedAt为空。
  • 已存在运营商级任务:保持现有状态和通过时间,不被旧任务覆盖。
  • 全部适用运营商处理完成后,旧任务改为legacy_split并永久保留,状态轨迹不删除;迁移重复执行不得重复创建任务或覆盖现有事实。

企业签名页面以后新建运营商级“已通过”任务时,继续以保存时刻作为approvedAt,无需额外填写历史时间。自动转换完成后历史兼容读取不再命中,不保留运营端人工确认入口。

5. 预警规则与生命周期

5.1 规则优先级

  • 企业预警:企业应用特殊规则优先于通用规则。
  • 通道预警:通道特殊规则优先于通用规则。
  • 每个规则分别配置移动、联通、电信的X天和Y条,并可启停或继承通用规则。
  • 规则修改保存后记录版本,下一检测日读取新版本;预警快照保存命中的规则版本和阈值,历史结果不随规则变化漂移。

5.2 预警周期

同一检测维度在连续低于阈值期间属于同一个预警周期;每天保存检测快照,但不创建重复周期。恢复达标后关闭当前周期;以后再次低于阈值创建新周期。

每日快照必须使用唯一检测日和唯一维度保证幂等。多实例或任务重启不得重复生成预警、未读消息或Webhook。

5.3 抑制与已读

  • 临时抑制支持常用天数和自定义天数,到期后的下一检测日自动恢复。
  • 永久抑制在“抑制管理”集中展示,取消时必须二次确认、填写原因并写操作日志。
  • 取消抑制不补发历史站内消息或Webhook。
  • 旧预警只读;最新预警可以进入抑制操作。抑制管理始终可以取消当前抑制。
  • 未读状态与抑制状态独立;右上角只统计今日未读且未抑制的消息。

6. 30日检测数据

  • 企业区按“企业签名 × 运营商”展示。
  • 通道区按“签名 × 通道 × 运营商”展示。
  • 日期T由页面日期控件决定,展示T-1T-30
  • 每日展示提交尝试数、上游接受业务短信数、最终送达成功数和最终成功率。
  • 无真实提交显示灰色;尚未报备通过或早于当前连续通过时间显示“不适用”,不得伪装成零发送。
  • 其他非零数据复用现有红、橙、黄、蓝、绿、深绿六档色阶。

7. 全部实施步骤(共16步)

第1步:设计、需求与测试文档

先完成本文、需求文档、规划测试用例和测试进度同步并交由用户评审;用户确认后才进入代码和数据库实现。本步骤已完成。

第2步:用户评审与口径冻结

由用户评审字段、交互、统计、历史兼容、抑制和发布顺序。用户已确认按步骤实施,本步骤已完成。

第3步:发布基线与真实数据盘点

重新核对Git、运行提交、migration、活动通道、通道组、路由、签名任务、历史记录和近30日业务短信数据;制作数据库与代码恢复方案。只读盘点,不发送短信、不修改通道。

第4步:兼容数据库底座

新增通道运营商能力集合;为签名报备任务增加carrier/approvedAt/approvalScope等兼容字段和条件唯一约束。旧字段继续可读,迁移只增加能力,不切换发送行为。

第5步:通道历史能力回填

将旧单运营商值回填为单元素集合,将all回填为三元素能力集合;已删除通道同样保留并迁移。核对记录数和所有外键关联,不改变账号、密码、状态或单价。

第6步:通道运营商多选管理

改造通道创建、编辑、复制、详情、列表筛选和审计;后端强制至少选择一个运营商。取消仍被活动通道组使用的能力时返回真实影响并阻止保存。

第7步:运营商级签名报备后端

升级签名任务创建、批量生成、状态修改、查询、删除治理和汇总逻辑。运营商必须属于通道能力集合;同一签名、通道、运营商只存在一个当前任务。

第8步:报备任务与签名状态页面

在签名页、报备任务页和通道报备详情页展示运营商级状态;同一通道可按三行或可展开三运营商展示。三网摘要只汇总真实运营商任务,不从通道级状态推断。

第9步:历史报备自动转换

使用幂等migration按通道能力集合生成运营商级任务;旧任务为已通过时全部适用运营商均按迁移当天记为已通过,其他状态原样转换。已有运营商任务不覆盖,旧任务转为legacy_split并保留。预警页面不提供“历史待确认”页签,后端不暴露历史人工确认接口。

第10步:发送链兼容双读

发送链优先读取运营商级任务;未完成拆分的历史任务暂时使用受控旧资格。记录每次使用旧资格的可观测指标,为严格切换提供清零门禁。

第11步:严格运营商级发送门禁

只有当活动历史未拆分数、旧资格命中数和异常数据全部为零后,才切换为“签名 × 通道 × 运营商”严格校验。专项验证断连、超时、补发和通道切换,避免误阻断真实业务。

第12步:预警规则与通知配置

实现通用规则、企业应用特殊规则、通道特殊规则、规则版本和多Webhook配置。Webhook地址加密保存、脱敏显示,并限制安全目标。

第13步:每日检测、预警周期与快照

实现北京时间每日幂等任务、企业和通道两类检测、连续周期、恢复关闭、规则快照和近30日聚合。不得以Mock、静态数据或前端计算代替真实数据库结果。

调度固定拆为两个阶段:北京时间04:00只完成检测、周期推进和快照落库,同时冻结预警标题与正文;北京时间08:00再按快照创建站内消息、聚合Webhook并开始投递。服务晚启动时按所处时点顺序补偿,04:00前不检测、08:00前不发消息。由于自动调度、启动补偿和数据库幂等已覆盖日常及故障恢复,运营端不再保留手动检测按钮和对外管理接口。

第14步:抑制、已读和Webhook投递

实现临时/永久抑制、抑制管理、取消审计、未读状态、异步Webhook、幂等、失败重试和投递日志。抑制期间继续生成检测快照。

第15步:预警页面和签名质量检测改版

在安全控制增加“签名清退预警”,增加消息列表、今日企业/通道数量和顶部预警铃铛;原待审核铃铛更换为任务图标但保留全部功能。签名质量检测页先展示“签名通道发送质量”,其后增加企业、通道两类30日热力图;两张热力图按维度行各自独立分页、每页10行,日期列仍横向滚动。删除已确认不保留的四个统计模块。

预警页签命名为“预警消息”,后端按消息创建时间的北京时间日期区间查询历史消息,并在同一查询中关联检测维度、企业、企业应用、签名和通道完成筛选、计数及每页10条分页;默认区间为今日至今日。抑制和取消抑制复用平台Modal,临时抑制以截止日期换算为后端天数,永久抑制不传天数,两者均要求原因;取消也要求原因,不使用浏览器原生弹窗。

热力图日期列按T-1T-30由新到旧排列;行首只常驻签名以及通道维度必要的通道/运营商标识,企业和企业应用通过签名悬停提示查看。企业、通道模块分别在前端对后端返回的真实维度按企业、企业应用、签名过滤并独立分页。每行增加30日上游受理业务短信合计并按合计降序排列。格子悬停明确展示提交条数和最终发送成功条数,不混淆上游接受。报备后的完整观察窗口只控制清退预警资格,观察期仍按日生成observing快照并展示真实发送量,不创建预警周期、站内消息或Webhook。

页面底部增加独立的未报备签名查询。后端按所选北京时间自然日,以SmsMessageRecord为业务短信事实,按短信运营商检查该签名是否存在任一未删除通道上的当前运营商级approved任务;仍处于approved的历史通道级兼容任务视为已有真实旧报备,避免迁移期误报。其余按签名和消息实际企业应用聚合,后端完成关键字过滤、总数和分页,前端不使用静态数据或全量拉取伪分页。

第16步:完整验证与分阶段预生产发布

依次执行migration演练、真实PostgreSQL聚合、API专项、发送链、长短信、重试/补发、权限、Webhook安全、TypeScript、构建、结构契约和git diff --check。发布必须分别设置“兼容底座”“历史确认”“严格发送”“预警启用”门禁,不在一次发布中同时迁移、切换发送和启用预警。

8. 暂停与回滚门禁

  • 第2步用户未确认:停止,不实施。
  • 第4至10步可回滚到能够读取运营商集合和历史任务的兼容版本;出现双运营商通道后不得回滚到只识别旧单值的版本。
  • 第11步严格门禁启用后,如出现真实发送资格异常,优先切回兼容双读版本,不回滚或覆盖已经产生的新业务数据。
  • 任一阶段不得为验收发送、补发或重投真实短信,不修改真实通道账号、密码、启停状态、企业余额或客户连接,除非另获明确授权。