Files
junhong_cmp_fiber/openspec/changes/add-commission-clawback-records/design.md
break 370fd3e67f
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 10m49s
update
2026-09-03 09:28:28 +08:00

2.4 KiB

Context

退款和佣金终态可能异步到达,回溯必须等待原佣金事实且不能修改其历史记录。

Decisions

  • 回溯表以退款+原佣金唯一,保存负数快照;退款消费者等待佣金终态再可靠重试。
  • 在钱包事务内先处理待审提现释放,再插入回溯和扣款流水;唯一约束保证重放安全。

生成、资金与读侧契约

退款事件消费

  • 退款完成可靠事件以 refund_idorder_id 进入回溯用例;锁定退款、订单和佣金终态。原订单佣金未终态时不写“无需回溯”,仅保留可重试事件;终态无佣金时写退款已处理且无需回溯的审计;换货事件不进入本用例。
  • 查询原订单全部可回溯佣金,按稳定顺序计算。全额退款回溯每条剩余可回溯金额;部分退款以 refund_amount / frozen_actual_paid_amount 计算,每条向下取整,最后一条仅补足总额舍入差且不得超过该条剩余可回溯余额。冻结实收金额缺失或非正时记录可恢复失败,不以订单标价替代。
  • 新表以 (refund_id, original_commission_id) 唯一,保存负数金额、原佣金/订单/退款快照、不可提现标识、生成时间;唯一冲突视为已生成,禁止第二次扣款。

钱包与提现原子边界

  • 在同一钱包事务内,先锁定代理佣金钱包和所有待审核/审批中的提现申请;拒绝这些申请、释放其冻结余额并保存“退款回溯优先”原因,然后插入所有回溯明细和负数佣金钱包流水。允许钱包余额低于零。
  • 原佣金记录、历史发放金额和已提现完成事实不更新、不删除;回溯是独立负数事实。事务任一步失败时不释放提现、不写部分回溯或部分流水,可靠事件保留重试。

查询与导出

  • 扩展佣金明细列表/详情:原佣金返回 clawback_records 摘要,回溯明细返回 original_commission_id、退款单号、负数金额、不可提现、回溯后实际钱包余额和生成时间。关联查询先应用既有佣金数据范围,再按关联 ID 查询;越权不泄露存在性。
  • 导出每条原佣金和回溯明细各一行,冻结筛选、操作者、可见范围和生成时间;金额保持分,展示层转换元不得改变负数或余额事实。

Migration Plan

新增成对迁移;隔离库验证全额/部分、舍入、佣金延迟、重复事件、提现释放、负余额及 up/down/up。