feat: support governed cascade deletion

This commit is contained in:
hectorzhao
2026-08-09 19:08:38 +08:00
parent 6add563ee8
commit 7804f64ced
9 changed files with 476 additions and 47 deletions
+13 -4
View File
@@ -1926,17 +1926,26 @@
## 签名删除预检与多通道报备汇总修正(2026-08-09)
- 签名删除预检中的“未结束报备任务”只统计仍需处理的过程态任务;`approved``completed``failed``cancelled``rejected``abandoned``partial``partial_success`均属于已结束历史,不得仅因这些任务存在而阻止删除。模板、引流信息等其他真实依赖仍按原删除治理规则阻止删除
- 签名删除预检中的“未结束报备任务”只统计仍需处理的过程态任务;`approved``completed``failed``cancelled``rejected``abandoned``partial``partial_success`均属于已结束历史,不得作为活动关联项
- 签名及运营商报备汇总不得因单个目标通道失败就直接变为整体“报备失败”。全部当前目标通道通过时为“报备成功”;至少一个通过但尚未全部通过时为“部分成功”;没有通过且仍有其他目标待处理时为“报备中”;只有全部当前目标通道均为`failed/rejected`时才为整体“报备失败”。
- 每个通道的失败事实、失败原因和历史报备记录必须继续保留并展示;汇总状态修正只改变整体归因,不得覆盖或删除通道级失败证据。
## 通道组删除风险展示与历史保留(2026-08-09)
- 运营端删除通道组前,必须通过真实后端和数据库统计并展示:关联正常企业应用数、关联已删除企业应用数、组内通道数、等待供应商提交结果数。企业应用按不同`applicationId`去重;状态不是`deleted`的现存应用计为正常应用,状态`deleted`或应用记录已不存在的残留关联计为已删除应用
- 运营端删除通道组前,必须通过真实后端和数据库统计并展示:关联正常企业应用数、组内通道数、等待供应商提交结果数。企业应用按不同`applicationId`去重;状态为`deleted`或应用记录已不存在的残留关联可继续计入后台审计快照,但不得在删除弹窗展示
- “等待供应商提交结果”固定为该通道组下`SmsSubmitRecord.submitStatus = queued`的记录数,表示平台已选定该组但尚未收到供应商提交结果;该状态不按三个工作日自动完成,不能与最终回执超时口径混用。
- 正常应用关联、已删除应用残留关联、组内通道和等待提交记录均只作风险展示,不得隐藏、禁用或阻止“确认删除”;弹窗不要求输入通道组名称,不要求填写删除原因,由运营查看真实影响后确认。
- 正常应用关联、组内通道和等待提交记录均只作风险展示,不得禁用或阻止“确认删除”;弹窗不要求输入通道组名称,不要求填写删除原因,由运营查看真实影响后确认。
- 删除采用逻辑删除,将通道组状态置为`deleted`并从通道组列表及新短信选路中排除;不得删除组内通道配置、企业应用关联、发送记录、回执或审计数据,确保历史查询、回执处理及上行接入号匹配仍可追溯。
- 弹窗标题为“删除通道组:{通道组名称}”,正文依次展示上述项真实数量,并明确:“删除后该通道组不再参与新短信发送,历史配置、发送、回执和审计数据继续保留。”操作仅保留“取消”和“确认删除”。
- 弹窗标题为“删除通道组:{通道组名称}”,正文依次展示上述项真实数量,并明确:“删除后该通道组不再参与新短信发送,历史配置、发送、回执和审计数据继续保留。”操作仅保留“取消”和“确认删除”。
## 通道、签名与模板级联删除确认(2026-08-09)
- 通道、签名和模板删除原因统一为选填;未填写时仍允许删除,后端必须继续记录操作人、对象版本、幂等键、真实依赖快照和级联结果。删除仍采用逻辑删除,不物理清除历史发送、计费、审核、报备或审计数据。
- 删除签名时,若存在未删除短信模板、未删除引流信息或未结束报备任务,弹窗必须分别提供“同时删除关联的模板”“同时删除引流信息”“同时结束关联的报备任务”勾选项。发现的勾选项必须全部勾选后才允许确认;后端必须再次校验并在同一个`Serializable`事务中将关联模板和引流信息逻辑删除、将未结束报备任务置为`abandoned`,最后逻辑删除签名。
- 删除通道时,若存在未结束报备任务,必须提供“同时结束关联的报备任务”勾选项;勾选后在同一事务中将任务置为`abandoned`并逻辑删除通道。已有活动通道组引用、直接路由规则或活动网关连接仍属于不能由该勾选项解决的硬依赖,必须先处理后再删除。
- 运营端可以看到未结束报备任务的真实ID和状态;客户端也允许勾选“同时结束关联的报备任务”,但客户端专用预检响应和页面不得展示任务ID、状态、通道或其他内部详情,只展示统一说明:“发现关联的未结束报备任务。勾选后将全部置为‘放弃报备’,历史任务和报备记录继续保留。”
- 每一条被放弃的报备任务必须写`ChannelSignatureReportRecord`,保留变更前状态、`abandoned`变更后状态、操作人、原因和`deletion_governance`来源;级联删除的模板和引流信息必须留下子对象审计记录。删除通道并结束任务后,受影响的未删除签名必须在同一事务内按剩余有效通道重算报备汇总。
- 关联模板若仍存在真实未结束发送或批量任务,不得仅靠“同时删除关联的模板”绕过发送安全约束;模板本身删除也使用同一活动任务口径。`SmsSendTask``approved/rejected`按已结束审核任务处理,`SmsBatchTask`至少将`finished/canceled/rejected/failed/completed/cancelled`按终态处理,避免已结束历史被误判为活动任务。
## 发送质量矩阵与成功率色阶统一(2026-08-09)
+11 -3
View File
@@ -4415,15 +4415,23 @@ npm run verify:phase8
| 用例编号 | 操作 | 预期结果 |
| --- | --- | --- |
| TC-DELETE-SIGNATURE-004 | 对仅存在`approved``abandoned`等已结束报备任务,且无模板、引流信息或其他活动依赖的签名执行删除预检 | 已结束报备任务不出现在“未结束报备任务”中,删除预检允许继续;历史任务和记录仍保留 |
| TC-DELETE-SIGNATURE-005 | 对仍存在`pending``waiting_material``reporting``exporting`任务的签名执行删除预检 | 预检列出真实未结束任务ID和状态并阻止删除 |
| TC-DELETE-SIGNATURE-005 | 运营端对仍存在`pending``waiting_material``reporting``exporting`任务的签名执行删除预检 | 预检列出真实未结束任务ID和状态,出现“同时结束关联的报备任务”必选项;未勾选不能确认,勾选后可继续 |
| TC-DELETE-SIGNATURE-006 | 签名同时关联未删除模板、引流信息和未结束报备任务 | 分别出现三个级联勾选项;少勾选任意一项时确认按钮不可用且后端直接调用也拒绝,全部勾选后才可确认 |
| TC-DELETE-SIGNATURE-007 | 客户端删除存在未结束报备任务的签名 | 页面只展示统一的结束报备说明和勾选项;API及页面均不出现任务ID、状态、通道等内部详情;全部关联项勾选后允许确认 |
| TC-DELETE-SIGNATURE-008 | 全部勾选后删除同时关联模板、引流信息和过程态报备任务的签名 | 同一`Serializable`事务内模板、引流信息和签名均逻辑删除,任务置为`abandoned`;每条任务及子对象均有真实审计记录,历史消息、计费、审核和报备记录保留 |
| TC-DELETE-SIGNATURE-009 | 关联模板仍存在未结束发送或批量任务 | 即使勾选“同时删除关联的模板”仍由真实活动任务阻止删除,不中断或丢失正在处理的数据 |
| TC-DELETE-CHANNEL-010 | 通道仅关联未结束报备任务,没有活动组、直接路由或连接 | 出现“同时结束关联的报备任务”必选项;勾选后任务置为`abandoned`并写记录,通道逻辑删除,受影响有效签名按剩余有效通道重算汇总 |
| TC-DELETE-CHANNEL-011 | 通道仍存在活动通道组、直接路由或活动网关连接 | 报备任务勾选项不能绕过其他硬依赖,后端拒绝删除并返回真实阻断原因 |
| TC-DELETE-REASON-012 | 分别在运营端和客户端删除无硬依赖的通道、签名、模板,删除原因留空或填写内容 | 留空时允许删除;填写时原文进入审计详情,三类对象均不再要求至少4个字符 |
| TC-DELETE-TEMPLATE-013 | 模板只关联状态为`approved/rejected`的发送审核任务和`finished/canceled`的批量任务 | 已结束任务不阻止模板删除;真实过程态发送或批量任务仍阻止删除 |
## 2026-08-09 通道组删除风险展示与历史保留用例
| 用例编号 | 场景 | 预期结果 |
| --- | --- | --- |
| TC-CHANNEL-GROUP-DELETE-001 | 打开同时关联正常应用、已删除应用、多个通道和`queued`提交记录的通道组删除弹窗 | 后端按不同应用ID去重并返回四项真实数量;弹窗标题、数量单位、说明和按钮文案与需求一致 |
| TC-CHANNEL-GROUP-DELETE-001 | 打开同时关联正常应用、已删除应用、多个通道和`queued`提交记录的通道组删除弹窗 | 后端按不同应用ID去重并保留审计统计;弹窗只展示关联正常企业应用、组内通道、等待供应商提交结果三项真实数量标题、数量单位、说明和按钮文案与需求一致 |
| TC-CHANNEL-GROUP-DELETE-002 | 同一正常企业应用存在多条通道组关联 | “关联正常企业应用”只计1个,不按关联规则条数重复累计 |
| TC-CHANNEL-GROUP-DELETE-003 | 关联记录指向状态为`deleted`或已不存在的企业应用 | 两类均计入“关联已删除企业应用”,不计入正常应用 |
| TC-CHANNEL-GROUP-DELETE-003 | 关联记录指向状态为`deleted`或已不存在的企业应用 | 两类均计入正常应用,删除弹窗不展示“关联已删除企业应用”;后台审计快照仍可保留其真实数量 |
| TC-CHANNEL-GROUP-DELETE-004 | 通道组存在正常/已删除应用关联、组内通道或等待供应商提交记录后确认删除 | 所有业务依赖只展示不阻止;后端将通道组状态置为`deleted`并写操作审计,不物理删除关联和历史记录 |
| TC-CHANNEL-GROUP-DELETE-005 | 删除通道组后查询通道组列表并发送新短信 | 默认列表不再显示该组,新短信选路不再选择该组 |
| TC-CHANNEL-GROUP-DELETE-006 | 删除通道组后查询历史发送/回执/审计,或按历史通道接入号处理上行 | 组内通道、应用关联、发送、回执和审计数据仍存在,历史链路可追溯 |
+10
View File
@@ -3314,3 +3314,13 @@ git diff --check
- 新通道组删除影响接口已出现在部署后Swagger路径中,未认证访问返回401;前端生产包包含“等待供应商提交结果”和历史数据保留完整文案。对真实PostgreSQL最近三个活动通道组只读执行同口径统计,均得到正常应用2、已删除应用0、组内通道3、等待供应商提交0;没有点击或调用确认删除。现有浏览器无登录会话,未绕过验证码或伪造登录态,登录后UI弹窗交互仍可作为后续人工验收项。
- 发布前数据库状态为9条active通道、连接状态9条connected;重启后6条active通道恢复`connected 1/1`3条富泷通道返回供应商`authentication / connect response status: auth failed`。本轮未修改这些通道的账号、密码或启停状态,仅保留真实失败状态并报告。部署后API/Gateway error级journal均为0。
- npm审计报告根项目3项high、API项目3项moderate和4项high;专用安全门禁确认PostCSS补丁、React Router RSC未使用和brace expansion边界有效,未执行可能破坏兼容性的自动升级。本次没有发送、补发或重投真实短信,没有修改企业余额、客户连接或任何真实通道配置。
## 2026-08-09 通道、签名与模板级联删除确认(本地未提交)
- 通道组删除弹窗不再展示“关联已删除企业应用”,继续展示关联正常企业应用、组内通道和等待供应商提交结果;后端已有真实影响统计及删除审计快照保持不变。
- 通道、签名和模板删除原因统一改为选填。签名存在关联模板、引流信息或未结束报备任务时分别出现“同时删除关联的模板”“同时删除引流信息”“同时结束关联的报备任务”;通道存在未结束报备任务时出现结束报备勾选项。发现的级联项必须全部勾选后页面才允许确认,后端也独立复核所有布尔选项,不能绕过前端直接删除。
- 客户端允许同步结束签名关联的未结束报备任务,但客户端专用预检不返回任务ID、状态或通道详情,页面只展示统一处理说明。运营端仍可查看真实任务ID和状态。
- 所有级联动作与主对象逻辑删除在同一个`Serializable`事务完成;关联模板和引流信息逻辑删除,过程态报备任务置为`abandoned`并逐条写`ChannelSignatureReportRecord`,子对象另写操作日志。通道删除后,同事务按剩余未删除通道重算受影响签名报备汇总;活动通道组、直接路由、活动连接及关联模板的活动发送任务仍保持硬阻断。
- 修正模板活动任务终态口径:`SmsSendTask``approved/rejected``SmsBatchTask``finished/canceled/rejected/failed/completed/cancelled`不再被误判为未结束任务;真实过程态任务继续阻止模板或签名级联删除。无需新增数据库字段或migration。
- 使用Node.js v24运行删除治理定向1 suite / 11 tests全部通过;排除此前已确认依赖本机Redis的`send-chain.service.spec.ts`后,API其余32 suites / 324 tests全部通过。API TypeScript build、前端TypeScript`--noEmit --incremental false`、Vite v8.1.5生产构建(2535 modules,仅既有约2.04MB单chunk提示)和`git diff --check`均通过。
- 本轮未连接或修改预生产数据库,未执行任何真实通道、签名、模板、引流信息或报备任务删除,未发送、补发或重投真实短信,未修改真实通道、企业余额或客户连接。代码按要求保持未提交、未推送、未部署;既有`api/tsconfig.build.tsbuildinfo`、根目录`tsconfig.tsbuildinfo``outputs/`和空文件`=`继续保护,不归因、不删除、不提交。