Files
junhong_cmp_fiber/openspec/specs/refund-asset-reset/spec.md
huang 95fc0b0a1b
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m16s
修复一些问题,主要是生效套餐
2026-05-12 10:32:38 +08:00

4.1 KiB

ADDED Requirements

Requirement: 退款后套餐精准失效

退款审批通过后,系统 SHALL 仅失效本次退款关联订单生成的套餐使用记录。若退款单传入 package_usage_id,系统 SHALL 优先失效该套餐使用记录,且该记录必须属于退款订单;若未传入 package_usage_id,系统 SHALL 失效该订单生成的全部可失效套餐使用记录。

Scenario: 精准失效单个套餐

  • WHEN 退款单包含 package_usage_id
  • THEN 系统 SHALL 将该套餐使用记录从 status IN (0,1,2) 更新为 status=4
  • AND 系统 SHALL 写入 refund_idrefund_no 快照

Scenario: 未指定套餐时失效订单套餐

  • WHEN 退款单未包含 package_usage_id
  • THEN 系统 SHALL 将该订单生成的所有 status IN (0,1,2) 套餐使用记录更新为 status=4

Scenario: 主套餐关联加油包失效

  • WHEN 被失效套餐为主套餐
  • THEN 系统 SHALL 将其关联的可失效加油包一并更新为 status=4

Requirement: 退款后待生效套餐接续

退款套餐失效后,系统 SHALL 按购买顺序尝试激活该资产队首待生效主套餐。系统 MUST NOT 跳过未满足实名条件的队首套餐。

Scenario: 立即生效套餐接续

  • WHEN 退款后资产无生效主套餐,且队首待生效主套餐 pending_realname_activation=false
  • THEN 系统 SHALL 激活该套餐,并按套餐 expiry_base 计算生效时间和过期时间

Scenario: 实名套餐已满足条件

  • WHEN 队首待生效主套餐 pending_realname_activation=true
  • AND 单卡已实名,或设备任意已绑定卡已实名
  • THEN 系统 SHALL 激活该套餐,并清除 pending_realname_activation

Scenario: 实名套餐未满足条件

  • WHEN 队首待生效主套餐 pending_realname_activation=true
  • AND 单卡未实名,或设备没有任何已绑定卡实名
  • THEN 系统 SHALL 保持该套餐待生效
  • AND 系统 MUST NOT 跳过该套餐激活后续待生效套餐

Requirement: 退款后必要时停机

套餐失效和接续激活完成后,系统 SHALL 检查资产是否仍有生效主套餐。仅当资产没有生效主套餐时,系统 SHALL 执行停机操作。

Scenario: 有接续套餐时不强停

  • WHEN 退款后成功接续待生效主套餐,或资产仍存在其他生效主套餐
  • THEN 系统 SHALL NOT 执行退款停机

Scenario: 无可用主套餐时停机

  • WHEN 退款后资产没有任何生效主套餐
  • THEN 单卡订单 SHALL 调用 StopResumeService.ManualStopCard(iccid)
  • AND 设备订单 SHALL 调用 DeviceService.StopDevice(deviceID)

Requirement: 退款不得重置资产世代和钱包

套餐退款不是资产退回库存。退款资产处理 MUST NOT 执行资产 generation+1、MUST NOT 清理个人客户绑定、MUST NOT 删除或重建资产钱包。资产世代重置和钱包重建仅属于换货/转新流程。

Scenario: 退款后保留资产钱包

  • WHEN 套餐退款审批通过
  • THEN 资产钱包 ID、余额和冻结余额 SHALL 保持不被退款资产处理重建或清零

Scenario: 退款后保留资产世代

  • WHEN 套餐退款审批通过
  • THEN IoT 卡或设备的 generation SHALL 不因退款资产处理变化

Requirement: 退款后处理标记

退款后资产处理成功完成后,系统 SHALL 将退款单 asset_reset 标记为 true。该字段为兼容字段,语义为“退款后资产处理是否完成”。

Scenario: 资产处理完成

  • WHEN 套餐失效、接续激活检查和必要停机处理完成
  • THEN 退款单 asset_reset SHALL 标记为 true

Requirement: 资产处理失败容错

资产处理 SHALL 在独立 Goroutine 中执行,失败不影响审批结果。

Scenario: 资产处理失败

  • WHEN 套餐失效、接续激活或生效套餐查询过程中发生错误
  • THEN 审批结果 SHALL NOT 受影响(已通过)
  • AND asset_reset SHALL 保持 false
  • AND 系统 SHALL 记录 Error 日志(含 refund_id 和错误信息)