## 1. 迁移与常量 - [x] 1.1 新增成对迁移(编号排在 238 之后):放宽核销 `IN (0..4)`、退款 `IN (1..7)`、扫码注册 `IN (0..3)`、资料资格 `IN (0..4)`、线下充值 `IN (1..7)` 的状态约束并更新列注释;佣金提现只更新列注释;同时放宽 `tb_approval_decision_delivery` 决策取值约束允许 `submission_failed`;down 恢复原约束。 - [x] 1.2 新增状态常量与中文名“审批提交失败”:核销 4、退款 7、扫码注册 3、资料资格 4、线下充值 7、佣金提现 5,同步模型注释与状态名称函数。 - [x] 1.3 `pkg/constants/approval.go` 新增 `ApprovalDecisionSubmissionFailed = "submission_failed"`。 ## 2. 审批核心发出提交失败决策 - [x] 2.1 `markSubmissionState` 在状态 7 分支、实例更新成功后,同一事务内依次调用 `DecisionDeliveryWriter.Create` 与 `TerminalEventWriter.Append` 写 `submission_failed`(事件号 `approval:{实例ID}:submission_failed`,事件结构不加字段);状态 8 不发。`ApprovalContextRepository` 注入两个写入器并修改启动装配。 - [x] 2.2 核对 `approval_submission_consumer.go` 表单构造失败与企微明确拒绝两处均经该分支发出决策。 - [x] 2.3 `TerminalDecisionConsumer.Consume` 对 `submission_failed` 单独放行,`StatusForDecision` 与 `ApplyDecision` 不改,渠道回调仍拒绝该值。 - [x] 2.4 六个消费者处理 `submission_failed` 时按实例读取企微审批上下文 `last_error`,脱敏后写入终态原因与审计。 ## 3. M13 退款关闭类终态定位 - [x] 3.1 `internal/service/refund/approval_decision.go` 的 `applyClosedDecision` 改为 `ResolveRefundInTx` 定位,再按 `target.ID` 对退款单加行锁;其余逻辑不变。 ## 4. 六个业务消费者接入(同一次交付) - [x] 4.1 核销:照 `applyClosed` 实现 `applySubmitFailed`(确认实例为 7、只处理最新尝试、释放全部预占、0→4 条件更新、终态原因、审计);`ValidateApplicationResubmit` 允许状态 4 重提。 - [x] 4.2 退款:新增提交失败分支,用 `ResolveRefundInTx` 定位,待审批→7 条件更新、记录原因、审计;状态 7 加入 `RefundResubmittableStatuses()`,不加入 `RefundActiveStatuses()`。 - [x] 4.3 扫码注册代理:0→3,不创建实体,审计。 - [x] 4.4 线下充值:待审批→7,不入账,审计。 - [x] 4.5 佣金提现:同事务释放冻结并记录释放时间,待审核→5,审计;`Resubmit` 扩展为允许状态 5,按新金额重新冻结。 - [x] 4.6 提现资料资格:0→4,审计;确认可提交新资料版本、不影响已通过版本。 ## 5. 恢复入口与投影 - [x] 5.1 核销、退款、扫码注册三处恢复入口的提交失败 replay 分支改为拒绝“审批提交失败为终态,请重新发起”;`recoverable` 对新状态返回 false。 - [x] 5.2 核销列表与详情按最新审批实例批量读取企微上下文,填充提交状态、名称、脱敏摘要、可恢复、最近恢复结果与时间。 - [x] 5.3 六个业务的列表筛选、接口字段说明、导出状态格式化(含 `internal/exporter/refund_scene.go`)加入新状态;实现时 `grep` 各状态常量逐处核对。 ## 6. 文档与测试环境验证 - [x] 6.1 `gofmt`、`go build ./cmd/api ./cmd/worker`、`go run cmd/gendocs/main.go`。 - [x] 6.2 在 `junhong_cmp_test` 执行新迁移(up、down、再 up)并确认旧数据不受影响。 - [ ] 6.3 (测试环境已验证核销、退款、扫码注册、资料资格、线下充值五类;佣金提现因测试环境未配置 commission_withdrawal_approval 审批场景无法创建审批,待配置后补验)按 ENG-TEST-001 用缺必填控件映射对六个业务类型各构造一次提交失败:业务单变为“审批提交失败”、占用释放(核销预占、提现冻结与钱包流水)、审计写入、列表筛选导出可见;恢复被拒;重新发起生成新尝试与新审批;同一事件重复投递结果不变。 - [x] 6.4 构造提交结果未知的实例,业务单保持审批中。 - [x] 6.5 核对每个提交失败事件都有决策投递记录且最终为成功;模拟渠道回调带 `submission_failed` 被拒、实例状态不变。 - [x] 6.6 M13:对尝试模式退款分别用模拟企微撤销、拒绝、删除终态事件触发,退款单变为已拒绝、原因与审计正确、资产可换货;对其重新发起生成新审批;模拟卡管未知的企微单号回调只留痕;“通过”“通过后撤销”与早期 `business_id = 退款单 ID` 的数据回归不变。 - [x] 6.7 核销列表与详情提交状态与测试库一致,无上下文申请正常返回,无逐行查询。 - [ ] 6.8 只读统计测试库“实例 7 或已终态、业务单仍审批中”的存量,需要时写一次性补数据脚本,经确认后执行。 - [ ] 6.9 运行 `openspec validate --all` 与 `./scripts/context-health.sh`。