重构用的提案,现在不敢跑
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 49s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 49s
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
## REMOVED Requirements
|
||||
|
||||
### Requirement: 资产充值关联支付配置
|
||||
**Reason**: `tb_asset_recharge_record` 表删除,支付配置关联迁移至 `tb_payment.payment_config_id`。
|
||||
**Migration**: 查询支付配置时从 `tb_payment` 读取,`PaymentStore.GetByPaymentNo()` 返回含 `payment_config_id` 的完整记录。
|
||||
|
||||
### Requirement: 资产充值表结构变更
|
||||
**Reason**: `tb_asset_recharge_record` 表重命名为 `tb_asset_recharge_record_archive` 并停止写入,相关表结构变更不再需要维护。
|
||||
**Migration**: 新的充值数据结构参见 `recharge-order` spec(`tb_recharge_order`)和 `payment-record` spec(`tb_payment`)。
|
||||
|
||||
### Requirement: 资产充值回调按配置验签
|
||||
**Reason**: 充值回调路由改为通过 `tb_payment` 查找配置,验签逻辑迁移至 `payment-record` spec 的支付路由统一需求。
|
||||
**Migration**: 回调处理查 `tb_payment.payment_config_id` 加载对应配置验签,与原逻辑等价。
|
||||
|
||||
### Requirement: 资产充值记录扩展字段(操作人与代际)
|
||||
**Reason**: 这些字段(operator_type、generation)迁移至 `tb_recharge_order` 表,继续有效。
|
||||
**Migration**: `tb_recharge_order.operator_type` 和 `tb_recharge_order.generation` 字段语义不变,字段值枚举不变。
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 旧表在验证完成后删除
|
||||
系统 SHALL 在所有新功能验证通过后,作为最后一步执行 `DROP TABLE tb_asset_recharge_record`。迁移期间旧表保留但不写入,仅用于人工对照核查。
|
||||
|
||||
#### Scenario: 旧表无新写入
|
||||
- **WHEN** 新代码部署完成后
|
||||
- **THEN** `tb_asset_recharge_record` 的 updated_at 最新记录时间早于部署时间,确认无新写入
|
||||
|
||||
#### Scenario: DROP 旧表
|
||||
- **WHEN** 所有验证任务通过(tasks.md 第 11 组全部完成)
|
||||
- **THEN** 执行迁移文件 DROP TABLE,旧表彻底删除
|
||||
@@ -0,0 +1,33 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: D2 套餐订单列表接口
|
||||
`/api/c/v1/orders` 接口 SHALL 保持不变,仅查询 `tb_order` 返回套餐购买订单。充值订单通过独立接口 `/api/c/v1/recharge-orders` 展示,两者不混合。
|
||||
|
||||
#### Scenario: 订单列表只返回套餐订单
|
||||
- **WHEN** 用户查询某张卡的订单列表
|
||||
- **THEN** 仅返回该卡下的套餐订单(来自 `tb_order`),不包含充值订单
|
||||
- **THEN** 响应结构与原有接口完全兼容,无新增字段
|
||||
|
||||
### Requirement: AutoPurchaseAfterRecharge 异步任务
|
||||
auto_purchase 任务 SHALL 从 `tb_recharge_order` 读取 linked_package_ids,执行完成后更新 `tb_recharge_order.auto_purchase_status`,同时创建套餐订单(`tb_order`)和对应的 `tb_payment`(payment_method=wallet)。不再读取 `tb_asset_recharge_record`。
|
||||
|
||||
#### Scenario: 自动购包成功写入新表
|
||||
- **WHEN** auto_purchase 任务从 `tb_recharge_order` 获取 linked_package_ids 并完成购包
|
||||
- **THEN** 创建 `tb_order`(type=single_card/device,payment_status=2)
|
||||
- **THEN** 创建 `tb_payment`(payment_method=wallet,status=2,关联新订单)
|
||||
- **THEN** `tb_recharge_order.auto_purchase_status` 更新为 success
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: D1 下单幂等恢复
|
||||
系统 SHALL 在幂等键命中且对应充值订单为待支付状态时,返回已有充值订单信息(含 payment_config 引导),而非返回错误 "订单正在创建中"。
|
||||
|
||||
#### Scenario: 幂等键命中且订单待支付
|
||||
- **WHEN** 用户重复发起下单请求,Redis 幂等键已存在且值为 recharge_order_no
|
||||
- **THEN** 查询 `tb_recharge_order`,status=1(待支付)
|
||||
- **THEN** 接口返回已有充值订单信息,HTTP 200,包含 `idempotent: true` 标志
|
||||
- **THEN** 前端可凭此引导用户拉起已有支付而非展示报错
|
||||
|
||||
#### Scenario: 幂等键命中但订单已支付或关闭
|
||||
- **WHEN** 幂等键存在,但对应充值订单 status=2/3(已支付或已关闭)
|
||||
- **THEN** 删除 Redis 幂等键,允许重新发起下单
|
||||
@@ -0,0 +1,14 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: 强充检查结果对客户端透出
|
||||
强充判断逻辑 SHALL 不变(检查余额是否低于阈值),但触发强充后的创建流程 SHALL 写入 `tb_recharge_order` + `tb_payment`,不再写入 `tb_asset_recharge_record`。强充订单的 linked_package_ids、linked_carrier_type、linked_carrier_id 存储在 `tb_recharge_order` 中。
|
||||
|
||||
#### Scenario: 余额不足触发强充,写入新表
|
||||
- **WHEN** 用户购买套餐时余额低于强充阈值,触发强充流程
|
||||
- **THEN** 创建 `tb_recharge_order` 记录(含 linked_package_ids、linked_carrier_type、linked_carrier_id、auto_purchase_status=pending)
|
||||
- **THEN** 创建 `tb_payment` 记录(payment_method=wechat,status=1)
|
||||
- **THEN** 不再写入 `tb_asset_recharge_record`
|
||||
|
||||
#### Scenario: 强充发起后订单在列表可见
|
||||
- **WHEN** 强充发起成功(微信支付参数返回前端)
|
||||
- **THEN** 用户立刻可在 `/api/c/v1/orders` 列表中看到该充值订单(status=1,待支付)
|
||||
@@ -0,0 +1,29 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: 钱包支付
|
||||
钱包支付 SHALL 在扣款成功的同一事务中创建 `tb_payment` 记录(payment_method=wallet,status=2,paid_at=当前时间),关联到 `tb_order`(order_type=package_order)。不再仅通过 `tb_order.payment_method` 隐式记录支付信息。
|
||||
|
||||
#### Scenario: 钱包支付同步创建支付记录
|
||||
- **WHEN** 用户通过钱包支付套餐订单,扣款成功
|
||||
- **THEN** 在同一事务中:创建 `tb_payment`(method=wallet,status=2)、更新 `tb_order.payment_status=2`、扣减钱包余额、创建钱包流水
|
||||
|
||||
#### Scenario: 钱包余额不足时不创建支付记录
|
||||
- **WHEN** 用户发起钱包支付但余额不足
|
||||
- **THEN** 事务回滚,不创建 `tb_payment` 记录,返回余额不足错误
|
||||
|
||||
### Requirement: 第三方支付回调
|
||||
第三方支付回调处理 SHALL 从 `tb_payment` 查找 payment_no;找到后更新 `tb_payment.status=2` 并更新关联的 `tb_order` 或 `tb_recharge_order`。
|
||||
|
||||
#### Scenario: 新单号回调走新路由
|
||||
- **WHEN** 第三方支付回调,payment_no 在 `tb_payment` 中存在
|
||||
- **THEN** 更新 `tb_payment`(status=2,third_party_trade_no,paid_at)
|
||||
- **THEN** 根据 `tb_payment.order_type` 更新关联业务订单(`tb_order` 或 `tb_recharge_order`)
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 支付记录幂等保障
|
||||
系统 SHALL 通过 `tb_payment` 的 `payment_no` 唯一约束 + 状态检查确保 PayOrder 接口的幂等性:同一 order_id 在 `tb_payment` 中已有 status=2 的记录时,直接返回成功,不重复扣款。
|
||||
|
||||
#### Scenario: 重复调用 PayOrder 幂等返回
|
||||
- **WHEN** 相同 order_id 的 PayOrder 请求重复到达,`tb_payment` 中已存在 status=2 记录
|
||||
- **THEN** 直接返回支付成功,不重复扣减钱包余额
|
||||
@@ -0,0 +1,40 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 支付记录创建
|
||||
系统 SHALL 在每次发起支付时创建 `tb_payment` 记录,关联到业务订单(`tb_order` 或 `tb_recharge_order`),记录 order_type 用于多态关联。钱包直接支付时 status 直接设为 2(已支付),第三方支付时 status 为 1(待支付)。
|
||||
|
||||
#### Scenario: 微信支付创建支付记录
|
||||
- **WHEN** 用户发起微信支付(强充或套餐直接微信支付)
|
||||
- **THEN** `tb_payment` 创建 status=1 的记录,payment_method=wechat,关联 order_id 和 order_type
|
||||
|
||||
#### Scenario: 钱包支付创建支付记录
|
||||
- **WHEN** 用户通过钱包支付套餐订单
|
||||
- **THEN** `tb_payment` 创建 status=2 的记录,payment_method=wallet,paid_at=当前时间
|
||||
|
||||
### Requirement: 支付回调幂等处理
|
||||
系统 SHALL 通过 `tb_payment.payment_no` 唯一约束和状态检查确保支付回调幂等,重复回调不产生重复业务效果。
|
||||
|
||||
#### Scenario: 首次支付成功回调
|
||||
- **WHEN** 第三方支付成功回调,payment_no 在 `tb_payment` 中存在且 status=1
|
||||
- **THEN** 更新 `tb_payment.status`=2,记录 third_party_trade_no 和 paid_at
|
||||
- **THEN** 触发关联业务订单的后续处理
|
||||
|
||||
#### Scenario: 重复支付成功回调
|
||||
- **WHEN** 相同 payment_no 的支付成功回调再次到达,`tb_payment.status` 已为 2
|
||||
- **THEN** 直接返回成功,不执行任何业务更新
|
||||
|
||||
### Requirement: 支付路由统一
|
||||
系统 SHALL 在支付回调处理时,优先从 `tb_payment` 查找 payment_no;若存在则走新路由(更新 `tb_payment` + 关联业务订单);若不存在则 fallback 到旧 `tb_asset_recharge_record` 查询(兼容迁移过渡期)。
|
||||
|
||||
#### Scenario: 新单号走新路由
|
||||
- **WHEN** 支付回调的 payment_no 在 `tb_payment` 中存在
|
||||
- **THEN** 走新支付路由:更新 `tb_payment` → 更新关联 `tb_recharge_order` 或 `tb_order` → 触发后续业务
|
||||
|
||||
|
||||
|
||||
### Requirement: 支付配置关联
|
||||
系统 SHALL 在 `tb_payment` 中存储 payment_config_id,关联发起支付时使用的微信/支付宝配置,支持多配置场景下的对账。
|
||||
|
||||
#### Scenario: 记录支付配置快照
|
||||
- **WHEN** 创建支付记录时
|
||||
- **THEN** 将当前使用的 payment_config_id 写入 `tb_payment`
|
||||
@@ -0,0 +1,50 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 充值订单创建
|
||||
系统 SHALL 在强充发起时创建 `tb_recharge_order` 记录,记录充值金额、关联资产、关联套餐 IDs,初始状态为待支付(status=1)。同时创建对应的 `tb_payment` 记录(payment_method=wechat,status=1)。
|
||||
|
||||
#### Scenario: 强充发起成功
|
||||
- **WHEN** 用户发起强充(余额不足场景),系统成功调用微信支付 API
|
||||
- **THEN** `tb_recharge_order` 创建一条记录(status=1,linked_package_ids 已设置)
|
||||
- **THEN** `tb_payment` 创建一条关联记录(order_type=recharge_order,payment_method=wechat,status=1)
|
||||
- **THEN** 接口返回充值订单信息 + 微信支付参数
|
||||
|
||||
#### Scenario: 微信支付 API 调用失败
|
||||
- **WHEN** 系统在调用微信支付 API 时发生错误
|
||||
- **THEN** `tb_recharge_order` 记录被回滚(或标记为已关闭 status=3)
|
||||
- **THEN** `tb_payment` 记录被回滚
|
||||
- **THEN** Redis 幂等键被清除,允许用户重新发起
|
||||
|
||||
### Requirement: 充值订单状态流转
|
||||
系统 SHALL 通过支付回调更新充值订单状态:待支付(1)→ 已支付(2),关闭(3),退款(4)。状态更新使用乐观锁确保幂等性。
|
||||
|
||||
#### Scenario: 微信支付回调成功
|
||||
- **WHEN** 微信支付成功回调到达,payment_no 存在于 `tb_payment`
|
||||
- **THEN** `tb_payment.status` 更新为 2,记录 third_party_trade_no 和 paid_at
|
||||
- **THEN** 关联的 `tb_recharge_order.status` 更新为 2
|
||||
- **THEN** 钱包余额增加,创建钱包流水记录
|
||||
- **THEN** 若 linked_package_ids 非空,触发 auto_purchase 异步任务
|
||||
|
||||
#### Scenario: 重复回调幂等处理
|
||||
- **WHEN** 同一 payment_no 的支付成功回调重复到达
|
||||
- **THEN** 系统检测到 `tb_payment.status` 已为 2,直接返回成功
|
||||
- **THEN** 不重复更新钱包余额,不重复触发 auto_purchase
|
||||
|
||||
### Requirement: 自动购包状态追踪
|
||||
系统 SHALL 在 `tb_recharge_order` 上记录 auto_purchase_status,由 Asynq Worker 更新,支持 pending / success / failed 三种状态。
|
||||
|
||||
#### Scenario: 自动购包成功
|
||||
- **WHEN** auto_purchase 任务成功创建套餐订单并激活套餐
|
||||
- **THEN** `tb_recharge_order.auto_purchase_status` 更新为 success
|
||||
|
||||
#### Scenario: 自动购包失败
|
||||
- **WHEN** auto_purchase 任务在最大重试次数后仍失败
|
||||
- **THEN** `tb_recharge_order.auto_purchase_status` 更新为 failed
|
||||
- **THEN** 记录错误日志,告警通知运营
|
||||
|
||||
### Requirement: 充值订单列表查询
|
||||
系统 SHALL 支持按 iot_card_id 或 device_id + generation 查询充值订单列表,支持按 status 过滤。
|
||||
|
||||
#### Scenario: 按资产查询充值订单
|
||||
- **WHEN** 系统查询某张卡的充值订单列表
|
||||
- **THEN** 返回该卡(iot_card_id 匹配)且 generation 匹配的所有充值订单,按 created_at 降序
|
||||
@@ -0,0 +1,31 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: 创建钱包充值订单
|
||||
创建钱包充值订单 SHALL 写入 `tb_recharge_order`(非强充时 linked_package_ids 为 NULL),并同时创建 `tb_payment` 记录。不再写入 `tb_asset_recharge_record`。充值订单号格式保持 CRCH 前缀兼容。
|
||||
|
||||
#### Scenario: 用户主动充值写新表
|
||||
- **WHEN** 用户发起钱包充值(非强充场景)
|
||||
- **THEN** 创建 `tb_recharge_order`(linked_package_ids=NULL,auto_purchase_status=NULL)
|
||||
- **THEN** 创建 `tb_payment`(payment_method=wechat/alipay,status=1)
|
||||
- **THEN** 不写 `tb_asset_recharge_record`
|
||||
|
||||
### Requirement: 充值支付回调处理
|
||||
充值支付回调 SHALL 查 `tb_payment` 获取充值订单,更新 `tb_payment.status=2`,更新 `tb_recharge_order.status=2`,增加钱包余额,创建钱包流水。原有 `RechargeService.HandlePaymentCallback` 中对 `tb_asset_recharge_record` 的操作全部迁移到新表。
|
||||
|
||||
#### Scenario: 充值回调更新新表
|
||||
- **WHEN** 充值支付回调到达
|
||||
- **THEN** 查 `tb_payment` by payment_no
|
||||
- **THEN** 事务:更新 `tb_payment.status=2` → 更新 `tb_recharge_order.status=2` → 增加 `tb_asset_wallet.balance` → 创建 `tb_asset_wallet_transaction`(reference_type=recharge)
|
||||
|
||||
### Requirement: 充值记录新增 auto_purchase_status 状态追踪
|
||||
此需求 SHALL 迁移至 `tb_recharge_order.auto_purchase_status` 字段,语义和状态枚举不变(pending / success / failed)。`tb_asset_recharge_record` 上的该字段随表一起归档停用。
|
||||
|
||||
#### Scenario: 强充后 auto_purchase 完成,更新新表字段
|
||||
- **WHEN** auto_purchase 任务完成套餐激活
|
||||
- **THEN** `tb_recharge_order.auto_purchase_status` 更新为 success(不再更新 `tb_asset_recharge_record`)
|
||||
|
||||
## REMOVED Requirements
|
||||
|
||||
### Requirement: Store 方法签名支持事务参数
|
||||
**Reason**: `AssetRechargeStore` 连同 `tb_asset_recharge_record` 一起删除,其事务方法签名不再需要维护。
|
||||
**Migration**: 事务支持迁移至 `RechargeOrderStore` 和 `PaymentStore`,方法签名设计参考 `recharge-order` spec。
|
||||
Reference in New Issue
Block a user