diff --git a/.scratch/ur48-asset-payment-methods/issues/01-payment-config-asset-contract.md b/.scratch/ur48-asset-payment-methods/issues/01-payment-config-asset-contract.md new file mode 100644 index 0000000..2390fc3 --- /dev/null +++ b/.scratch/ur48-asset-payment-methods/issues/01-payment-config-asset-contract.md @@ -0,0 +1,16 @@ +# 01 — 接入支付配置并提供资产展示契约 + +**What to build:** C 端和后台可以使用同一份受控支付方式规则:卡、设备各自读取已注册的配置并在配置异常时回退安全默认值,资产信息稳定返回可展示的 `allowed_payment_methods`。后台配置接口所返回的信息足以驱动受控复选框,钱包始终不可移除;C 端不再维护资产类型支付规则副本。 + +**Blocked by:** `tech-public-foundation` 08 — 交付系统配置更新、权限和审计闭环(外部前置链:01 → 07 → 08)。 + +**Status:** ready-for-agent + +**架构通道:** 主通道为 Query,辅助通道为 Application。 + +**完整业务边界:** 本票收口 UR48 的两个支付配置 Key、支付方式解析/校验能力、配置异常安全默认及资产信息展示契约。明确不创建 `tb_system_config`、通用配置 API、缓存壳层或审计壳层;这些均由公共基础拥有。 + +- [ ] 注册卡和设备的支付方式 Key,限制值为唯一且包含钱包的 `wallet|wechat|alipay` 集合,并为非法、缺失或损坏配置定义安全默认及中文安全日志。 +- [ ] `GET /api/c/v1/asset/info` 仅在完成资产解析和归属校验后返回稳定排序的 `allowed_payment_methods`;不存在、无权或未知资产类型不泄露配置。 +- [ ] 后端与真实 PostgreSQL、Redis 的集成测试覆盖默认、自定义、缓存、缓存故障回退、配置异常、资产归属及 API 文档运行时契约。 + diff --git a/.scratch/ur48-asset-payment-methods/issues/02-asset-wallet-recharge-payment-policy.md b/.scratch/ur48-asset-payment-methods/issues/02-asset-wallet-recharge-payment-policy.md new file mode 100644 index 0000000..99ac576 --- /dev/null +++ b/.scratch/ur48-asset-payment-methods/issues/02-asset-wallet-recharge-payment-policy.md @@ -0,0 +1,16 @@ +# 02 — 限制普通资产钱包充值方式 + +**What to build:** C 端用户为资产钱包充值时,服务只接受该资产当前允许集合与第三方充值方式的交集;钱包永远不会作为“给钱包充值”的渠道。没有可用第三方渠道或客户端伪造方式时,后端安全拒绝。 + +**Blocked by:** 01 — 接入支付配置并提供资产展示契约。 + +**Status:** ready-for-agent + +**架构通道:** 复杂写(现有充值用例的最小完整边界)。 + +**完整业务边界:** 本票收口 C 端普通资产钱包充值的支付许可判定及接口交互结果。明确不修改代理、后台、线下、银行或其他充值流程,不复制另一套资产支付规则。 + +- [ ] 充值创建在资产解析、归属和现有金额/渠道/幂等校验后,以统一支付许可能力校验微信或支付宝;钱包和不允许方式均被拒绝。 +- [ ] 接口返回和错误能让页面仅展示可充值第三方方式,并在交集为空时展示不可充值提示;不得通过页面隐藏代替服务端校验。 +- [ ] Fiber、认证、GORM/PostgreSQL 与真实 Redis 集成测试覆盖卡/设备组合、空交集、伪造钱包方式、配置变更和既有充值幂等行为。 + diff --git a/.scratch/ur48-asset-payment-methods/issues/03-order-payment-method-snapshot-and-force-recharge.md b/.scratch/ur48-asset-payment-methods/issues/03-order-payment-method-snapshot-and-force-recharge.md new file mode 100644 index 0000000..b4e77b4 --- /dev/null +++ b/.scratch/ur48-asset-payment-methods/issues/03-order-payment-method-snapshot-and-force-recharge.md @@ -0,0 +1,17 @@ +# 03 — 创建套餐订单时确定支付方式与强充处理 + +**What to build:** C 端创建套餐订单时必须选择允许的支付方式,普通待支付订单保存不可变方式快照并返回给页面;需要强充时,微信或支付宝立即走对应支付流程,钱包强充明确拒绝且不留下订单、充值单或支付单。 + +**Blocked by:** 01 — 接入支付配置并提供资产展示契约。 + +**Status:** ready-for-agent + +**架构通道:** 复杂写(Order Domain/Application)。 + +**完整业务边界:** 本票收口 C 端套餐创建、支付方式快照、强充分流及创建幂等的完整写侧规则。明确不迁移后台订单、代理订单、线下支付或支付回调整体流程。 + +- [ ] `/api/c/v1/orders/create` 对所有套餐订单强制接收 `wallet|wechat|alipay`,在创建任何业务事实或调用第三方前按实际资产许可校验,并将普通订单方式持久化和返回。 +- [ ] 强充微信要求合法应用类型并返回微信参数,强充支付宝返回支付链接;强充钱包或只剩钱包的配置均以中文业务错误拒绝且无残留事实。 +- [ ] 同资产套餐已有待支付订单时,不同支付方式不能绕过既有冲突;请求摘要或 Redis 防重键正确区分支付方式,同时 PostgreSQL 仍为权威事实。 +- [ ] 集成测试覆盖前端所需响应字段、普通两阶段流程、三种强充分支、提交前配置变化、幂等和 OpenAPI 契约。 + diff --git a/.scratch/ur48-asset-payment-methods/issues/04-order-snapshot-pay-and-cancel.md b/.scratch/ur48-asset-payment-methods/issues/04-order-snapshot-pay-and-cancel.md new file mode 100644 index 0000000..a15e4be --- /dev/null +++ b/.scratch/ur48-asset-payment-methods/issues/04-order-snapshot-pay-and-cancel.md @@ -0,0 +1,16 @@ +# 04 — 按订单快照支付、取消并重新创建 + +**What to build:** C 端用户只能按创建订单时保存的支付方式执行支付;方式后来被禁用时,用户可安全取消自己的待支付订单并重新创建,而不能在旧订单上换方式。支付与取消并发时只会有一个终态成功。 + +**Blocked by:** 01 — 接入支付配置并提供资产展示契约;03 — 创建套餐订单时确定支付方式与强充处理。 + +**Status:** ready-for-agent + +**架构通道:** 复杂写(Order Domain/Application)。 + +**完整业务边界:** 本票收口 C 端套餐订单的快照支付、二次许可校验、主动取消和取消后重建规则。明确不调整自动取消任务、支付回调或其他订单类型的状态机,只保证它们不改写支付方式快照。 + +- [ ] `/api/c/v1/orders/{id}/pay` 从订单读取方式快照并在支付前重读最新许可;过渡字段仅可与快照完全一致,不一致返回冲突且不能覆盖快照。 +- [ ] 新增 C 端取消接口,仅允许本人取消待支付套餐订单;使用条件更新实现与支付并发互斥,重复取消幂等返回当前状态,并复用既有资源释放和支付记录作废逻辑。 +- [ ] 订单详情和支付响应返回前端展示所需的固定支付方式;方式禁用时返回可引导“取消后重新创建”的中文安全错误,不自动降级或换渠道。 +- [ ] 真实 Fiber、认证、GORM/PostgreSQL、Redis 集成测试覆盖快照不可变、微信附加参数、禁用后拒绝、跨方式支付记录不复用、取消权限/幂等/并发及 API 文档契约。 diff --git a/.scratch/ur48-asset-payment-methods/系统配置调研.md b/.scratch/ur48-asset-payment-methods/系统配置调研.md new file mode 100644 index 0000000..b6d0dc3 --- /dev/null +++ b/.scratch/ur48-asset-payment-methods/系统配置调研.md @@ -0,0 +1,47 @@ +# `tb_system_config` 调研结论 + +## 结论 + +`tb_system_config` **确实是已确认的七月迭代公共基础需求**,不是 UR#48 临时假定或需要重新发明的能力;但它在当前工作区仍是**已规划、已拆票、未实现**状态。 + +UR#48 应依赖公共基础的第 07、08 号票,不应复制系统配置表、注册表、缓存、超管权限、通用列表/更新 API 或审计壳层。UR#48 自己负责注册两个支付 Key、其值域与钱包不可移除规则,以及资产展示、下单、支付、充值等支付业务校验。 + +## 已确认的七月迭代设计 + +- 标准评审稿将系统配置列为“跨需求基础设施”,目标是把支付方式等受控配置从代码迁移到数据库;数据模型和首批两个支付 Key 均已明确:[7月迭代技术方案-标准评审稿.md:162](/data/zoujin/xj02/junhong_cmp_fiber/docs/7月迭代/7月迭代技术方案-标准评审稿.md:162)、[同文件:170](/data/zoujin/xj02/junhong_cmp_fiber/docs/7月迭代/7月迭代技术方案-标准评审稿.md:170)、[同文件:184](/data/zoujin/xj02/junhong_cmp_fiber/docs/7月迭代/7月迭代技术方案-标准评审稿.md:184)。 +- 该稿冻结了更新后删缓存、默认缓存五分钟、未知 Key 不可写、异常回退安全默认值,以及“受控控件而非 JSON 文本框”的规则:[同文件:201](/data/zoujin/xj02/junhong_cmp_fiber/docs/7月迭代/7月迭代技术方案-标准评审稿.md:201)、[同文件:209](/data/zoujin/xj02/junhong_cmp_fiber/docs/7月迭代/7月迭代技术方案-标准评审稿.md:209)。管理接口也已约定为 `GET /api/admin/system/config?module=` 和 `PUT /api/admin/system/config/{config_key}`:[同文件:215](/data/zoujin/xj02/junhong_cmp_fiber/docs/7月迭代/7月迭代技术方案-标准评审稿.md:215)。 +- 需求 09 明确卡/设备支付方式读取系统配置、钱包恒定允许、C 端仅展示接口返回集合、订单创建固化方式且支付时再次校验:[同文件:761](/data/zoujin/xj02/junhong_cmp_fiber/docs/7月迭代/7月迭代技术方案-标准评审稿.md:761)。 +- 独立系统配置方案提供了 `tb_system_config` DDL、两个 `c2b.payment` 初始化值和唯一 Key 约束:[系统配置.md:35](/data/zoujin/xj02/junhong_cmp_fiber/docs/7月迭代/独立方案/基础规范/系统配置.md:35)、[同文件:54](/data/zoujin/xj02/junhong_cmp_fiber/docs/7月迭代/独立方案/基础规范/系统配置.md:54)。它还定义了 Model、Store、五分钟 Redis 读取辅助能力和管理 API 形态:[同文件:65](/data/zoujin/xj02/junhong_cmp_fiber/docs/7月迭代/独立方案/基础规范/系统配置.md:65)、[同文件:90](/data/zoujin/xj02/junhong_cmp_fiber/docs/7月迭代/独立方案/基础规范/系统配置.md:90)、[同文件:107](/data/zoujin/xj02/junhong_cmp_fiber/docs/7月迭代/独立方案/基础规范/系统配置.md:107)、[同文件:138](/data/zoujin/xj02/junhong_cmp_fiber/docs/7月迭代/独立方案/基础规范/系统配置.md:138)。 +- 原始需求 09 也显式声明依赖系统配置,并规定 C 端消费 `allowed_payment_methods`、后台用钱包不可取消的复选框:[需求09-C端支付限制配置化.md:1](/data/zoujin/xj02/junhong_cmp_fiber/docs/7月迭代/独立方案/原需求/需求09-C端支付限制配置化.md:1)、[同文件:116](/data/zoujin/xj02/junhong_cmp_fiber/docs/7月迭代/独立方案/原需求/需求09-C端支付限制配置化.md:116)、[同文件:133](/data/zoujin/xj02/junhong_cmp_fiber/docs/7月迭代/独立方案/原需求/需求09-C端支付限制配置化.md:133)。 + +## 已有公共基础 PRD 与票据 + +公共基础 PRD 已将“受控系统配置壳层”纳入交付范围,并明确当前 `tb_system_config` 尚未落地:[tech-public-foundation/PRD.md:7](/data/zoujin/xj02/junhong_cmp_fiber/.scratch/tech-public-foundation/PRD.md:7)、[同文件:25](/data/zoujin/xj02/junhong_cmp_fiber/.scratch/tech-public-foundation/PRD.md:25)。 + +- 公共基础是 `tb_system_config` 和其公共索引、约束、必要初始化数据的唯一迁移所有者:[tech-public-foundation/PRD.md:84](/data/zoujin/xj02/junhong_cmp_fiber/.scratch/tech-public-foundation/PRD.md:84)。 +- 公共壳层的责任包括受控注册表、超级管理员查询/更新、GORM 事务、Audit 接缝、五分钟 Redis 缓存与安全回退:[同文件:154](/data/zoujin/xj02/junhong_cmp_fiber/.scratch/tech-public-foundation/PRD.md:154)。其中明确划分:UR#48 负责具体支付 Key、支付值域和启停校验;公共基础只负责存储、注册、权限、缓存、API 和审计壳层:[同文件:165](/data/zoujin/xj02/junhong_cmp_fiber/.scratch/tech-public-foundation/PRD.md:165)。 +- 当前仓库“没有公共 Outbox 和受控系统配置实现”的状态被 PRD 再次明确记录:[同文件:259](/data/zoujin/xj02/junhong_cmp_fiber/.scratch/tech-public-foundation/PRD.md:259)。 +- 下游依赖表将 UR#48 明确列为受 `tb_system_config`、受控 Key 注册、缓存、权限、API 和审计壳层阻塞;并禁止下游复制临时配置中心:[同文件:267](/data/zoujin/xj02/junhong_cmp_fiber/.scratch/tech-public-foundation/PRD.md:267)、[同文件:283](/data/zoujin/xj02/junhong_cmp_fiber/.scratch/tech-public-foundation/PRD.md:283)、[同文件:285](/data/zoujin/xj02/junhong_cmp_fiber/.scratch/tech-public-foundation/PRD.md:285)。 + +对应票据已存在、均为 `ready-for-agent`,但尚未勾选完成: + +1. **07 — 交付受控系统配置注册与查询闭环**:被 01 号公共迁移门禁阻塞;只交付系统配置表、注册、缓存读取和超级管理员列表 API,明确不注册支付具体 Key。[07-controlled-system-config-read.md:1](/data/zoujin/xj02/junhong_cmp_fiber/.scratch/tech-public-foundation/issues/07-controlled-system-config-read.md:1)、[同文件:5](/data/zoujin/xj02/junhong_cmp_fiber/.scratch/tech-public-foundation/issues/07-controlled-system-config-read.md:5)、[同文件:11](/data/zoujin/xj02/junhong_cmp_fiber/.scratch/tech-public-foundation/issues/07-controlled-system-config-read.md:11)。 +2. **08 — 交付系统配置更新、权限和审计闭环**:被 07 号票阻塞;交付单 Key 更新、授权、校验、事务、缓存失效和审计接缝。[08-controlled-system-config-update.md:1](/data/zoujin/xj02/junhong_cmp_fiber/.scratch/tech-public-foundation/issues/08-controlled-system-config-update.md:1)、[同文件:5](/data/zoujin/xj02/junhong_cmp_fiber/.scratch/tech-public-foundation/issues/08-controlled-system-config-update.md:5)、[同文件:11](/data/zoujin/xj02/junhong_cmp_fiber/.scratch/tech-public-foundation/issues/08-controlled-system-config-update.md:11)。 + +因此,UR#48 在真实执行顺序上至少依赖:**公共基础 01 → 07 → 08**;UR#48 可在公共契约稳定后并行实现其支付领域部分,但不可先行落一套替代基础设施。 + +## 当前实现核查 + +截至当前 `HEAD`,仓库没有 `SystemConfig` 模型、`tb_system_config` 迁移、对应 PostgreSQL Store、通用系统配置 Handler/Route 或 `pkg/sysconfig` 读取包。作为对照,现存 `internal/model/system.go` 只定义 `DevCapabilityConfig` 等旧模型,其表名是 `tb_dev_capability_config`,不是 `tb_system_config`:[internal/model/system.go:9](/data/zoujin/xj02/junhong_cmp_fiber/internal/model/system.go:9)、[同文件:23](/data/zoujin/xj02/junhong_cmp_fiber/internal/model/system.go:23)。 + +迁移目录中也没有包含 `tb_system_config` 或 `c2b.payment` 的 SQL 文件;清理脚本列出的现有“系统配置表”保留集合同样未包含 `tb_system_config`:[scripts/cleanup/main.go:38](/data/zoujin/xj02/junhong_cmp_fiber/scripts/cleanup/main.go:38)。这与公共 PRD 的“尚未落地”状态一致。 + +## Git 历史 + +- 七月迭代标准方案在提交 `d022cc8788999c9e5426063907d6fe3c569bd22c`(2026-07-17,`迭代方案确认`)中确认。 +- 公共基础 PRD 与票据在提交 `21702da413979970989a0026ee0e5cbba248e47b`(2026-07-22,`创建相关issues`)中加入;该提交新增第 07、08 号系统配置票据。 +- 对所有分支的 Git 历史及当前 Go、迁移、路由和 Store 路径检索,未发现将 `tb_system_config` 实现提交到仓库的证据;命中均为上述规划/票据/文档,或与通用系统配置无关的旧模型。 + +## 对 UR#48 拆票的影响 + +UR#48 不应再包含“建立公共系统配置能力”票。其首张业务票应改为“在公共基础 07、08 完成后,注册 `c2b.payment.card_allowed_methods` 和 `c2b.payment.device_allowed_methods`,并交付支付许可读取/安全默认/资产展示契约”;后续再按订单创建、固定方式支付与取消等完整业务纵向切片拆分。