收口审计治理与套餐任务进展

Constraint: 在线热修前必须保存当前迭代分支全部有效代码进展
Confidence: medium
Scope-risk: broad
Directive: 后续修改需保持审计事件与业务事务边界一致
Tested: git diff --cached --check
Not-tested: 未运行全量测试,提交用于切换分支前保存既有工作
This commit is contained in:
2026-08-05 14:30:54 +08:00
parent b3499adfca
commit 5e552d99bc
178 changed files with 16797 additions and 5674 deletions

View File

@@ -46,42 +46,42 @@
- [x] 5.8 迁移企业卡授权/回收纵向用例关联企业、owner shop、卡和授权记录并保持现有有效授权语义。【主简单写 + Application边界企业卡授权不迁移设备授权验证授权/撤销/重复/越权、卡活动和企业范围核对通过LSP 无诊断】
- [x] 5.9 迁移企业设备授权/回收纵向用例,关联企业、设备及实际随设备处理的绑定卡,保持现有授权语义。【主:复杂写或简单写事务脚本|边界:企业设备授权|不迁移:卡槽绑定规则|验证:多卡设备授权/撤销/越权、资源关系和企业活动核对通过LSP 无诊断】
- [x] 5.10 迁移个人客户资料、手机号和微信主体纵向用例,记录真实个人 actor不把普通查询或 Token 刷新误记为业务操作。【主:简单写 + Application边界个人客户身份资料不迁移资产绑定验证资料/手机号/微信变更、失败、凭据删除和 subject_detail 核对通过LSP 无诊断】
- [ ] 5.11 迁移个人客户卡/设备绑定、解绑和换货绑定迁移纵向用例,关联客户、资产和绑定记录。【主:简单写或复杂写 Application边界客户资产关系不迁移换货其他资金/套餐步骤|验证:绑定/解绑/迁移、资源快照、越权和多资源活动核对通过LSP 无诊断】
- [x] 5.11 迁移个人客户卡/设备绑定、解绑和换货绑定迁移纵向用例,关联客户、资产和绑定记录。【主:简单写或复杂写 Application边界客户资产关系不迁移换货其他资金/套餐步骤|验证:绑定/解绑/迁移、资源快照、越权和多资源活动核对通过LSP 无诊断】
## 6. 卡、设备、绑定、分配与换货迁移
- [ ] 6.1 迁移 IoT 卡创建/导入落库、基础资料、删除纵向用例,快照含 ID/ICCID/VirtualNo/MSISDN/运营商/店铺/系列/generation。【主简单写 + 旧 Service Adapter边界卡身份生命周期不迁移状态与外部命令验证创建/更新/删除、历史快照、凭据规则和旧资产写归零核对通过LSP 无诊断】
- [ ] 6.2 迁移 IoT 卡分配、回收和系列绑定纵向用例,关联分配记录、来源/目标店铺、系列和必要设备关系。【主:复杂写或简单写事务脚本|边界:卡归属与系列|不迁移:卡状态/Gateway验证分配/回收/拒绝、多资源、主体活动和旧写归零核对通过LSP 无诊断】
- [ ] 6.3 迁移 IoT 卡停复机、实名策略/状态、限速和人工刷新纵向用例,实际外部尝试写 Integration Log内部状态变化写 Audit Eventunknown 不伪装失败或成功。【主:复杂写 + Gateway Adapter边界卡状态与外部命令不迁移卡归属验证success/failed/denied/unknown、Integration/Audit 分界、主体结论和旧写归零核对通过LSP 无诊断】
- [ ] 6.4 迁移设备创建/导入落库、基础资料和删除纵向用例,快照含 ID/VirtualNo/IMEI/SN/型号/店铺/系列/generation。【主简单写 + 旧 Service Adapter边界设备身份生命周期不迁移状态、卡槽与 Gateway验证创建/更新/删除、历史快照和旧资产写归零核对通过LSP 无诊断】
- [ ] 6.5 迁移设备分配、回收和系列/实名策略纵向用例,关联分配记录、来源/目标店铺及实际连带卡。【主:复杂写或简单写事务脚本|边界:设备归属与策略|不迁移:设备外部命令|验证:分配/回收/策略、设备卡关系、主体活动和旧写归零核对通过LSP 无诊断】
- [ ] 6.6 迁移设备停复机、Wi-Fi、切卡模式、重启和重置纵向用例外部尝试写 Integration Log实际内部变化写 Audit Event。【主复杂写 + Gateway Adapter边界设备外部命令不迁移设备归属与卡槽绑定验证success/failed/unknown、设备时间线、安全结论和旧写归零核对通过LSP 无诊断】
- [ ] 6.7 迁移设备绑卡、解绑和当前卡切换纵向用例,把设备、目标卡、旧/新当前卡及每个 binding 作为一等资源,保存 slot/is_current。【主复杂写边界设备卡槽关系完整用例不迁移设备/卡其他状态机验证1-4 卡槽、旧新卡角色、资源双向时间线、事务和主体范围核对通过LSP 无诊断】
- [ ] 6.8 迁移单笔资产分配/回收纵向用例,关联分配记录、来源/目标店铺、设备及实际连带卡。【主:复杂写 Application边界单笔资产流转不迁移批量分配和企业授权验证卡/设备流转、多资源、越权和每资源时间线核对通过LSP 无诊断】
- [ ] 6.9 迁移批量设备分配纵向用例,批次根事件与每台实际变化设备/绑定卡子事件计数一致。【主:复杂写 + Application/Asynq边界批量设备流转不迁移其他批量任务验证success/partial/failed、根子计数、幂等和店铺范围核对通过LSP 无诊断】
- [ ] 6.10 迁移卡换货完整用例,记录换货单、旧/新卡 ICCID+VirtualNo、客户绑定、钱包/流水、套餐权益、店铺和状态变化。【主:复杂写 Domain/ApplicationOutbox/Query边界卡换货创建至完成/取消/迁移|不迁移:设备换货|验证:资金/套餐/客户迁移、失败回滚、多资源时间线和外部安全结论核对通过LSP 无诊断】
- [ ] 6.11 迁移设备换货完整用例,记录旧/新设备 VirtualNo+IMEI+SN、实际绑定卡/卡槽、客户绑定、钱包/流水、套餐权益、店铺和换货单。【主:复杂写 Domain/ApplicationOutbox/Query边界设备换货完整流程不迁移无关订单规则验证多卡设备换货、资金/套餐/客户迁移、失败回滚和所有资源时间线核对通过LSP 无诊断】
- [x] 6.1 迁移 IoT 卡创建/导入落库、基础资料、删除纵向用例,快照含 ID/ICCID/VirtualNo/MSISDN/运营商/店铺/系列/generation。【主简单写 + 旧 Service Adapter边界卡身份生命周期不迁移状态与外部命令验证创建/更新/删除、历史快照、凭据规则和旧资产写归零核对通过LSP 无诊断】
- [x] 6.2 迁移 IoT 卡分配、回收和系列绑定纵向用例,关联分配记录、来源/目标店铺、系列和必要设备关系。【主:复杂写或简单写事务脚本|边界:卡归属与系列|不迁移:卡状态/Gateway验证分配/回收/拒绝、多资源、主体活动和旧写归零核对通过LSP 无诊断】
- [x] 6.3 迁移 IoT 卡停复机、实名策略/状态、限速和人工刷新纵向用例,实际外部尝试写 Integration Log内部状态变化写 Audit Eventunknown 不伪装失败或成功。【主:复杂写 + Gateway Adapter边界卡状态与外部命令不迁移卡归属验证success/failed/denied/unknown、Integration/Audit 分界、主体结论和旧写归零核对通过LSP 无诊断】
- [x] 6.4 迁移设备创建/导入落库、基础资料和删除纵向用例,快照含 ID/VirtualNo/IMEI/SN/型号/店铺/系列/generation。【主简单写 + 旧 Service Adapter边界设备身份生命周期不迁移状态、卡槽与 Gateway验证创建/更新/删除、历史快照和旧资产写归零核对通过LSP 无诊断】
- [x] 6.5 迁移设备分配、回收和系列/实名策略纵向用例,关联分配记录、来源/目标店铺及实际连带卡。【主:复杂写或简单写事务脚本|边界:设备归属与策略|不迁移:设备外部命令|验证:分配/回收/策略、设备卡关系、主体活动和旧写归零核对通过LSP 无诊断】
- [x] 6.6 迁移设备停复机、Wi-Fi、切卡模式、重启和重置纵向用例外部尝试写 Integration Log实际内部变化写 Audit Event。【主复杂写 + Gateway Adapter边界设备外部命令不迁移设备归属与卡槽绑定验证success/failed/unknown、设备时间线、安全结论和旧写归零核对通过LSP 无诊断】
- [x] 6.7 迁移设备绑卡、解绑和当前卡切换纵向用例,把设备、目标卡、旧/新当前卡及每个 binding 作为一等资源,保存 slot/is_current。【主复杂写边界设备卡槽关系完整用例不迁移设备/卡其他状态机验证1-4 卡槽、旧新卡角色、资源双向时间线、事务和主体范围核对通过LSP 无诊断】
- [x] 6.8 迁移单笔资产分配/回收纵向用例,关联分配记录、来源/目标店铺、设备及实际连带卡。【主:复杂写 Application边界单笔资产流转不迁移批量分配和企业授权验证卡/设备流转、多资源、越权和每资源时间线核对通过LSP 无诊断】
- [x] 6.9 迁移批量设备分配纵向用例,批次根事件与每台实际变化设备/绑定卡子事件计数一致。【主:复杂写 + Application/Asynq边界批量设备流转不迁移其他批量任务验证success/partial/failed、根子计数、幂等和店铺范围核对通过LSP 无诊断】
- [x] 6.10 迁移卡换货完整用例,记录换货单、旧/新卡 ICCID+VirtualNo、客户绑定、钱包/流水、套餐权益、店铺和状态变化。【主:复杂写 Domain/ApplicationOutbox/Query边界卡换货创建至完成/取消/迁移|不迁移:设备换货|验证:资金/套餐/客户迁移、失败回滚、多资源时间线和外部安全结论核对通过LSP 无诊断】
- [x] 6.11 迁移设备换货完整用例,记录旧/新设备 VirtualNo+IMEI+SN、实际绑定卡/卡槽、客户绑定、钱包/流水、套餐权益、店铺和换货单。【主:复杂写 Domain/ApplicationOutbox/Query边界设备换货完整流程不迁移无关订单规则验证多卡设备换货、资金/套餐/客户迁移、失败回滚和所有资源时间线核对通过LSP 无诊断】
## 7. 套餐、交易与资金纵向迁移
- [ ] 7.1 迁移套餐系列、套餐商品、店铺系列/套餐分配、批量定价和关键价格配置纵向用例,关联店铺、系列、套餐和价格历史,保持现有上架/分配规则。【主:简单写 + Application边界套餐配置与授权不迁移套餐购买流程验证before/after、批量根子、店铺时间线、凭据规则和旧 account 借用写归零核对通过LSP 无诊断】
- [ ] 7.2 迁移套餐权益激活、排队、流量重置/扣减、退款失效、资产失效和换货迁移纵向用例,系统任务使用真实 actor权益、订单、套餐和资产作为独立资源。【主复杂写 Domain/ApplicationWorker/Outbox边界package_usage 生命周期|不迁移:套餐列表 Query验证状态条件、重复任务幂等、系统 actor、父子链路和资源时间线核对通过LSP 无诊断】
- [ ] 7.3 迁移订单创建、后台代购、C 端/OpenAPI 购买、取消、钱包支付和过期关闭纵向用例,关联买家/操作者、资产、套餐、金额、支付方式、钱包/流水和购买角色。【主:复杂写 Domain/ApplicationOutbox边界订单状态与支付准备不迁移订单只读列表验证各入口 actor、成功/拒绝/失败、资金同事务、系统过期和链路核对通过LSP 无诊断】
- [ ] 7.4 迁移支付创建、微信/支付宝/富友预下单、查单和回调确认纵向用例:每次外部尝试写 Integration Log实际改变支付/订单/充值事实时写 Audit Event关联支付单、业务单、渠道交易号和 correlation。【主复杂写 + Infrastructure Adapter边界支付外部与内部终态不迁移渠道协议重构验证success/unknown/迟到回调/重复回调、series/correlation、Domain Ledger 和时间线核对通过LSP 无诊断】
- [ ] 7.5 迁移退款申请、审批终态、钱包回充、佣金失效、套餐/资产后处理和通知纵向用例,关联退款、审批、订单、资产、钱包、原扣款/退款流水、佣金和套餐权益,资金事实与审计同事务。【主:复杂写 Domain/ApplicationOutbox/Integration边界退款完整业务链不迁移原路退款等未实现能力验证通过/拒绝/重提/重复终态/失败回滚、资金时间线和代理安全结论核对通过LSP 无诊断】
- [ ] 7.6 迁移个人资产充值和代理在线/线下充值纵向用例,关联充值单、提交人、店铺/资产、支付或审批、钱包、交易流水和自动购包;外部回调与系统恢复使用真实 actor。【主复杂写 Domain/ApplicationPayment/Approval/Outbox边界充值创建至入账不迁移新充值渠道验证在线/线下、回调/审批、重复入账、unknown、资金同事务和主体投影核对通过LSP 无诊断】
- [ ] 7.7 迁移代理主钱包订单扣款和预占/释放/完成纵向用例,关联订单、钱包、预占、唯一流水和余额前后值。【主:复杂写 Domain/ApplicationOutbox边界订单资金占用与扣款不迁移充值/退款/信用额度|验证:乐观锁/状态条件、唯一业务键、审计失败回滚和失败短事务核对通过LSP 无诊断】
- [ ] 7.8 迁移代理主钱包充值入账、人工调整、退款回充和信用额度纵向用例,逐项关联业务单、原流水/新流水和余额前后值。【主:复杂写 Domain/ApplicationOutbox边界代理钱包正向及回退资金不迁移资产钱包与佣金提现验证重复入账/退款上限/人工原因/信用变更、同事务和资金查询核对通过LSP 无诊断】
- [ ] 7.9 迁移卡/设备资产钱包充值、扣款、退款和换货迁移纵向用例,关联资产完整标识、钱包、业务单和唯一流水。【主:复杂写 Domain/Application边界资产钱包资金不迁移代理主钱包验证卡/设备、换货、重复业务键、余额前后值和资源时间线核对通过LSP 无诊断】
- [ ] 7.10 迁移佣金计算/入账/失效和提现申请/审批/驳回纵向用例,关联店铺、订单、系列、佣金记录、提现单、钱包/流水和金额状态。【主:复杂写 Domain/ApplicationWorker/Outbox边界佣金与提现完整状态机不迁移统计 Query验证计算幂等、审批终态、资金同事务、失败短事务和资金时间线核对通过LSP 无诊断】
- [x] 7.1 迁移套餐系列、套餐商品、店铺系列/套餐分配、批量定价和关键价格配置纵向用例,关联店铺、系列、套餐和价格历史,保持现有上架/分配规则。【主:简单写 + Application边界套餐配置与授权不迁移套餐购买流程验证before/after、批量根子、店铺时间线、凭据规则和旧 account 借用写归零核对通过LSP 无诊断】
- [x] 7.2 迁移套餐权益激活、排队、流量重置/扣减、退款失效、资产失效和换货迁移纵向用例,系统任务使用真实 actor权益、订单、套餐和资产作为独立资源。【主复杂写 Domain/ApplicationWorker/Outbox边界package_usage 生命周期|不迁移:套餐列表 Query验证状态条件、重复任务幂等、系统 actor、父子链路和资源时间线核对通过LSP 无诊断】
- [x] 7.3 迁移订单创建、后台代购、C 端/OpenAPI 购买、取消、钱包支付和过期关闭纵向用例,关联买家/操作者、资产、套餐、金额、支付方式、钱包/流水和购买角色。【主:复杂写 Domain/ApplicationOutbox边界订单状态与支付准备不迁移订单只读列表验证各入口 actor、成功/拒绝/失败、资金同事务、系统过期和链路核对通过LSP 无诊断】
- [x] 7.4 迁移支付创建、微信/支付宝/富友预下单、查单和回调确认纵向用例:每次外部尝试写 Integration Log实际改变支付/订单/充值事实时写 Audit Event关联支付单、业务单、渠道交易号和 correlation。【主复杂写 + Infrastructure Adapter边界支付外部与内部终态不迁移渠道协议重构验证success/unknown/迟到回调/重复回调、series/correlation、Domain Ledger 和时间线核对通过LSP 无诊断】
- [x] 7.5 迁移退款申请、审批终态、钱包回充、佣金失效、套餐/资产后处理和通知纵向用例,关联退款、审批、订单、资产、钱包、原扣款/退款流水、佣金和套餐权益,资金事实与审计同事务。【主:复杂写 Domain/ApplicationOutbox/Integration边界退款完整业务链不迁移原路退款等未实现能力验证通过/拒绝/重提/重复终态/失败回滚、资金时间线和代理安全结论核对通过LSP 无诊断】
- [x] 7.6 迁移个人资产充值和代理在线/线下充值纵向用例,关联充值单、提交人、店铺/资产、支付或审批、钱包、交易流水和自动购包;外部回调与系统恢复使用真实 actor。【主复杂写 Domain/ApplicationPayment/Approval/Outbox边界充值创建至入账不迁移新充值渠道验证在线/线下、回调/审批、重复入账、unknown、资金同事务和主体投影核对通过LSP 无诊断】
- [x] 7.7 迁移代理主钱包订单扣款和预占/释放/完成纵向用例,关联订单、钱包、预占、唯一流水和余额前后值。【主:复杂写 Domain/ApplicationOutbox边界订单资金占用与扣款不迁移充值/退款/信用额度|验证:乐观锁/状态条件、唯一业务键、审计失败回滚和失败短事务核对通过LSP 无诊断】
- [x] 7.8 迁移代理主钱包充值入账、人工调整、退款回充和信用额度纵向用例,逐项关联业务单、原流水/新流水和余额前后值。【主:复杂写 Domain/ApplicationOutbox边界代理钱包正向及回退资金不迁移资产钱包与佣金提现验证重复入账/退款上限/人工原因/信用变更、同事务和资金查询核对通过LSP 无诊断】
- [x] 7.9 迁移卡/设备资产钱包充值、扣款、退款和换货迁移纵向用例,关联资产完整标识、钱包、业务单和唯一流水。【主:复杂写 Domain/Application边界资产钱包资金不迁移代理主钱包验证卡/设备、换货、重复业务键、余额前后值和资源时间线核对通过LSP 无诊断】
- [x] 7.10 迁移佣金计算/入账/失效和提现申请/审批/驳回纵向用例,关联店铺、订单、系列、佣金记录、提现单、钱包/流水和金额状态。【主:复杂写 Domain/ApplicationWorker/Outbox边界佣金与提现完整状态机不迁移统计 Query验证计算幂等、审批终态、资金同事务、失败短事务和资金时间线核对通过LSP 无诊断】
## 8. 审批、配置、批量与自动入口迁移
- [ ] 8.1 迁移通用审批和企微申请提交、回调同步、主动恢复及终态分发纵向用例,记录真实提交人、外部系统/系统任务 actor、审批实例、业务单、Integration Log 和 Outbox不伪造本地审批人。【主复杂写 Domain/ApplicationWeCom Adapter/Outbox边界审批完整链路不迁移新审批引擎验证提交、unknown、回调、恢复、重复终态、actor/correlation 和资源时间线核对通过LSP 无诊断】
- [ ] 8.2 迁移支付配置、运营商、企微应用/成员/场景及其他关键连接配置纵向用例,记录配置身份、状态和“凭据是否已配置”,不记录 Secret、Token、AESKey、私钥或证书正文。【主简单写 + Infrastructure Adapter边界外部连接配置不迁移配置 UI 与渠道业务协议验证CRUD/启停/校验失败、同事务、凭据删除和平台完整业务字段核对通过LSP 无诊断】
- [ ] 8.3 迁移卡/设备导入、资产套餐批购、订单套餐失效和导出任务创建/取消纵向用例,记录任务、文件名/目标/操作者和批量根子结果;对象存储签名 URL 不入审计审计中心自身仍不提供导出。【主Application + AsynqObject Storage边界现有导入批量和业务导出任务动作不迁移导出 DataSource 内容|验证:结构化 payload、幂等、partial、凭据删除和任务/资源时间线核对通过LSP 无诊断】
- [ ] 8.4 迁移通知生成、投递、单条/全部已读和清理纵向用例,低风险写仍登记 action系统清理使用系统 actorAudit Event 不替代通知或 Outbox 投递事实。【主:简单写/Application + Worker边界通知状态变化不迁移通知查询验证人工/系统 actor、低风险默认展示、Outbox 幂等和资源关联核对通过LSP 无诊断】
- [ ] 8.5 迁移轮询配置、并发配置、告警规则、人工触发/取消和状态变化纵向用例;手动轮询表继续承担进度/结果,实际 Gateway 尝试写 Integration Log人工触发动作另写 Audit Event。【主Application + AdapterScheduler/Query边界轮询配置与人工动作不迁移删除手动任务表和普通运行查询验证配置/触发/拒绝、任务 ledger 保留、Integration/Audit 分界和 actor 核对通过LSP 无诊断】
- [x] 8.1 迁移通用审批和企微申请提交、回调同步、主动恢复及终态分发纵向用例,记录真实提交人、外部系统/系统任务 actor、审批实例、业务单、Integration Log 和 Outbox不伪造本地审批人。【主复杂写 Domain/ApplicationWeCom Adapter/Outbox边界审批完整链路不迁移新审批引擎验证提交、unknown、回调、恢复、重复终态、actor/correlation 和资源时间线核对通过LSP 无诊断】
- [x] 8.2 迁移支付配置、运营商、企微应用/成员/场景及其他关键连接配置纵向用例,记录配置身份、状态和“凭据是否已配置”,不记录 Secret、Token、AESKey、私钥或证书正文。【主简单写 + Infrastructure Adapter边界外部连接配置不迁移配置 UI 与渠道业务协议验证CRUD/启停/校验失败、同事务、凭据删除和平台完整业务字段核对通过LSP 无诊断】
- [x] 8.3 迁移卡/设备导入、资产套餐批购、订单套餐失效和导出任务创建/取消纵向用例,记录任务、文件名/目标/操作者和批量根子结果;对象存储签名 URL 不入审计审计中心自身仍不提供导出。【主Application + AsynqObject Storage边界现有导入批量和业务导出任务动作不迁移导出 DataSource 内容|验证:结构化 payload、幂等、partial、凭据删除和任务/资源时间线核对通过LSP 无诊断】
- [x] 8.4 迁移通知生成、投递、单条/全部已读和清理纵向用例,低风险写仍登记 action系统清理使用系统 actorAudit Event 不替代通知或 Outbox 投递事实。【主:简单写/Application + Worker边界通知状态变化不迁移通知查询验证人工/系统 actor、低风险默认展示、Outbox 幂等和资源关联核对通过LSP 无诊断】
- [x] 8.5 迁移轮询配置、并发配置、告警规则、人工触发/取消和状态变化纵向用例;手动轮询表继续承担进度/结果,实际 Gateway 尝试写 Integration Log人工触发动作另写 Audit Event。【主Application + AdapterScheduler/Query边界轮询配置与人工动作不迁移删除手动任务表和普通运行查询验证配置/触发/拒绝、任务 ledger 保留、Integration/Audit 分界和 actor 核对通过LSP 无诊断】
- [ ] 8.6 迁移支付、运营商实名和企微等外部 Callback 中实际改变内部事实的入口,使用 external actor无状态变化只保留 Integration Log。【主Application/Infrastructure Adapter边界当前外部回调不迁移渠道协议验证逐回调 action、幂等、资源解析、Integration/Audit 分界和链路核对通过LSP 无诊断】
- [ ] 8.7 迁移当前 Worker 中实际改变内部业务事实的入口,使用 system_task actor 并传播 correlation/parent纯投递或技术装配按清单 N/A。【主Application/Asynq边界当前 Worker 写入口不迁移Scheduler 与 Callback验证逐 Worker 覆盖、幂等、失败重试和未登记动作门禁 PASSLSP 无诊断】
- [ ] 8.8 迁移当前 Scheduler 中实际创建任务、改变配置/状态或产生业务事实的入口,使用 scheduled_job actor实施时以当前清单为准不硬编码历史数量。【主Application/Scheduler边界当前计划任务不迁移Worker 消费逻辑|验证:逐 Scheduler 覆盖、重复调度幂等、父子链路和 N/A 理由 PASSLSP 无诊断】

View File

@@ -4,7 +4,7 @@
七月迭代分支虽然仍保留旧 `enqueueActivationTask`,但已经具备更合适的本地接续边界:`ActivationService.ActivateNextPendingMainPackage` 负责载体锁、队首选择、条款快照、状态事务和提交后复机;实际激活事务还会原子追加 `card.observation.series.requested` Outbox。套餐状态推进本身是本地数据库用例不需要再经过一次 Asynq 才能执行。
本设计仅适用于 `Iteration/7-11`,不包含任何 `main` 分支兼容、纯 Asynq 热修或跨分支移植决策。
本设计仅适用于 `Iteration/7-11`,不包含跨分支兼容或移植决策。
## Goals / Non-Goals
@@ -18,7 +18,7 @@
**Non-Goals:**
-涉及 `main`,不生成可向 `main` cherry-pick 的修复提交
-提供跨分支兼容或移植方案
- 不新增套餐激活 Outbox 事件、消费者、迁移或队列类型。
- 不删除仍可能被其他旧入口使用的 `TaskTypePackageQueueActivation` 和 Handler只停止过期接续与孤儿恢复继续走该路径。
- 不修改购买、优先级分配、实名激活、流量扣减、退款失效和停复机规则。
@@ -106,12 +106,12 @@ Outbox 写入失败时套餐激活事务回滚,避免状态已生效但后续
1.`Iteration/7-11` 实施真实孤儿查询和同步接续调用。
2. 更新审计覆盖基线与功能总结,执行格式化、静态检查和 `go build ./...`
3. 用只读 SQL/查询计划验证候选公平性,用运行日志和数据库事实核验同步接续及卡观测 Outbox。
4. 形成七月分支专属 Lore commit该提交不面向 `main` 移植
4. 复核七月分支专属差异并保留在当前工作树,不创建提交
5. 发布七月迭代时观察至少两个轮询周期,确认真实孤儿收敛且卡观测 Outbox 正常投递。
### 回滚
- 无数据库迁移,回滚七月专属修复提交并重新部署 Worker。
- 无数据库迁移,发布后如需回滚,则回退七月专属修复代码并重新部署 Worker。
- 已正确激活的套餐保持业务事实,不执行反向 SQL。
- 回滚后出现孤儿时,使用带状态条件的单卡修复 SQL逐条处理。

View File

@@ -25,7 +25,7 @@
## Impact
- **适用分支**:仅 `Iteration/7-11`;本 Change 不描述、不实施、不引用 `main` 线上热修
- **适用分支**:仅 `Iteration/7-11`,按当前分支的同步接续与卡观测 Outbox 架构独立实施
- **架构通道**:主通道为套餐生命周期复杂写,沿用 `Polling Handler → Package Activation Service → GORM transaction`;辅助通道为 PostgreSQL 候选查询、Redis 载体锁和既有卡观测 Outbox。完整边界只覆盖“旧套餐过期后接续队首套餐及孤儿恢复”不迁移购买、实名、流量、退款和停复机用例。
- **主要代码**`internal/polling/package_activation_handler.go`、必要时最小调整 `internal/service/package/activation_service.go` 的结果日志;复用现有 `internal/infrastructure/cardobservation/series_event.go` 和公共 Outbox 装配。
- **数据库**:不新增表、字段、索引或迁移;只调整现有 `tb_package_usage` 查询和调用顺序。

View File

@@ -1,29 +1,29 @@
## 0. 七月分支基线与边界
- [ ] 0.1 在 `Iteration/7-11` 记录套餐激活相关代码、现有卡观测 Outbox 装配和工作树状态,确认本 Change 只覆盖“旧套餐过期后接续队首套餐及孤儿恢复”,不涉及 `main`、线上纯 Asynq 热修或其他套餐用例。验证:相关文件差异摘要不包含跨分支移植计划。
- [ ] 0.2 保存生产故障只读基线 `100/100/0`,准备真实孤儿候选 SQL和 `EXPLAIN (ANALYZE, BUFFERS)`;所有 SQL 仅允许读取。验证SQL 能区分占位记录、真实孤儿和每个载体的稳定队首。
- [ ] 0.3 增量更新 `.scratch/tech-global-audit/审计覆盖基线.md`Audit Event N/A、Domain Ledger N/A、Integration Log N/AOutbox 明确复用 `card.observation.series.requested` 且不新增事件类型。验证:四类公共能力均有明确决定。
- [x] 0.1 在 `Iteration/7-11` 记录套餐激活相关代码、现有卡观测 Outbox 装配和工作树状态,确认本 Change 只覆盖“旧套餐过期后接续队首套餐及孤儿恢复”,不涉及其他套餐用例。验证:相关文件差异摘要不包含跨分支移植计划。
- [x] 0.2 保存生产故障只读基线 `100/100/0`,准备真实孤儿候选 SQL和 `EXPLAIN (ANALYZE, BUFFERS)`;所有 SQL 仅允许读取。验证SQL 能区分占位记录、真实孤儿和每个载体的稳定队首。
- [x] 0.3 增量更新 `.scratch/tech-global-audit/审计覆盖基线.md`Audit Event N/A、Domain Ledger N/A、Integration Log N/AOutbox 明确复用 `card.observation.series.requested` 且不新增事件类型。验证:四类公共能力均有明确决定。
## 1. 真实孤儿公平恢复切片
- [ ] 1.1 修改 `findAndActivateOrphanPackages`:通过 GORM 执行 PostgreSQL CTE/窗口查询,先按卡或设备选择 `priority ASC, created_at ASC, id ASC` 的唯一队首,再用 `NOT EXISTS` 排除 `status IN (1,2)` 的占位载体,最后限制 100 个真实孤儿;删除逐条 `Count` 和 Go map 二次分组。验证:只读 SQL 在前 100 条全部被占位时仍返回窗口后的真实孤儿,同一载体只返回一条队首。
- [ ] 1.2 对每个真实孤儿直接调用 `ActivateNextPendingMainPackage`,根据 `activated bool` 和错误记录实际结果,不调用 `enqueueActivationTask`。验证:孤儿路径不存在 `package:queue:activation` 投递,锁冲突和条件未满足不记录成功。
- [x] 1.1 修改 `findAndActivateOrphanPackages`:通过 GORM 执行 PostgreSQL CTE/窗口查询,先按卡或设备选择 `priority ASC, created_at ASC, id ASC` 的唯一队首,再用 `NOT EXISTS` 排除 `status IN (1,2)` 的占位载体,最后限制 100 个真实孤儿;删除逐条 `Count` 和 Go map 二次分组。验证:只读 SQL 在前 100 条全部被占位时仍返回窗口后的真实孤儿,同一载体只返回一条队首。
- [x] 1.2 对每个真实孤儿直接调用 `ActivateNextPendingMainPackage`,根据 `activated bool` 和错误记录实际结果,不调用 `enqueueActivationTask`。验证:孤儿路径不存在 `package:queue:activation` 投递,锁冲突和条件未满足不记录成功。
- [ ] 1.3 执行候选 SQL和 `EXPLAIN (ANALYZE, BUFFERS)`,记录真实孤儿数量、执行耗时和扫描行数;没有性能证据时不新增索引。验证:候选查询无逐载体 N+1单轮最多返回 100 个载体。
## 2. 过期接续与 Outbox 一致性切片
- [ ] 2.1 修改 `processExpiredPackage`:事务内只提交旧主套餐过期和关联加油包失效,事务成功后直接调用 `ActivateNextPendingMainPackage`;删除该路径对 `activateNextPackage/enqueueActivationTask` 的调用。验证:旧状态未提交时不会执行新套餐激活,提交后进程退出可由孤儿扫描恢复。
- [ ] 2.2 核对同步接续成功事务继续调用 `appendActivationObservation`,并由现有 Writer 原子追加 `card.observation.series.requested`;不得新增套餐激活 Outbox 事件或消费者。验证:激活状态和卡观测事件同事务成功或回滚,稳定事件 ID仍基于 package usage ID。
- [ ] 2.3 收紧轮询日志:仅 `activated=true` 记录本轮成功;锁冲突、无队首、占位变化、等待实名和幂等分别记录明确结果。验证:日志包含载体类型、载体 ID、套餐使用记录或可定位的候选信息和触发来源。
- [x] 2.1 修改 `processExpiredPackage`:事务内只提交旧主套餐过期和关联加油包失效,事务成功后直接调用 `ActivateNextPendingMainPackage`;删除该路径对 `activateNextPackage/enqueueActivationTask` 的调用。验证:旧状态未提交时不会执行新套餐激活,提交后进程退出可由孤儿扫描恢复。
- [x] 2.2 核对同步接续成功事务继续调用 `appendActivationObservation`,并由现有 Writer 原子追加 `card.observation.series.requested`;不得新增套餐激活 Outbox 事件或消费者。验证:激活状态和卡观测事件同事务成功或回滚,稳定事件 ID仍基于 package usage ID。
- [x] 2.3 收紧轮询日志:仅 `activated=true` 记录本轮成功;锁冲突、无队首、占位变化、等待实名和幂等分别记录明确结果。验证:日志包含载体类型、载体 ID、套餐使用记录或可定位的候选信息和触发来源。
## 3. 七月分支验证与文档
- [ ] 3.1 对受影响 Go 文件执行 `gofmt`、现有静态检查和 `go build ./...`;按用户要求不新增、修改或运行自动化测试。验证:全量构建退出码为 0无临时调试标记。
- [ ] 3.2 使用只读数据库事实核验:真实孤儿进入候选、同步接续后队首变为 `status=1`、同一载体无第二条生效主套餐、对应卡观测 Outbox 与激活事务一致。验证:保存 SQL、预期和实际结果不执行批量修复。
- [ ] 3.3 新建 `docs/feature-505-package-activation-recovery/功能总结.md` 并更新 README 功能索引记录七月专属架构、根因、SQL、Outbox 一致性、发布观察、回滚和未执行自动化测试声明。验证:文档不出现 `main`、cherry-pick 或纯 Asynq 热修步骤。
- [ ] 3.4 复核七月分支差异并使用中文 Lore commit 提交修复。验证:提交不包含线上 `main` 提案或实现,可独立 revert`openspec validate fix-package-activation-starvation --strict` 通过。
- [x] 3.3 新建 `docs/feature-505-package-activation-recovery/功能总结.md` 并更新 README 功能索引记录七月专属架构、根因、SQL、Outbox 一致性、发布观察、回滚和未执行自动化测试声明。验证:文档只描述当前分支架构和发布步骤。
- [x] 3.4 复核七月分支差异并保留在当前工作树,不创建提交。验证:差异仅包含本 Change`openspec validate fix-package-activation-starvation --strict` 通过。
## 4. 七月迭代发布观察
- [ ] 4.1 部署前记录真实孤儿数量、最老等待时间、同载体重复生效检查和卡观测 Outbox 待投递状态部署后观察至少两个轮询周期。验证真实孤儿持续收敛、无重复生效、Outbox 正常投递。
- [ ] 4.2 准备回滚说明:无数据库迁移,仅 revert 七月专属修复提交并重新部署 Worker已正确激活的套餐不反向修改。验证说明包含观察停止条件和带状态保护的单卡人工恢复边界。
- [x] 4.2 准备回滚说明:无数据库迁移,发布后仅回退七月专属修复代码并重新部署 Worker已正确激活的套餐不反向修改。验证说明包含观察停止条件和带状态保护的单卡人工恢复边界。