feat: integrate analytics and fragment receipt improvements

This commit is contained in:
hectorzhao
2026-08-03 15:34:41 +08:00
parent 3357ace7e1
commit 530a65de80
89 changed files with 1964 additions and 324 deletions
+34 -3
View File
@@ -16,6 +16,7 @@
- 企业应用连接详情只展示当前已连接会话;断开或心跳超时会话从活跃连接表删除,不保留为连接历史。
- 短信审核批量通过必须基于明确勾选,只处理已选待审核任务;不得默认通过当前筛选结果或全部数据。
- 下游投递记录支持创建日期范围筛选,并将日期条件下推 PostgreSQL 列表与 Dashboard 聚合。
- 下游投递记录和恢复状态管理的多条件筛选区必须遵循共享查询控件规范:普通条件、日期范围和操作按钮使用统一宽度,空间不足时按完整控件自动换行,不允许为维持单行而压缩、重叠或截断控件;移动端条件整行展示,查询与重置按钮保持清晰的独立操作区。
- 短信模板变量插入到文本框当前选区或光标位置,插入后光标移动到变量之后。
- 运营端短信记录使用自适应信息卡片,发送详情按概览、短信内容、通道回执、状态和分片审计分组,失败原因使用独立警示区域突出;该项只调整前端展示,不改变短信记录后端语义。
- 人工充值弹窗不要求填写操作人,操作身份从当前登录会话和后端操作日志取得。
@@ -1691,7 +1692,7 @@
4. 通讯日志不得保存短信正文、密码、密钥、Token、签名鉴权值或完整HTTP请求体;手机号只保存脱敏值。CMPP心跳不得逐包写入数据库,连接健康仍使用连接状态和聚合指标。
5. 通讯日志写入不能阻塞短信主链路,默认批量异步写入,缓冲区应有上限和溢出告警;热数据默认保留30天,保留期允许通过环境变量配置。
6. 通讯日志方向固定使用“企业应用 → 平台、平台 → 供应商通道、供应商通道 → 平台、平台 → 企业应用”。供应商长短信每个真实 `SUBMIT``SUBMIT_RESP` 分片各记一条,企业应用每个真实 `SUBMIT_RESP` 也必须记录;内部 `submit-result` 聚合回调不是协议报文,不得重复生成通讯日志。
7. 供应商长短信回执必须先写入对应 `SmsMessageSegmentAudit`。仅当同一提交尝试的全部分片均为 `delivered` 时,主记录才转 `delivered` 并向企业应用投递一次最终回执;任一分片明确失败可进入最终失败/补发状态,分片尚未齐全时主记录保持 `submitted`,不得由首片成功提前聚合。
7. 供应商长短信回执必须先写入对应 `SmsMessageSegmentAudit`。仅当同一提交尝试的全部分片均为 `delivered` 时,主记录才转 `delivered`;任一分片明确失败可进入最终失败/补发状态,分片尚未齐全时主记录保持 `submitted`,不得由首片成功提前聚合。内部业务终态只聚合一次,但对企业应用的CMPP状态报告必须按其原始Submit分片逐片投递,并分别使用平台当初为该分片返回的`CMPP_SUBMIT_RESP.Msg_Id`HTTP Webhook仍按原HTTP消息投递一个最终事件。
8. 长短信任一分片返回非成功终态时,系统必须通过该分片审计关联的提交记录识别当前发送尝试,不得仅以主记录保存的首片上游消息号判断;确认属于当前尝试后,整条短信立即进入失败/补发或退款终态,无需等待其余分片回执。
9. 回执和上行投递方式不得由运营人员选择。企业应用开通CMPP接口即按CMPP投递,开通HTTP接口且对应Webhook地址非空即按HTTP投递,两者同时满足时双投;任一地址为空时只跳过该类HTTP事件。运营端企业应用HTTP参数页必须始终可编辑回执和上行Webhook地址,不因HTTP接口开关关闭而隐藏。
10. Gateway向企业应用发送真实 `CMPP_DELIVER` 以及收到企业应用真实 `CMPP_DELIVER_RESP` 时,都必须各写一条通讯交互日志,分别使用“平台→企业应用”和“企业应用→平台”方向;下游投递记录继续承担排队、重试和ACK业务状态,不得以通讯日志替代。
@@ -1709,7 +1710,8 @@
1. 用户逻辑删除后,原用户记录、用户主键及历史审计关联必须继续保留;用户名、邮箱和手机号仅在未删除用户范围内唯一。新建用户可以复用逻辑删除记录曾使用的登录标识,但必须生成新的用户主键,不得继承旧用户的角色、企业归属、密码、会话或权限。
2. 用户登录和按用户名查找必须显式排除逻辑删除记录。活动用户之间的登录标识并发冲突继续由PostgreSQL唯一索引保证,并返回HTTP 409、冲突字段及明确中文提示。
3. 运营端用户管理将用户姓名、登录账号、所属企业、用户角色和状态拆分为独立条件;客户端将用户姓名、登录账号和状态拆分。点击查询或重置时调用真实后端组合查询,条件之间使用AND,登录账号内部对用户名、邮箱和手机号使用OR;不得加载全量数据后仅在浏览器过滤。
4. 删除、禁用或降权最后一个平台管理员时,后端实时拦截继续作为权威判断;企业管理员不设“最后一名”保护,可删除或停用至零人。前端必须在当前确认弹窗内以`role=alert`显示平台管理员保护失败原因和处理建议,保持弹窗打开,禁止只向浏览器控制台输出未处理Promise;请求期间确认按钮必须禁用
4. 运营端用户管理的五组查询条件与查询/重置操作必须使用共享查询控件宽度并允许按完整控件自然换行;不得通过缩窄字段把所有条件强塞在一行。“新增用户”作为业务操作与查询操作保持独立,在窄屏下不得挤入查询字段之间
5. 删除、禁用或降权最后一个平台管理员时,后端实时拦截继续作为权威判断;企业管理员不设“最后一名”保护,可删除或停用至零人。前端必须在当前确认弹窗内以`role=alert`显示平台管理员保护失败原因和处理建议,保持弹窗打开,禁止只向浏览器控制台输出未处理Promise;请求期间确认按钮必须禁用。
## 2026-07-26 企业应用停用与回执清算补充要求
- 删除企业前必须检查其企业应用;只要存在`active``disabling`应用就阻止删除,并提示先完成应用停用。
@@ -1768,7 +1770,7 @@
1. 同一`SmsSubmitRecord`无论收到多少个分片失败回执、重复聚合结果或并发工作线程,只允许创建一个下一跳补发记录。数据库必须以来源提交记录建立唯一补发关系,不能只依靠进程内锁、先查后建或短信主记录当前状态判断。
2. 任一分片明确失败仍可及时判定本次长短信尝试失败,不要求等待其余失败回执;后续分片回执继续完整落库和写通讯日志,但只能复用已取得的补发决定,不得再次向Gateway发布提交命令。
3. 短信扣费、冻结释放和最终失败退款必须使用稳定业务幂等键。企业账户余额变更在数据库事务内按企业串行并使用原子增量,禁止读取旧余额后覆盖写入;相同幂等键重复调用必须返回原交易,不得再次改变余额。
4. 同一短信记录只允许成一最终回执投递。CMPP下游投递使用数据库唯一去重键,HTTP Webhook使用稳定事件号和事件/端点唯一关系;重复终态处理返回原投递,不得再次向客户发送
4. 同一短信记录只允许成一个内部最终业务结论、一笔最终退款和一个HTTP最终回执事件。CMPP下游必须按原始客户Submit分片分别生成最终状态报告,使用“短信记录+原始客户分片序号”数据库唯一键;同一分片重复终态处理返回原投递,不得再次发送。HTTP Webhook继续使用短信记录级稳定事件号和事件/端点唯一关系。
5. 补发抢占成功、并发复用及下游投递去重必须写结构化日志,至少包含平台消息号、短信记录、来源提交记录、下一跳`submitId`、通道和复用的投递记录。
6. 历史重复提交、通讯报文、回执、退款及客户ACK属于事故审计证据,不得在功能migration中删除或覆盖。历史余额修正必须先完成账户与流水专项对账,再通过可审计冲正处理。
@@ -1873,3 +1875,32 @@
- 短信发送页的字数和预计条数必须随编辑后的实际短信内容即时重新计算;单条短信不超过70个Unicode字符计1条,长短信按每67个字符计费,预计条数为单号码计费条数乘有效号码数。单价单位显示为“元/条”。
- 提交发送任务失败时使用页面中央弹窗展示真实后端错误;定时发送控件提供按北京时间计算的“今天”按钮,并以浅色背景标出北京时间当天。提交给后端的定时时间必须显式携带`+08:00`时区。
- 提交任务成功后弹窗展示真实任务编号和发送号码数。“继续发送短信”清空当前发送表单和导入内容;“查看任务进度”进入批量任务页面并按任务编号定位本次任务。
## 工作台金额与审核查询控件统一(2026-08-03)
- 客户端短信服务工作台在“今日返还金额”前展示“今日消费金额”,金额取当前企业 Dashboard API 按北京时间当天汇总的真实消费值,与运营端账务口径一致,不在浏览器重新估算。
- 审核中心的企业认证、短信、短信模板、短信签名和引流信息审核页面均提供“提交时间”日期区间筛选;短信签名和引流信息的“导入批次审核”页签也按导入批次提交时间筛选。
- 提交时间筛选必须传入真实后端并由 PostgreSQL 执行。日期边界按 `Asia/Shanghai` 自然日解释,开始日包含 `00:00:00`,结束日包含 `23:59:59.999`;格式非法、日历日期不存在或开始日晚于结束日时,API 返回受控参数错误。
- 运营端查询区建立全局统一尺寸:普通输入框/下拉框使用统一标准宽度,日期区间控件使用更宽的统一宽度,查询/重置按钮使用统一固定宽度;窄屏下控件和按钮自适应整行,不产生页面级横向溢出。
- 风控规则页的规则范围、平台白名单和号码频次触发记录三组查询条件均使用上述统一布局。白名单和触发记录提供查询、重置,重置后以明确的默认条件重新请求真实后端。
## 短信内容引流信息识别与统计(2026-08-03)
- 本期只识别、记录、查询和统计短信内容是否含引流信息。引流资料是否已报备、审核状态及报备进度均不得拦截或转人工审核;所有发送入口移除`DRAINAGE_NOT_APPROVED`决策,既有模板、签名、余额、黑名单和其他风控规则保持不变。
- 运营端“系统管理”新增“引流识别规则”页面,规则存储在真实数据库,支持 URL、手机号码、固定电话三类表达式的新增、编辑、启停、优先级和测试。变更保留版本并写操作日志,发送入口按当前启用规则生成识别快照和规则版本。
- URL 识别覆盖带协议链接、无`http://`的裸域名、短链接、IP 地址及端口/路径,并支持中文标点相邻、空格或中文句号拆分等规避写法;手机号码支持`+86`、空格、短横线和中文标点拆分;固定电话支持区号括号、分隔符和分机号。邮箱地址不属于引流信息。
- 识别规范化只作用于检测副本,不得修改真实短信发送内容。消息记录持久化是否含引流、命中类型、原文位置、规则版本和检测时间;历史未检测数据保留为“未检测”,不得伪造为不含引流。
- 运营端短信记录提供“是否含引流信息”筛选,支持含引流、不含引流和未检测;含引流记录使用提示色底色并高亮原文命中片段,CSV 同步导出该维度。
- 数据统计的签名发送质量明细保留原“通道 × 运营商”整体矩阵,并提供按含引流、不含引流、未检测切分的矩阵视图;整体统计必须直接反映全部提交,不得用分组平均值替代。
- 运营看板“今日签名发送统计”按签名统计全部短信,不区分是否含引流;“今日签名发送统计 - 含引流”只统计内容识别结果为含引流的消息。
- 未来可在识别结果之上增加发送、拒绝或人工审核决策,但必须作为独立迭代启用,不能在本期以隐式状态或既有报备审核逻辑提前拦截。
## CMPP逐分片最终回执与72小时超时回执(2026-08-03
- CMPP协议状态值中的`ACCEPTD``UNKNOWN`不得在产品和代码中扩展解释为协议规定的“临时状态生命周期”;平台只依据明确业务规则判断是否继续等待,不能臆造协议阶段。
- Gateway接收每个客户`CMPP_SUBMIT`时必须保存该包的`Registered_Delivery``Sequence_Id`。长短信每个原始分片的身份独立保存,不得只保留第一片;历史未保存`Registered_Delivery`的CMPP记录按原有“请求回执”行为兼容。
- 内部仍以一条`SmsMessageRecord`聚合长短信业务终态、重投、计费和退款;对外CMPP状态报告按原始客户分片逐片建立。每片使用`SubmitGroupMessageId + 原Sequence_Id`重建平台当初返回的`SUBMIT_RESP.Msg_Id`,并以“短信记录+客户分片序号”独立幂等。
- 已取得真实分片回执时,下游对应分片必须使用该片自己的状态、原始状态码、错误码和到达时间,不得把另一片的结果复制过来;整条短信明确最终失败而部分片仍无结果时,缺失片使用整条短信的明确最终失败状态,已成功片不得改写为失败。
- `Registered_Delivery=0`的客户分片不生成CMPP状态报告;同一HTTP提交仍只生成一个消息级最终Webhook,不因供应商内部计费分片数而重复回调。
- 提交或未知状态满72小时仍无明确最终回执时,主记录转为`timeout`并写入`undelivered/EXPIRED/RECEIPT_TIMEOUT`。CMPP对每个请求状态报告的原始分片建立失败回执,HTTP建立一个明确失败Webhook;退款保持消息级一次。
- 超时状态变更与下游回执建单之间必须可恢复:仅在HTTP事件及全部应建CMPP分片投递均成功持久化后写`timeoutReceiptQueuedAt`;中途失败保留空标记,由后续定时扫描按稳定幂等键补齐,禁止出现“已转超时但永久没有下游回执”。