Files
邹进 6298a9061f fix: 第1批 M8、M13、M14 审批提交失败终态与退款关闭类终态定位
- 审批核心在实例进入提交失败的同一事务内写 submission_failed 决策投递与终态事件,消费入口单独放行
- 核销(4)、退款(7)、扫码注册(3)、资料资格(4)、线下充值(7)、佣金提现(5)新增“审批提交失败”终态并释放预占/冻结
- 三处恢复入口不再重放提交失败;退款关闭类终态按审批尝试定位退款单(M13)
- 核销列表与详情批量返回审批提交状态;筛选、字段说明、状态名称、退款导出加入新状态
- 迁移 000239 放宽五张业务表状态约束与决策投递取值约束(测试库已执行 up/down/up)
- OpenSpec Change fix-approval-submission-failure-terminal:18/26,测试部署后端到端验证与存量补数据待完成
2026-10-12 00:03:46 +09:00

8.2 KiB
Raw Blame History

MODIFIED Requirements

Requirement: 订单、退款与换货状态门禁

系统 SHALL 仅允许待支付订单取消;退款申请按待审批、已通过、已拒绝、已退回、原路退款处理中、原路退款失败、审批提交失败流转,仅已拒绝、已退回、原路退款失败和审批提交失败申请可修改并重新提交;换货按待填写信息、待发货、已发货、已完成或已取消流转,并拒绝与当前状态或流程类型不匹配的操作。处于待审批、原路退款处理中或原路退款失败的退款申请 MUST 阻止同一订单创建新的退款申请,且 MUST NOT 被再次推进为新的审批实例或第二次渠道退款。已拒绝与审批提交失败的退款申请为终态,MUST NOT 阻止同一订单创建新的退款申请,也 MUST NOT 阻止该资产换货。

Scenario: 重复推进终态

  • GIVEN 退款或换货已进入不允许当前操作的状态
  • WHEN 再次审批、发货、完成、取消或重新提交
  • THEN 系统返回状态冲突且不重复改变资产、余额或业务状态

Scenario: 原路退款失败后重提

  • WHEN 退款申请处于原路退款失败状态且调用方在其数据范围内修改材料后重新提交
  • THEN 系统新增一条审批尝试记录与一个新的企业微信审批实例并使申请回到待审批,历史尝试与已提交的渠道退款不被覆盖

Scenario: 企业微信通过后撤销的申请被再次推进

  • GIVEN 退款申请已记录企业微信通过后撤销的审批异常
  • WHEN 调用者再次提交或重提该申请
  • THEN 系统返回状态冲突,不恢复套餐权益、不取消已提交的渠道退款且不自动重提

Scenario: 审批提交失败的退款不阻断换货

  • GIVEN 资产的退款申请处于审批提交失败
  • WHEN 调用方为该资产发起换货
  • THEN 系统不因该退款申请拒绝换货

Requirement: 企业微信唯一终审与审批尝试重提

退款申请 SHALL 保存退款原因、冻结实收金额、唯一关联套餐及其使用情况、方式、金额和当次材料快照。超级管理员、平台用户和代理可在各自订单数据范围内创建、修改并重提未成功申请;企业微信是唯一终审,本地 MUST NOT 人工通过、拒绝或退回已关联审批实例的申请。每次创建或重提 MUST 新增一条不可变的审批尝试记录,并以该尝试记录作为通用审批业务标识;同一申请每次提交各自持有独立审批实例,历史尝试材料与审批结果不被覆盖。退款单 SHALL 仅保存最新尝试与最新审批实例引用用于展示。

同一订单同时至多存在一张待审批、原路退款处理中或原路退款失败的退款申请。企业微信驳回、撤销或删除待审批申请后,系统 MUST 将退款申请置为已拒绝(终态),拒绝原因分别为“企业微信审批已拒绝”“企业微信审批已撤销”“企业微信审批已删除”,并写审计;要再退款须在卡管对该申请重新发起,生成新的审批尝试与新的企业微信审批。企业微信侧对已驳回或已撤销审批重新提交产生的新审批单号,系统 MUST NOT 关联到任何退款申请,只按既有“未关联本系统业务,已忽略”留痕。原路退款明确失败后可修改未成功申请的金额、原因、方式、收款信息和附件并重提;每次重提必须新建审批实例及快照。

审批核心对最新审批实例发出 submission_failed 决策时,系统 MUST 确认审批实例仍为提交失败,将退款申请从待审批条件更新为审批提交失败(终态),记录脱敏失败原因并写审计,按事件幂等;该申请 MUST 可在卡管重新发起,MUST NOT 再通过恢复入口重放原提交。审批结果未知时申请保持在途,使用既有查询与恢复闭环,不得另建或重提。企业微信通过后撤销时不回滚套餐失效或已启动退款,标记审批异常并禁止自动重提。

审批终态(含通过、驳回、撤销、删除、通过后撤销与提交失败)MUST 以审批实例标识判别业务归属:先按审批尝试记录标识与审批实例匹配,未命中时按退款申请标识与审批实例匹配以兼容尚未切换到尝试模式的存量申请,两者均不匹配时返回稳定冲突错误,不得回落到任一候选业务单。定位后 MUST 对退款申请加行锁再推进状态。

Scenario: 审批通过前结果未知

  • WHEN 企业微信提交成功性或最终结果暂时未知
  • THEN 申请保持在途且订单不得创建第二张活动申请,系统通过既有恢复机制确认结果

Scenario: 未成功申请重提新建实例

  • GIVEN 退款申请处于已拒绝、已退回、原路退款失败或审批提交失败状态且无审批异常
  • WHEN 调用者修改材料后重新提交
  • THEN 系统在同一事务新增审批尝试记录并创建新的企业微信审批实例,原尝试记录与历史审批结果保持不变

Scenario: 尝试模式申请被企业微信撤销

  • GIVEN 退款申请以审批尝试记录作为审批业务标识,且处于待审批
  • WHEN 企业微信对该审批返回撤销、拒绝或删除
  • THEN 系统按审批尝试定位到该退款申请,将其置为已拒绝并记录对应原因与审计,该资产随后可换货

Scenario: 企业微信侧重新提交不关联

  • WHEN 企业微信回调一个卡管未创建的审批单号(企微侧对已驳回或已撤销审批的重新提交)
  • THEN 系统不关联任何退款申请,只留痕“未关联本系统业务,已忽略”

Scenario: 审批提交失败

  • WHEN 待审批退款申请的最新审批实例提交企微失败
  • THEN 退款申请变为审批提交失败并写审计,列表、筛选、导出显示该状态;重复投递结果不变

Scenario: 存量申请审批终态仍被消费

  • GIVEN 退款申请由本能力上线前创建,其审批实例的业务标识指向退款申请本身
  • WHEN 该审批实例到达通过或关闭终态
  • THEN 系统按审批实例标识匹配到该退款申请并幂等推进,不按尝试模式误判为不存在

Scenario: 已关联实例的本地人工终审

  • GIVEN 退款申请已关联审批实例
  • WHEN 后台账号调用本地通过、拒绝或退回入口
  • THEN 系统拒绝该操作且不改变退款申请与订单状态

Scenario: 存量无实例待审批申请仍可终结

  • GIVEN 退款申请未关联任何审批实例且处于待审批状态
  • WHEN 后台账号在既有开关开放时调用本地通过、拒绝或退回入口
  • THEN 系统按既有语义终结该申请,不要求该申请先接入企业微信审批

Requirement: 退款原审批实例可受控恢复

系统 SHALL 提供 POST /api/admin/refunds/{id}/recover-approval,允许既有退款管理范围内的超级管理员、平台用户和代理恢复仍处于待审批的退款最新审批实例;企业账号拒绝,越权与不存在不可区分。恢复 MUST 复用原审批实例及 approval:{instance_id}:submission 稳定提交事实,不得新增审批尝试/实例、修改冻结退款材料或触发退款、订单、套餐与资金动作。已有 sp_no 只查询同步,结果未知只确认;审批实例为提交失败时 MUST 返回“审批提交失败为终态,请重新发起”,MUST NOT 重放原提交事件。审批终态、审批提交失败、原路退款处理中或渠道退款失败 MUST 返回状态冲突。审批提交失败的退款申请 recoverable MUST 为 false。历史快照缺失新增键时,只能从关联不可变审批尝试补齐缺失值并写脱敏审计。

Scenario: 恢复入口只处理原审批事实

  • WHEN 授权账号请求恢复待审批退款
  • THEN 系统按最新尝试与实例关联选择恢复分支,列表/详情返回提交状态、可恢复标记、安全失败摘要和最近恢复时间,重复或并发请求至多一次改变提交事实。

Scenario: 提交失败不可恢复

  • WHEN 授权账号对审批实例已提交失败的退款申请请求恢复
  • THEN 系统返回“审批提交失败为终态,请重新发起”,不重放提交事件、不改变审批实例