fix: coordinate SMS completion and improve operations diagnostics
CSS quality / css-quality (push) Has been cancelled

This commit is contained in:
hectorzhao
2026-09-16 18:27:29 +08:00
parent a0209f93bc
commit a350aca883
40 changed files with 2599 additions and 366 deletions
@@ -2321,3 +2321,21 @@ Webhook需在当前受支持Node运行时通过真实HTTPS投递;SSRF校验后
## 2026-09-16 产品名称统一
产品正式名称为“聆界短信平台”,页面标题、API文档品牌名称、导出表格作者和充值回执替代文本统一。产品3.0、工程3.0.0不变;CMPP协议名称及技术标识保持兼容。名称调整仅涉及展示文案和导出作者元数据,不改变布局、业务流程、协议、接口地址或工程版本;版本元数据属于独立变更。
## 2026-09-16 长短信回执并发处理可靠性补充(待实施)
本节细化既有短信幂等、补发与计费一致性要求,不改变费率、分段汇总、补发条件或客户接口协议。不同分段回执同时到达时,同一次有效发送只能产生一份已提交的收尾决策;同一次失败最多创建一个后继补发。合法分段历史完整保留,HTTP按业务消息、CMPP按客户原始分段生成耐久通知,网络失败沿用同一投递身份重试。
处理进程退出后必须接续,不因“已认领”漏处理;旧持有者和旧尝试不得覆盖新的有效结果,不重复扣费、退款或补发。unknown及不完整分段继续等待既有条件,不能被永久完成标记阻止后续处理。历史数据不得因升级自动重发或重退。
实施设计和适用边界见 [发送链路第10节](phase-4-send-pipeline-redesign.md),验收为 [TC-RC-20260916-0112](system-functional-test-cases.md)。本次仅方案,不代表线上修复或新增发送授权。
## 2026-09-16 五项联合整改(实施中)
1. 实施发送链路方案第10节,长短信回执按尝试耐久协调,保证并发、故障恢复、补发、账务和通知一致。
2. 运营通道测试不进行签名/引流内容检测与报备校验,正文按输入交给指定通道;仍校验权限、号码/长度、通道启用/连接和协议参数。客户正常发送保持原规则。
3. 双端签名工具增加短信参数独立输入、真实发送与应用层HTTP请求/响应展示,详见HTTP专项设计2026-09-16补充。
4. 系统监控告警持久保留,仅手动清除,已读不清除、恢复不清除,新触发周期独立。
5. 监控刷新失败显示真实上一快照和过期提示,超时/切换请求取消,恢复后刷新;不同查询范围隔离。
授权交付:代码、定向/全量测试、精确提交、推送、测试环境标准发布及隔离模拟短信验收;不操作预生产,不向真实运营商发送。
+4
View File
@@ -336,3 +336,7 @@ HTTP-FULL-B02:去除URL IPv6方括号后区分IP字面量与DNS,DNS失败转
### HTTP-0915-B02 HTTP发送误依赖CMPP开关
真实测试企业HTTP enabled/sendEnabled=true、CMPP interfaceEnabled=false时,合法模板请求422,未创建短信。根因SendBatchEntryService.validateSendResources无条件读取interfaceEnabled,与需求HTTP客户接口第一版的独立开通矛盾。仅由内部HTTP_REQUEST_CONTEXT符号确认的HTTP请求传递httpRequest校验选项,再读取真实httpConfig.enabled/sendEnabled;普通客户端及CMPP路径保留原检查,企业认证、租户、应用状态及模板校验不变。没有数据库迁移和计费规则变化。须真实复验CMPP关闭HTTP送达、HTTP关闭拒绝及原CMPP拒绝回归。
## 2026-09-16 签名工具增加真实发送调试(实施中)
双端共用页面保留原始正文签名计算,增加短信调试区:AccessKey、AccessSecret、mobile、content、clientMessageId、Idempotency-Key分别输入。发送目标固定当前站点的/api/openapi/v1/sms/messages,按公开协议生成秒时间戳和nonce,使用同一份JSON字节计算签名并发送。密钥只在页面内存,不存储/上传AccessSecret;展示实际应用层请求方法、路径、请求头、正文和HTTP状态、可读取响应头、原始响应正文,不伪称浏览器隐藏头或HTTP版本为抓包结果。一次点击一次请求,发送期间禁用,不自动重试;超时提示结果未知,保留同一业务幂等键用于核对。新业务内容编辑后生成新幂等键,重试同一内容保持业务键。由原OpenAPI鉴权、应用权限、计费、风控处理,无绕过接口。覆盖失败响应、网络失败、超时、长短信、中文和特殊字符、双端三尺寸与真实发送验收。
+151
View File
@@ -195,3 +195,154 @@ GatewaySubmitOutbox
- 修复后正价smoke为9/9受理,账单`9×325=2925`20 TPS为199/199、账单6467530 TPS为299/299、账单9717550 TPS为499/499、账单162175。四个成功窗口共1006条,账单1006笔、单价均325、合计326950。
- 50 TPS档499条非补发首次供应商Submit覆盖9.930秒,即`50.25条/秒`;相对同日改造前Outbox阶段的`33.07条/秒`提高约52%。该档客户端P50/P95/P99为35/76/135ms;首提499条唯一,全部尝试及Outbox各542条唯一,补发均关联原提交。
- 压测结束Inbox、Submit Outbox和两条Redis Stream全部排空,数据库无重复Submit ID、无等待锁、无idle in transaction;回调池`max=12,total=1,idle=1,waiting=0`。隔离应用单价已恢复0,三条临时运营商规则已删除,真实账务事实保留审计。100/200/300/500未继续执行,当前验收结论限定为50 TPS档通过。
## 10. 长短信分段回执并发整改方案(2026-09-16,待实施)
### 10.1 目的、证据和适用范围
业务解释:一条长短信有多段回执,多个处理流程同时发现整条短信已经有结果,重复安排通知或补发。现有数据库唯一键能阻止重复创建,但不能避免此前重复查询、选路和事务开销。整改目标是“先认领处理资格,再做业务动作;中途退出后可以安全接续”。
依据:[预生产只读诊断](cpu-diagnosis-20260916.md)。2026-09-16 09:2009:4012682次下游回执唯一键冲突关联6335条长短信;1862次补发唯一键冲突关联1859个长短信原始提交。下游冲突关联消息的13373条Inbox均matched且attemptCount=1;补发6组抽样显示不同分段失败回执同时到达并争抢创建补发。核心回执、补发、提交文件在d13ca07至cbc4a03之间无变化。
缺陷有两层:单个receiptKey去重不能覆盖不同分段;补发“先查询、后选路、再创建”的流程存在并发窗口。CPU峰值包含I/O等待,缺少业务进程历史CPU与慢SQL,不能承诺消除此缺陷即可消除全部CPU高峰。
本节是现有发送链路的专项补充,作为本次并发整改的设计依据;细化第4节结果处理及第7节不重不漏验收要求,不替代路由、计费、长短信协议或历史容量结论。不扩展到批次编号冲突、通道容量改造或历史短信重发。用户本轮仅要求方案文档,以下模型、状态、参数均是拟实施设计。
### 10.2 必须保持的业务规则
1. 原始回执逐事件持久化,同一事件幂等;不同分段的合法回执不能当成重复而丢弃。
2. 成功依现有通道回执模式汇总:per_segment须齐段成功,message_level保持既有整条成功语义。不得为降低冲突把第一段成功视为整条成功。
3. 同一次有效发送的失败只能触发一份补发决策;是否允许补发仍检查当前应用、通道组、报备、风控、时间上限等既有规则。unknown不触发补发,72小时及组内时限规则保持。
4. 旧尝试的迟到回执保留审计,不覆盖后续有效尝试的最终成功,不再次触发旧尝试补发或退款。矛盾回执按既有规则记录异常,不采用“谁抢到锁谁决定事实”。
5. 补发不是消息最终失败;仍有有效补发时不得提前生成业务最终失败通知或最终退款。
6. HTTP回调保持业务消息维度;CMPP回执按客户原始分段及Registered_Delivery要求生成。内部上游分段与客户分段不能混用。
7. 现有提交、回执、补发、投递和账务唯一约束全部保留;计费单位、价格、扣退费条件及租户权限不变。
8. 对外投递仍是可重试的至少一次交付,不能承诺网络侧绝对只收到一次;整改保证同一逻辑通知仅创建一份耐久投递事实,重试沿用其身份。
### 10.3 影响模块与最小实施边界
| 所有者 | 拟修改内容 |
|---|---|
| send-receipt.service.ts、send-chain.helpers.ts | 保存分段后提交汇总工作;按当前持久化事实重新汇总和校验有效尝试,移出重复终态副作用 |
| send-retry.service.ts、send-gateway-submit.service.ts | 统一补发处理资格,认领后选路,事务内验证资格并创建Submit与GatewaySubmitOutbox |
| send-gateway-result.service.ts、send-timeout.service.ts、send-downstream-delivery.service.ts | 清查提交失败、超时、平台失败等旁路,接入同一业务消息终态协调,不留下与回执处理竞争的独立写入口 |
| send-accounting.service.ts、send-completion.service.ts | 核实稳定账务键和事务接口;重复恢复不重复扣退,不能用已完成标记替代实际账务事实 |
| downstream-receipt-targets.ts、HTTP Webhook生产端 | 保持目标分段契约,幂等落库后再独立投递,重复命中不直接再次发送 |
| Prisma、回调进程恢复扫描、定向与集成测试 | 增量状态模型、认领/恢复索引、有限批次消费与故障注入 |
预期主要为API发送链路和数据库迁移;不新增页面、不改变客户HTTP参数、签名算法、错误码和CMPP协议。Gateway命令契约预期不变,若实现必须变更,先补契约及Go测试,不能隐式扩大范围。需检查全部调用者而非只在回执方法外套进程内锁。
### 10.4 拟增数据模型与认领规则
采用PostgreSQL耐久工作记录和短事务条件更新,避免仅靠进程内锁或Redis短期锁。拟新增 `SmsAttemptCompletionWork`,每个sourceSubmitRecordId唯一;该名称及字段在实施迁移前与现有模型再次核对。无供应商Submit的业务拒绝使用独立的稳定事件键,不伪造Submit ID。
| 字段 | 含义及约束 |
|---|---|
| id、workKey | 主键及唯一工作键;有Submit时固定为attempt:<sourceSubmitRecordId> |
| tenantId、messageRecordId、sourceSubmitRecordId | 与真实记录归属一致;不信任外部回调传入的租户或消息归属 |
| revision、processedRevision | 收到新的有效事实递增revision;完成时只确认已处理版本,避免并发新回执被覆盖 |
| state | pending、processing、retry_wait、idle、needs_reviewidle表示当前事实已处理,不等于永不再接收新事实 |
| leaseOwner、leaseUntil、fenceVersion | 租约及递增认领版本;旧持有者不能提交后续业务动作 |
| decision、retrySubmitRecordId | 本次已提交决策及已有补发引用;补发一旦创建,不因恢复或后续分段重新选路创建 |
| attempts、nextAttemptAt、lastError、createdAt、updatedAt | 恢复、退避和诊断信息;错误脱敏,不复制短信正文或凭据 |
索引:唯一workKey、非空sourceSubmitRecordId唯一;按state/nextAttemptAt及state/leaseUntil支持有界扫描;messageRecordId支持对账。不按手机号或高基数业务ID创建监控标签。
认领以数据库时间为准:pending、到期retry_wait或租约过期processing可由条件更新取得;认领成功递增fenceVersion。建议初始租约60秒、每20秒续租、每次扫描不超过32条,作为测试起点而非容量结论。连接池预算、扫描间隔及退避上限须通过隔离环境实测定稿。
每次持久化副作用都在短事务中锁定工作记录并核对认领版本、租约及当前有效尝试,同时锁定对应业务消息,使不同尝试/超时入口也不能交错覆盖最终状态。锁顺序统一为工作记录→业务消息→既有账务锁;禁止反向调用形成死锁。不得持有事务等待限速、网络或Redis。
### 10.5 事实保存、业务收尾和补发流程
**A. 接收与汇总**
1. 维持耐久Inbox接收。处理单个回执时,将回执事实、分段审计和工作记录唤醒放入同一短事务;唯一事件已存在时,也须核实存在对应工作,不直接忽略未完成收尾。
2. Inbox的matched表示关联事实已可靠保存,业务收尾由工作记录跟踪;两者状态不能混为一个“完成”。在事务提交前退出,由Inbox恢复;提交后退出,由工作扫描恢复。
3. 工作消费者认领后,重新读取当前Submit、所有有效分段及业务最终状态。未齐段成功则结束本轮为idle,保留processedRevision;后续新事实使其再次pending。unknown也不能被永久锁死,按既有状态机处理后续明确结果或超时。
4. 确认最终结果时,事务内重新核验revision、当前尝试和认领版本。有新事实或尝试已变更,重新汇总或记历史,不使用认领前的旧message对象直接更新。
**B. 允许补发**
1. Submit失败入口与回执失败入口都唤醒同一sourceSubmitRecordId的工作;取得资格后才进行选路等高成本操作。
2. 优先查询已有retryOfSubmitRecordId对应的Submit/Outbox。存在则复用,不再次选路、扣费或创建;不存在才评估业务规则并选择候选。
3. 选路和限速等待不持数据库锁,长等待续租;失去租约即停止。最终短事务核验资格、当前尝试及必要的实时启用/报备条件,原子提交补发Submit、消息当前尝试更新、GatewaySubmitOutbox和工作决策。
4. 事务失败全部回滚;成功后由原有Outbox发布器发送,不由认领流程直接调用供应商。不可把“处理中”当成“补发已成功创建”,也不可因此提前退款。
5. 临时数据库/连接错误进入retry_wait,不能误判为“无通道、最终失败”。确定不允许补发后,才走既有最终失败规则。
**C. 最终业务结果与客户通知**
最终消息状态、必要账务变化和全部应生成的耐久通知事实,应在同一短事务中提交。需让相关服务接受事务客户端;HTTP使用既有HttpWebhookEvent/Delivery模型,CMPP使用CmppDownstreamDelivery,不在事务内向客户发网络请求。
如实际账务接口无法共用事务,实施必须先补充稳定业务键的耐久分步恢复设计并验证全部崩溃点,不能先标工作完成再异步裸调用退款/通知。整条业务完成与单次发送尝试结束须分开:已安排补发只结束旧尝试,不给客户发最终失败。
正常幂等命中使用针对已知唯一键的无异常插入(例如参数化INSERT ON CONFLICT ... DO NOTHING RETURNING)并回读核实归属和内容;不能把所有数据库错误当重复成功。补发/回执唯一约束仍是最后防线,非预期冲突保留告警。
### 10.6 故障恢复与历史兼容
| 中断点 | 恢复预期 |
|---|---|
| 回执事实事务提交前 | 事务回滚,Inbox按既有机制再处理 |
| 事实已保存、工作尚未被领取 | 耐久pending扫描继续;不得依赖setImmediate一定执行 |
| 认领后、选路中进程退出 | 租约到期由新消费者接续,旧版本写入被fence拒绝 |
| Submit/Outbox事务提交结果不确定 | 按原始提交唯一键回读;已有记录继续原Outbox,不创建新Submit |
| 最终状态/账务/通知事务中退出 | 全部回滚或全部提交;恢复查稳定业务键,账务不重复 |
| 通知已入库、网络投递失败 | 原有投递记录重试;不重新运行短信补发决策 |
| 消费者持续失败 | 有限指数退避,达到配置上限进入needs_review并告警;不得伪造业务成功或静默丢弃 |
| 同时有新分段或迟到事实 | revision差异驱动再次汇总;旧尝试只留审计,已完成副作用不重复 |
迁移只增表/索引,不删除历史回执、补发、账单或唯一约束。启用前暂停受影响消费者并完成现有任务排空,不能让旧版直接处理与新版协调器长期并行。
切换时建立准确切换时间及待处理清单:未完成Inbox、正在处理回执以及尚未完成收尾的业务记录进入受控衔接;有最终通知/账务/补发事实的历史记录以事实作为已完成依据。不能仅因新工作表为空扫描全部历史短信安排补发。历史异常修复另行设计、授权和审计。
上线前必须验证回执先于Submit结果、历史缺失Submit关联、无租户通道测试短信和平台业务拒绝等路径。无法可靠关联的记录保留待匹配/人工排查,不推测来源、不误收尾。
### 10.7 观测、性能与验收证据
增加低基数指标:工作认领成功/竞争未获得、租约接管、旧版本拒绝、恢复次数、needs_review数量、最老未完成时长、最终动作数量。重复命中记录计数和必要采样,不让正常幂等持续生成ERROR堆栈;真实失败仍明确告警。
业务验证必须对账:每个源Submit最多一个有效后继补发;每个客户目标最多一份逻辑通知;每个账务业务键最多一笔;最终状态与分段事实/最新有效尝试一致;Inbox、工作表、Submit Outbox、Redis和客户投递都有可解释的完成或等待原因。
性能对比使用同环境、同版本以外条件、同长短信比例、同成功失败分布和同负载,分别记录入口、首次Submit、总Submit、最终送达、分段回执速率及窗口。记录CPU用户态/内核态/I/O wait、数据库写入与锁等待、队列积压及回执完成延迟。新增进程CPU/SQL采样需低开销评估,不擅自在线开启全量SQL日志。
确定性并发用例要求不再出现上述两类预期竞争导致的23505异常,正常情况下每次有效尝试仅一份已提交决策;故障恢复可重复计算,但不能重复业务副作用。性能无倒退且队列按批准的排空时限清空;执行负载前固定对比基线和延迟阈值,不事后选窗口宣称提升。不得承诺未经测量的CPU降幅或TPS。
### 10.8 实施顺序、成本和发布恢复
1. 补定向失败用例复现两段同时成功/失败;盘点所有终态和补发调用路径及账务事务能力,形成事务边界清单。
2. 实施增量模型、原子认领、revision/fence和扫描恢复;先验证多进程争抢及旧持有者失效。
3. 接入回执、提交失败、超时及平台失败路径;事务化Submit/Outbox与最终通知/账务。保持外部协议和业务规则。
4. 执行定向测试、API全量回归、类型检查、构建和现有质量门禁;真实PostgreSQL并发及迁移测试必须通过。Gateway有修改再执行Go测试及vet。
5. 在另行明确的隔离模拟范围内,以真实API、PostgreSQL、Redis、Gateway和Webhook接收端验收,包含非零计费、重启故障、回执乱序及排空对账;页面检查发送详情和批次最终状态。mock只能证明隔离逻辑。
6. 真实回归通过后,按明确提交/推送/目标环境授权交付;部署使用标准release流程和独立恢复资产。测试与预生产分别验收,预生产不得以历史授权直接补发或压测。
这是跨回执、补发、账务和耐久任务恢复的修复,成本主要在事务改造及故障验收,不能仅以修改几行或压低日志级别交付。完成第1步盘点后再给出实现工时;若需改变计费、状态优先级或Gateway契约,先记录范围扩展。
恢复策略:迁移保留增量表;发布失败先停止新旧受影响消费者交叉执行,盘点未完成工作、已生成Submit/Outbox/账务/投递事实,再选择经过兼容验证的应用版本恢复。旧版本不理解新工作表,不能直接回退并声称全部恢复;必须证明待处理工作已排空或存在经过验证的接续路径,否则保持暂停并修复。禁止删除工作记录、回滚业务数据或重新入队来掩盖异常。
上线停止条件:发现重复供应商Submit、重复扣退费、终态错误覆盖、持续积压、无法接管或恢复缺口立即停止放量,保留现场;不通过手工补发完成验收。
### 10.9 完成标准与本轮状态
验收用例见 [系统功能测试用例](system-functional-test-cases.md) 的TC-RC-20260916-0112;原TC-SEND-018/019/020继续执行。记录见 [测试进度](testing-progress.md)。
只有代码、真实并发/故障恢复、账务与队列对账均通过,并完成对应环境独立验收,才能标为该环境已修复。2026-09-16本轮只编写整改方案与用例,未实现模型或业务代码,未运行发送、迁移、提交、推送、测试部署或预生产部署。
### 10.10 2026-09-16 实施细化(开发中,尚未验收)
用户已明确授权实施第10节、提交、推送及测试环境部署;第10.1、10.9的“仅方案”状态是此前记录,当前开始实施,不能据此宣称已上线。
- 增加 `SmsCompletionEvent` 耐久事件日志,与工作 revision 在同一接收事务提交;Inbox matched 表示原始事件已存入该日志。规范化 Receipt/Segment 事实、汇总和副作用由收尾事务一并提交。此细化替代10.5 A1中先写规范化表的顺序,避免规范化事实落库后收尾未接续的窗口。日志保留原始事件,不能将未处理日志计作已完成业务回执。
- 回执、整条提交结果、分段提交结果、超时与平台拒绝通过统一入口入日志;先按可靠关联核验消息及租户。无可靠Submit关联的供应商回执继续留在Inbox待匹配;无供应商Submit的平台拒绝使用message工作键。迁移不扫描历史消息重发。
- 所有收尾协作者通过仅限发送链路的事务适配器加入当前短事务,账务内层事务加入同一事务。锁顺序为工作→消息→账务。HTTP通知生产端显式接收事务客户端,CMPP通知无异常幂等创建;事务内仅写耐久通知,不执行网络投递。
- 补发首先认领。首次尝试到达选路点时回滚探测事务,在事务外重新选路和限速;最终事务重新读事件、revision、有效尝试与当前路由条件,原子创建Submit/Outbox。回滚产生的会话ID不得进入跨事务缓存。临时故障必须抛出并退避,不能被吞成最终失败。
- 恢复扫描初始5秒/32条,租约60秒、20秒续期、事务20秒上限。最多12次失败进入needs_review;这些是待真实环境验证的初值。异步通知仍由原恢复消费者投递。
- 超时与迟到结果保持已退款状态,不重复扣退;每个历史业务键依据实际账务和通知事实恢复。上线前必须以故障与乱序测试核实,不把代码编译当作证明。
待补证据:真实PostgreSQL并发、fence过期、事务中断、队列排空、长短信CMPP与HTTP通知以及账务对账。当前仍为开发中。
### 10.11 本次实现边界与发布依赖(2026-09-16)
- 恢复扫描在worker/callback/all角色运行;正式运行必须启用SEND_SUBMIT_OUTBOX_PUBLISH_ENABLED及对应发布进程。测试环境18:20只读核验两项Outbox开关为true、独立服务active。关闭发布器不属于受支持上线组合,不能把pending当成已发送。
- 收尾needs_review及等待超过300秒由监控采集器直接查询耐久工作/事件表,写入同一告警事件库,恢复仍保留、仅人工清除;不依赖应用发布工具安装Prometheus规则。过程计数仍提供低基数metrics,采集进程口径需区分。
- 两项迁移仅新增四张表及索引,无历史回填、无删除、无自动重发;全量106项已在新隔离数据库重放。工作时间使用UTC表达式,避免数据库会话时区与Prisma时间不一致。应用回退前必须盘点和接续未完成工作,旧代码不能消费这些新表。
- 本地验证包括真实PostgreSQL、两个独立OS进程、事务回滚、旧消费者挂起后接管、三段通知目标、非零账务和重试上限可见告警;网络投递与目标环境的重启/排空验收独立记录,不将路由隔离测试冒称整链路通过。
@@ -256,3 +256,11 @@ type InfrastructureOverview = {
新增GET /admin/infrastructure-monitoring/alert-history,继承运营端会话鉴权,参数from/to为上海自然日,默认含今天近7日、最多31日,page正整数、每页25条。逐日查询Prometheus原始ALERTS_FOR_STATE范围向量,以标签指纹+activeAt分开触发周期,跨日采样合并;不使用粗粒度步长丢掉短周期,不把等待触发当作已发送告警。保留真实触发时间和范围内最后观测时间,最后观测不代表准确恢复。
历史和活动列表独立;历史不提供伪造恢复状态、旧annotations、批量已读或清理功能。超出Prometheus保留期/采集缺口的历史无法追溯,界面明确说明。失败返回503并展示错误,日期非法返回400;不迁移数据库、不变更阈值或采集配置。完整实现/验收及限制见operations-fixes-20260909.md。
## 2026-09-16 人工清除及刷新失败保留真实快照(实施中)
本节替代活动告警随Prometheus恢复自动消失及失败清空指标的旧规则。新增PostgreSQL告警事件记录,以fingerprint+activeAt唯一标识一次触发;后台定期采集及页面读取时持久化。指标恢复仅标识已恢复,告警仍在待处理列表,只有运营手动清除(全局生效、记录操作人及时间)才退出;已读保持个人维度,不等于清除。同周期清除后不被下次采集重新激活,新周期独立产生。采集失败不自动推断恢复,不删除记录。历史审计保留,不能将Prometheus过期历史伪造为已完整迁入。
页面按查询范围在组件内存保留最后成功的真实快照;失败/超时显示错误和最后成功采样时间,不伪装实时值,不通过localStorage生成业务事实。不同时间范围不能串用缓存;请求有真实AbortController超时、切换/卸载取消和过期响应保护,在线恢复触发刷新;保留会话失效/锁定处理。根因验收需记录网络失败与后端采集失败两种路径,并验证长停留、并发切换及三尺寸。
2026-09-16实施补充:收尾工作人工处理/积压告警由采集器直接读取PG,不需要额外安装Prometheus规则;持续条件复用同一发生周期,即使已清除也不在同周期重建,恢复后再次触发才是新事件。手动清除同步移除页面各范围缓存中的同一事件及数量,避免后续刷新失败使已清除告警重新显示。
+37
View File
@@ -5569,3 +5569,40 @@ CLIENT-0914-0107 的模板样式/顺序、文档归属与检索、中文状
- TC-BRAND-20260916-01:浏览器标题、平台Swagger、客户OpenAPI及HTTP文档展示“聆界短信平台”;充值回执图片替代文本、两类报备导出工作簿作者一致。源码检查与构建结果见测试进度,真实页面/API/导出验收单独记录。
- TC-BRAND-20260916-02:产品3.0/工程3.0.0、客户接口独立版本、CMPP协议、API路径、签名规则、工程包名和基础设施标识保持不变;已有工作区修改不被覆盖。
## 长短信回执并发整改验收(2026-09-16,待实施、未执行)
设计依据:[发送链路整改方案第10节](phase-4-send-pipeline-redesign.md#10-长短信分段回执并发整改方案2026-09-16待实施)。下列用例均为P0,通用前置条件为明确授权的隔离测试企业/应用、模拟号码/通道,真实API、PostgreSQL、Redis、Gateway和Webhook接收端;保留非零计费规则。测试执行本身不因用例存在而获得发送、补发、配置变更或压测授权。
每例保留messageId/sourceSubmitRecordId、脱敏回执时间线、工作记录及认领版本、Submit/Outbox数、客户逻辑通知及实际投递次数、账务流水和队列结果。实际投递重试与重复创建分别计数。故障测试使用隔离环境可控断点或进程终止,禁止预生产注入。
| 编号 | 场景与步骤 | 通过标准 |
|---|---|---|
| TC-RC-20260916-01 | 两段、三段成功回执通过不同消费者同时进入;再逐段延迟和逆序各执行一组 | per_segment最后一段成功前不判整条成功;齐段后仅一份最终业务决策;按客户目标生成规定数量回执,无多余逻辑通知和去重键异常 |
| TC-RC-20260916-02 | 两段、四段失败回执同时进入,开启允许补发且有可用模拟候选 | 每个源Submit仅一个后继Submit及对应Outbox;竞争失败流程不重复选路;模拟器无因本缺陷多出的Submit;无retryOf唯一键异常 |
| TC-RC-20260916-03 | 同一失败同时由Submit结果和回执入口触发;再与超时处理竞争 | 入口共用协调;按既有状态规则只提交有效决策;不得一边补发一边最终退款/通知失败 |
| TC-RC-20260916-04 | 相同回执重复20次,再混合不同分段并发;用两个回调消费者处理 | 原始合法分段保留,同一事件幂等;副作用数不随事件重复数增长;不存在仅单进程锁有效的问题 |
| TC-RC-20260916-05 | 旧尝试失败后新尝试成功,再注入旧尝试成功/失败回执;另测message_level成功后矛盾失败 | 最新有效成功不覆盖、不重复退款补发;历史完整;矛盾事件按既有异常规则记录 |
| TC-RC-20260916-06 | 注入unknown、缺一段、回执先于Submit结果;后续补齐合法事实;测试72小时超时 | unknown不补发,缺段不误成功,后续事实可唤醒idle;超时后迟到结果遵守既有规则;未匹配事件不被伪造关联 |
| TC-RC-20260916-07 | 在事实保存前、保存后未认领、认领后未提交三个断点退出并重启 | Inbox或耐久工作分别接续;不漏回执、不丢收尾;每例在预先配置的恢复预算内完成或明确告警 |
| TC-RC-20260916-08 | 挂起旧消费者至租约过期,让新消费者接管,再恢复旧消费者;选路期间加入新事实 | 新fence有效,旧fence不能创建Submit/退款/通知或覆盖状态;revision不丢;允许重新计算但无重复副作用 |
| TC-RC-20260916-09 | 在补发Submit/Outbox事务提交前后、最终状态/账务/通知事务提交前后断开连接或退出 | 未提交全部回滚,已提交通过稳定键回读;恢复不新建第二份补发或账务;短信记录、账户流水、Outbox和通知一致 |
| TC-RC-20260916-10 | HTTP通知成功、503、超时;CMPP客户断线重连;含多客户分段和Registered_Delivery=false | HTTP业务事件及CMPP应通知目标身份稳定;网络重试使用已有投递记录;不因客户回调失败补发短信;不要求回执的分段不下发 |
| TC-RC-20260916-11 | 升级前准备历史已完成、在途、缺Submit关联、无租户通道测试、平台拒绝数据;演练迁移、切换与恢复 | 已完成历史不重发、不重退;在途接续清单完整;归属不明保留待处理;测试消息不通知客户;旧版本恢复前必须验证未完成工作接续,跨租户关联拒绝 |
| TC-RC-20260916-12 | 相同负载及长短信/失败比例做修复前后对比,并注入临时数据库错误、候选失效和持续失败 | 认领后实时校验有效;临时故障不当最终失败;持续失败进入可见告警;正常并发无两类预期冲突;无业务重复、账务不符或持续积压,按预设延迟/排空预算通过 |
附加回归:TC-SEND-018补发停止条件、TC-SEND-019旧回执、TC-SEND-020账务幂等、单段短信、黑名单/频控/签名/引流报备、租户和应用停用、批次进度及发送详情真实回执时间。并发模拟通过不替代API全量、类型、构建与质量门禁;Gateway改动另执行Go测试和vet。任何无法执行项明确登记,不以mock计为真实验收。
## 五项联合整改验收补充(2026-09-16)
此前RC-01~12为本次实施矩阵,不能沿用“待实施”标题作为当前事实;执行结果逐项记录,未完整覆盖的条目保留未完成。
| 用例 | 验收内容 | 当前证据 |
|---|---|---|
| TC-OPS-0916-01 | 通道测试无签名、未报备URL及长短信;真实Gateway最终检查仍放行;普通客户保持原拦截 | 最终guard定向4项通过;真实Gateway待执行 |
| TC-OPS-0916-02 | 双端参数独立输入、原始UTF8签名、真实请求/响应、幂等键保留、重复点击/超时不自动重发 | 前端定向通过;真实浏览器待执行 |
| TC-OPS-0916-03 | 告警恢复、刷新、重启不清除;手动清除有审计且并发幂等;同周期不重现,新周期可见 | 真实PG通过;页面待执行 |
| TC-OPS-0916-04 | 监控刷新失败保留当前范围最后成功快照并标明非实时;网络恢复、路由切换与三尺寸 | 组件测试通过;真实浏览器待执行 |
| TC-OPS-0916-05 | 收尾第12次失败进入needs_review,自动出现在耐久告警;恢复后不自动消失 | 真实PG通过 |
RC-01/02/04/08/09/10/11目前仅部分本地证据:三段齐段、重复与双进程、事务回滚和过期接管、通知目标数与非零账务、迁移重放;尚不能标整条矩阵通过。RC-03/05/06/07/12的完整组合、网络故障/进程重启、修复前后性能对比须独立补验。无真实运营商流量,未声明容量提升。
+20
View File
@@ -5071,3 +5071,23 @@ CUA本轮可用,实际后端文档三尺寸1600×1000/1366×768/390×844无页
### 2026-09-16 更名本地提交范围核对
用户追加授权本地提交。本次精确暂存更名代码、规范标题及需求/用例/进度中的更名段落;package及lock版本、main.ts的Swagger版本变更和既有未跟踪version-3.0-baseline.md草稿不纳入本次提交。3.0.0版本元数据仍留在工作区,提交不代表版本标识已发布。前述测试为本地工作区结果,不冒称隔离候选精确提交的全量验证。既有metrics、发布工具、部署脚本与其他文档改动保留。推送、测试部署及预生产部署未执行。
## 2026-09-16 五项联合整改启动
用户确认实施phase-4-send-pipeline-redesign.md第10节,并授权通道测试免签名/引流检测、HTTP参数化发送调试、监控告警人工清除与刷新保留真实快照;提交、推送及测试环境发布/充分长短信验收。main=a0209f93bc8eee6cb08a9d7cace4163b26749ae6,实际远端86cb9ae,暂存区空。61份已有修改/草稿保护摘要及原文位于.local-data/five-fixes-20260916,前轮版本及发布工具不自动纳入。测试SSH首次连接超时,尚未认证;本地工作继续,部署/真实环境待连通后执行。尚未修改业务代码或操作线上状态。
## 2026-09-16 五项改造开发进展(18:00,本地,未提交/推送/部署)
- 承接用户确认:执行发送链路第10节、通道测试跳过签名与引流、HTTP参数化真实发送调试、告警手动清除、监控失败保留最后成功快照。测试机开机后SSH已恢复;在线版本仍为cbc4a033251c7496414b1e7aa6233ed49bd108ec。预生产未操作。
- 新增耐久工作/事件日志及告警事件/采集水位迁移;按工作→消息→账务/批次顺序收尾,补发选路限速在事务外,通知/账务/Outbox入同一事务。修复探测异常被吞、事务会话缓存、迟到结果重复计费、超时终态覆盖及多消息批次进度事务隔离细节。
- 通道测试除去入口检测,同时修正Gateway最终引流授权入口;仅按真实Submit归属确认的无租户/无批次测试消息豁免,普通客户消息仍校验。
- 本地隔离PostgreSQL 16434/cmpp_qa_completion_20260916已执行全量106迁移(后续UTC默认值细化尚需新库重放)。真实数据库验证并发24事件/12唯一事实、事务故障回滚与接续、租约接管、三段齐段成功、CMPP/HTTP通知幂等、非零975计费/超时退款一次/迟到回执、三段失败只创建一份后继Submit/Outbox。路由与限速在补发事务测试中被隔离,不作为真实路由/Redis/Gateway通过依据。
- 证据脚本tools/testing/verify-attempt-completion.mjs;日志.local-data/five-fixes-20260916/completion-integration.log。故障注入故意产生completion_retry_wait,不是线上异常。
- 最近定向隔离回归:发送链路+最终通道校验142/142;发送链路+监控服务147/147(范围重叠,不相加);HTTP页面/签名15/15。后端类型检查通过。后续改动须复验;真实浏览器、完整回归、故障恢复矩阵、实际CMPP/Webhook投递与测试部署仍未完成。
- 保护既有61项修改快照,未把原metrics/发布工具/文档草稿视作本轮内容。此前产品命名提交a0209f9尚未推送。本轮新增metrics两处接入需精确hunk暂存,不能包含此前指标修改。
### 2026-09-16 18:25 本地验证与交付准备
前端全量35套163项通过(115.33秒),后端77套835项通过(171.189秒);类型检查通过。新增隔离PG全量106迁移重放和11组耐久工作/告警验证通过,包含独立OS进程并发及挂起旧消费者恢复,日志在.local-data/five-fixes-20260916。第12次失败转人工处理及数据库告警采集已补验证;日志中的故意故障注入不得当线上异常。最新采集改动需候选精确提交回归。
真实环境尚未部署;独立Playwright获用户允许,专用Edge等待用户完成登录。测试Outbox发布开关及独立进程已核验。为通过更名涉及文件的既有门禁,仅移除official-export未使用导入并格式化该文件及RechargeReceiptDialog,业务规则不变。保护项未纳入;开始准备精确暂存,尚未提交/推送。