Files
junhong_cmp_fiber/.planning/phases/04-refund-pay-ops/04-DISCUSSION-LOG.md
huang e81d3a58ad
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m6s
docs(04): capture phase context
2026-03-28 14:24:25 +08:00

201 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Phase 4: 退款 + 支付 + 运营修复 - Discussion Log
> **Audit trail only.** Do not use as input to planning, research, or execution agents.
> Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.
**Date:** 2026-03-28
**Phase:** 04-退款-支付-运营修复
**Areas discussed:** Plan 分组策略, 退款状态机细节, OPS-01 卡/设备 status=4 触发路径, PAY-04 平台代购的具体场景
---
## Plan 分组策略
| Option | Description | Selected |
|--------|-------------|----------|
| REFUND 一个 Plan | DB迁移+Model+Store+Service+Handler+路由全部一次完成 | ✓ |
| REFUND 拆两个 Plan | Plan A: DB迁移+基础层Plan B: 功能层 | |
**User's choice:** 一个 Plan推荐
---
| Option | Description | Selected |
|--------|-------------|----------|
| PAY + OPS 合并一个 Plan | PAY 和 OPS 彼此独立,合并一个 Plan 减少上下文切换 | ✓ |
| PAY 和 OPS 各自独立 | 两个 Plan粒度更细 | |
**User's choice:** PAY + OPS 合并一个 Plan推荐
---
| Option | Description | Selected |
|--------|-------------|----------|
| 内嵌同步Approve 事务内) | 退款审批和佣金扣减原子,失败可回滚 | ✓ |
| 异步 Asynq 任务 | 入队 TaskTypeRefundCommissionDeduct审批响应快 | |
**User's choice:** 内嵌同步(推荐)
---
| Option | Description | Selected |
|--------|-------------|----------|
| REFUND-01 先行,再做 REFUND-02+03 | 与 Phase 3 DEVICE 基础层先行规范一致 | ✓ |
| 一次性全部完成 | DB迁移先执行所有上层代码同时完成 | |
**User's choice:** REFUND-01 先行,再做 REFUND-02+03推荐
---
| Option | Description | Selected |
|--------|-------------|----------|
| 不需要OPS-01 独立实现 | OPS-01 是套餐激活/到期直接更新 status不经过 StopResumeCallback | ✓ |
| 需要,提前将 CLEAN-06 并入本阶段 | 一并修复 bootstrap 注入 | |
**Notes:** 用户对 CLEAN-06 和 OPS-01 的关系有疑问确认两者独立后选择不提前。CLEAN-06 保留在 Phase 5。
---
## 退款状态机细节
| Option | Description | Selected |
|--------|-------------|----------|
| 审批人退回 | 审批人退回申请人(信息不全/待补充等),返回 returned 状态,申请人可重提 | ✓ |
| 申请人自撤回 | 申请人主动撤销,运营后可重提 | |
**User's choice:** 审批人退回(推荐)
---
| Option | Description | Selected |
|--------|-------------|----------|
| RF + 时间戳 + 随机数 | 独立生成,不关联订单号 | |
| 基于订单号迭代 | {order_no}-RF{seq}关联清晰seq 解决冲突 | ✓ |
**User's choice:** 基于订单号迭代,冲突解法用 {order_no}-RF{seq}
---
| Option | Description | Selected |
|--------|-------------|----------|
| 允许多次退款 | 同一订单可有多条退款记录,审批退款总额不超过实收金额 | |
| 同时只有一个待处理申请 | 上一次退款完成前不允许新申请 | ✓ |
**User's choice:** 同一订单同时只能有一个待处理的退款申请(推荐)
---
| Option | Description | Selected |
|--------|-------------|----------|
| 可修改金额 | 审批人可调整 approved_refund_amount以此为佣金扣减基准 | ✓ |
| 只能审批全额 | 简化 Approve 逻辑 | |
**User's choice:** 可修改金额(推荐)
---
| Option | Description | Selected |
|--------|-------------|----------|
| amount * approvedRefund / actualReceivedint64 | 先乘后除,禁用 float64 | ✓ |
| 先确认字段含义再决定 | — | |
**Notes:** 用户初始想先确认字段含义。解释了 actual_received_amount实收/ approved_refund_amount审批退款额以及"先乘后除"的整数精度含义后确认使用 int64 算法。
---
| Option | Description | Selected |
|--------|-------------|----------|
| 是,更新 payment_status=4 | 审批通过同时更新订单状态 | ✓ |
| 不更新订单状态 | 退款表独立记录 | |
**User's choice:** 是,更新 payment_status=4
---
## OPS-01 卡/设备 status=4 触发路径
| Option | Description | Selected |
|--------|-------------|----------|
| 事务内同步更新 | 套餐激活和卡状态更新原子,失败可回滚 | ✓ |
| 异步 goroutine | 套餐激活后异步更新卡/设备状态 | |
**User's choice:** 事务内同步更新(推荐)
---
| Option | Description | Selected |
|--------|-------------|----------|
| activateNextMainPackage 后检查 active/pending count | 在现有到期处理循环内,激活下一个失败时检查剩余套餐数量 | ✓ |
| 独立轮询任务定期检查 | 新建 Asynq 定时任务扫描无 active 套餐的卡/设备 | |
**User's choice:** 调用 activateNextMainPackage 后检查无剩余 active/pending 套餐(推荐)
---
| Option | Description | Selected |
|--------|-------------|----------|
| 分开更新两张表 | 根据 carrierType 分支到 iot_card/device 各自的 Store | ✓ |
| 统一封装 UpdateCarrierStatus() | 新建封装方法处理两种类型 | |
**User's choice:** 分开更新两张表(推荐)
---
| Option | Description | Selected |
|--------|-------------|----------|
| 直接输出 DB 字段,删除所有映射函数 | DB 存的 payment_status 与管理端完全一致1/2/3/4 | ✓ |
| 先确认 DB 存在的实际值 | 不确定 DB 值是否真的 1/2/3/4 | |
**User's choice:** 是,直接输出 DB 字段,删除所有映射函数
---
## PAY-04 平台代购的具体场景
| Option | Description | Selected |
|--------|-------------|----------|
| 仅 CreateLegacy | 规格书指定 | |
| 仅 CreateAdminOrder | Handler 实际调用的是 CreateAdminOrderCreateLegacy 已废弃 | ✓ |
**Notes:** 用户指出 CreateLegacy 已废弃,讨论后确认修改目标为 CreateAdminOrder。规格书中的引用有误这是本次讨论中最重要的一个勘误。
---
| Option | Description | Selected |
|--------|-------------|----------|
| 资产所属代理的钱包(*resourceShopID | 平台帮代理买,用代理自己的钱包 | ✓ |
| 平台自己的测试钱包 | 平台先垫付 | |
**User's choice:** 资产所属代理的钱包(*resourceShopID推荐
---
| Option | Description | Selected |
|--------|-------------|----------|
| purchaseRole=purchased_by_platform, operatorType=platform | 使用已有枚举 | ✓ |
| purchaseRole=self_purchase | 按代理自购处理 | |
**User's choice:** purchaseRole=purchased_by_platform, operatorType=platform推荐
---
| Option | Description | Selected |
|--------|-------------|----------|
| 与代理自购相同sellerCostPrice=资产所属代理成本价) | 上下级佣金链照常计算 | ✓ |
| sellerCostPrice=0不计佣金差 | 平台代购无差价 | |
**Notes:** 用户初始对 sellerCostPrice 含义不清楚,解释了佣金差价逻辑后确认:平台代购等同于代理自购,佣金链正常计算。
---
## the Agent's Discretion
- 富友支付 WxPreCreate 调用时的 goodsDesc 字段内容
- 退款 Store 层具体查询方法实现
- status=3/4 更新时的日志内容
- 富友 DTO 字段命名(参考 WechatPayJSAPIResponse 风格)
## Deferred Ideas
None — discussion stayed within phase scope.