fix: harden admin and CMPP delivery workflows

This commit is contained in:
hectorzhao
2026-07-15 11:21:02 +08:00
parent 00b6d95752
commit e47432bc9d
34 changed files with 878 additions and 226 deletions
+38 -7
View File
@@ -23,6 +23,19 @@
| 号码 | 合法号码、重复号码、非法号码、企业黑名单号码、全局黑名单号码。 |
| 账户 | 现金余额与授信额度组合后的和为正数、0、负数;授信额度覆盖正数、负数和 0;不配置套餐余量。 |
| 企业认证 | 未认证、待审核、已通过、已驳回四类企业认证资料。 |
## 2.1 2026-07-15 运营端细节回归
| 用例编号 | 优先级 | 验证内容 | 预期结果 |
| --- | --- | --- | --- |
| TC-ADMIN-UI-0715-01 | P1 | 新建/编辑企业应用并留空或修改 CMPP 账号 | 企业代码控件不可编辑且实时跟随账号;API 最终持久化二者相等;超过每任务号码上限时整个任务被拒绝并有拆分说明。 |
| TC-ADMIN-DICT-0715-02 | P1 | 删除手机号段;分别删除引用数为 0 和大于 0 的报备字段 | 号段从 PostgreSQL 删除;字段列表显示真实使用通道数,未引用字段删除成功,已引用字段按钮禁用且直接调用 DELETE 也返回 400。 |
| TC-ADMIN-CMPP-0715-03 | P1 | 建立连接后主动断开,再制造心跳超时 | 连接详情只显示 active 连接;断开/超时行从 `CmppDownstreamConnection` 删除,操作日志仍保留断开审计。 |
| TC-ADMIN-AUDIT-0715-04 | P0 | 不勾选、勾选部分任务分别点击批量操作 | 未勾选时按钮禁用;只通过已选任务,未选任务状态不变;确认弹窗数量等于选择数。 |
| TC-ADMIN-DOWNSTREAM-0715-05 | P1 | 选择下游投递创建日期范围 | 列表及页面 Dashboard 使用同一日期范围查询真实数据库,范围外记录不计入。 |
| TC-ADMIN-TEMPLATE-0715-06 | P1 | 将光标置于模板中间并插入推荐/自定义变量 | 变量在光标或选区处插入,原选区被替换,光标停在变量后;运营端和客户端一致。 |
| TC-ADMIN-RECORD-0715-07 | P1 | 查看桌面/窄屏短信记录及失败详情 | 卡片不产生页面横向滚动,信息分组清晰;失败原因独立突出;详情仍读取真实 submit、receipt 和分片审计 API。 |
| TC-ADMIN-MISC-0715-08 | P2 | 查看签名引流信息、零待审核通知和充值弹窗 | 使用“引流信息”标题且无提交时间;0 为黑字灰底;充值弹窗无操作人字段。 |
| 客户 | 正常客户、停用客户、欠费客户、未认证客户、跨租户客户、客户联系人和开票资料。 |
| 导入文件 | UTF-8 CSV、GBK CSV、TXT、超 20 MB 文件、含空行/重复/非法号码/非法字符文件。 |
| 非法内容 | 控制字符、emoji、换行、不可见字符、超长变量、签名外置内容、敏感词内容。 |
@@ -1167,6 +1180,21 @@
- 全局 `reportStatus=reporting` 不在入站阶段触发 `SIGNATURE` 拒绝,短信进入真实人工审核聚合链路且不产生签名失败回执。
- 审核通过后只允许选择签名任务为 approved 的主通道,不能选择 pending 的备用通道;最终提交前继续执行同一通道级校验。
### TC-SEND-039B CMPP 变量模板匹配与 direct_send 策略
- 优先级:P0
- 前置条件:应用 A 存在审核通过模板 `【航天信息信诺网】您本次操作的验证码是${code},有效时间10分钟。`;应用 B 配置 `templateMismatchMode=direct_send`。两个应用均配置已审核签名、余额、真实通道组及至少一个签名报备通过且在线的通道。
- 步骤:
1. 应用 A 通过 CMPP 提交 `【航天信息信诺网】您本次操作的验证码是715021,有效时间10分钟。`
2. 查询 `SmsMessageRecord/SmsBatchTask/SmsSendTask`,并检查进入风险评估的模板和变量。
3. 应用 B 提交签名合法但没有任何模板匹配的短信。
4. 分别将应用 B 的签名改为未审核、账户改为余额不足、具体通道签名报备改为未通过后重复提交。
- 预期结果:
- 步骤 1 按固定正文和 `${code}` 占位符匹配模板,保存真实 `templateId`,向风控传入 `code=715021`,不得产生 `TEMPLATE/REJECTD` 失败回执。
- 应用 B 的模板不匹配短信按 `direct_send` 继续进入风控、余额、队列和真实通道路由;消息保存识别出的 `signatureId`,不能被模板拒绝分支截断。
- `direct_send` 只跳过模板匹配要求,不跳过企业/应用状态、签名审核、风控、余额、具体通道报备、通道在线状态和 Gateway 提交校验;任一校验失败时按真实失败原因拒绝或失败。
- `reject``manual_review` 的既有行为不变;CMPP SubmitResp、失败 Deliver Receipt 和最终上游回执仍按既有异步语义处理。
### TC-GW-007 CMPP 客户到上游 SMSC 完整闭环
- 优先级:P0
@@ -1298,7 +1326,9 @@
- 页面列表来自真实 `/api/admin/operations/downstream-deliveries`,不是前端静态数组或本地状态拼装。
- 详情展示真实 payload、`retryCount/nextRetryAt/deliveredAt/lastError`
- 人工重投调用真实 `/api/admin/operations/downstream-deliveries/{id}/requeue`,由后端实际触发 Gateway `/downstream/receipt``/downstream/uplink`
- 重投后记录状态、失败原因和系统日志都与真实后端处理结果一致
- 人工重投后 `manualRetryCount` 递增、`lastRetriedAt` 更新,新一轮 `retryCount` 从 0 开始;系统日志保留重投前状态、原自动重试次数和新人工重投次数
- 重投后若尚未真正写出,列表显示“人工重投排队中”,不得误显示“待首次投递”;自动失败退避中的 pending 显示“等待自动重试”。
- `awaiting_ack` 记录在前端不可选且后端拒绝并发重投,不能仅依赖按钮禁用。
### TC-GW-015 下游投递指数退避
@@ -1326,17 +1356,18 @@
- 后端逐条执行真实重投,返回 `total/successCount/failedCount/results`
- 成功和失败记录都会保留真实后端状态与错误信息;空选择时接口拒绝执行。
### TC-GW-017 下游投递告警聚合
### TC-GW-017 下游投递告警统一聚合
- 优先级:P1
- 前置条件:真实 `CmppDownstreamDelivery` 中准备一批 `pending` 记录,其中部分已超过告警阈值;同时准备一批最近失败的 `failed` 记录
- 前置条件:真实 `CmppDownstreamDelivery` 中准备阈值内/外的 `pending`、未超时/已超过 `ackDeadlineAt``awaiting_ack`、最近窗口内/外的 `failed/unconfirmed/rejected` 及正常 `delivered` 记录,且覆盖多个应用
- 步骤:
1. 访问运营端 Dashboard 和右上角通知区域。
2. 调用真实 `/api/admin/operations/dashboard/statistics`,核对返回的下游投递告警聚合。
3. 点击“下游投递告警”通知,跳转到下游投递记录页进一步筛查。
- 预期结果:
- Dashboard 返回真实 `downstreamDeliverySummary`,至少包含 `pending/failed/delivered/stalledPending/recentFailed/alertCount`
- 右上角通知中的“下游投递告警”数量与真实 Dashboard 聚合一致,不是前端写死值
- Dashboard 返回真实 `downstreamDeliverySummary`,至少包含 `pending/failed/delivered/stalledPending/stalledAck/recentFailed/alertCount`
- `alertCount` 精确等于“超阈值 pending + 超时 awaiting_ack + 最近窗口内 failed/unconfirmed/rejected”,阈值内 pending、未超时 awaiting_ack、历史失败和 delivered 不计入
- 侧栏/首页的“下游投递告警”数量与下游投递 Dashboard 在同一筛选范围下一致,不是前端写死值。
- 点击通知后可以进入真实下游投递记录页继续处理。
### TC-GW-018 下游投递 Dashboard 聚合视图
@@ -1349,10 +1380,10 @@
3. 切换应用和类型筛选,确认顶部 Dashboard 与下方记录列表同时切换到同一筛选范围。
- 预期结果:
- 顶部 Dashboard 必须来自真实聚合接口,不能由当前页列表条目在前端临时汇总。
- `summary``total/pending/delivered/failed/stalledPending/recentFailed/alertCount` 与数据库真实结果一致。
- `summary``total/pending/awaitingAck/delivered/failed/unconfirmed/rejected/stalledPending/stalledAck/recentFailed/alertCount` 与数据库真实结果一致。
- `typeBreakdown` 能正确区分 `receipt``uplink` 的状态分布。
- `retryBuckets` 真实反映 `pending/failed` 记录的重试压力分布。
- `topApplications` 以告警量优先排序,切换筛选后结果实时刷新
- `topApplications` 使用与 `summary.alertCount` 相同的时间窗和状态条件统计,各应用告警数之和与同范围总告警一致,并以告警量优先排序。
### TC-GW-019 下游在线账号 Presence 持久化