You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
digital-rmb-backend/docs/superpowers/specs/2026-08-18-downstream-walle...

128 lines
7.4 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 模块 4/5 下游按需读取钱包前置数据设计
## 目标
建立模块 1 至模块 5 的真实业务数据关联,同时保持模块边界:模块 3 只记录钱包开通实验事实,不提前创建模块 4 或模块 5 的操作数据;模块 4、模块 5 在用户实际进入时主动读取前置模块结果。
## 已确认的业务边界
- 模块 3 完成钱包申请、证书生成、央行备案、合约生成、钱包激活和最终确认,只写 `walletopening` 模块自己的结果表。
- 模块 4 的付款用户必须完成模块 1、模块 2、模块 3模块 4 从模块 2 读取商业银行币串库存,从模块 3 读取已开通钱包资料。
- 模块 5 的付款方必须已经通过模块 4 取得数字货币币串;模块 5 的收款方只需要完成模块 3 并拥有已激活钱包。
- 下游读取必须按 `user_id + school_id + class_id` 隔离。按银行编码查询机构标识时也必须保留该隔离范围。
- 进入模块页面只能加载或初始化前置资源,不得创建兑换订单、支付订单或对应步骤记录。
## 数据所有权
### 模块 3 实验事实
以下表继续由模块 3 独占写入:
- `wallet_application`
- `bank_received_wallet_application`
- `wallet_verification_record`
- `wallet_identifier_generation`
- `wallet_registration_request`
- `central_wallet_registration`
- `smart_contract_generation`
- `central_wallet_activation`
模块 4、模块 5 对这些表只读,不反向修改。
### 共享钱包运行态
以下表定义为模块间共享的、可交易的钱包运行态,不属于模块 4 或模块 5 的步骤数据:
- `digital_wallet`
- `wallet_certificate`
- `wallet_contract`
- `simulated_bank_account`
- `wallet_bank_binding`
共享运行态只在模块 4 或模块 5 首次需要该钱包时,由下游按模块 3 最终结果幂等初始化。后续余额、冻结金额和额度累计值由真实兑换、支付业务更新,初始化逻辑不得覆盖已有值。
## 读取与初始化流程
新增一个共享的前置钱包读取服务,供模块 4 和模块 5 调用。
1. 接收当前主体 `userId`、`schoolId`、`classId`;按钱包标识读取收款人时,先定位钱包所属主体,再使用其完整主体范围校验。
2. 查询模块 3 同一主体的最新一轮结果,所有组成数据必须来自同一用户、学校和班级。
3. 验证以下完成条件:
- `central_wallet_activation.wallet_activated = true`
- `central_wallet_activation.final_sent = true`
- `central_wallet_activation.cb_final_signature` 非空;
- `central_wallet_registration.cb_root_signature` 非空且备案流程已完成;
- `wallet_identifier_generation.status = 'CERT_ISSUED'`,证书公钥、私钥和序列号完整;
- `smart_contract_generation.status = 'SENT'`,合约标识和额度字段完整;
- `wallet_application.status = 'SUBMITTED'`,银行卡、开户行、钱包类型和账户余额完整。
4. 任一条件不满足时返回业务校验错误,错误信息指出尚未完成的钱包开通前置步骤,不创建任何共享运行态记录。
5. 条件全部满足时,在一个事务内按依赖顺序插入缺失的共享记录:银行卡账户、钱包、证书、合约、绑定关系。
6. 如果共享钱包已经存在,只验证其归属与模块 3 结果一致,然后返回;不得更新余额、冻结金额、额度累计值、证书密钥或绑定关系。
7. 初始化完成后,模块 4、模块 5 继续使用现有共享运行态仓储完成签名、冻结、扣款、限额累计和余额更新。
## 字段来源
| 共享字段 | 模块 3 来源 |
|---|---|
| 钱包标识 | `central_wallet_activation.wallet_id` |
| 钱包类型 | `smart_contract_generation.wallet_type` |
| 央行最终确认签名 | `central_wallet_activation.cb_final_signature` |
| 钱包开户时间 | `central_wallet_activation.final_time`,无法解析时使用共享记录初始化时间 |
| 证书序列号、公私钥 | `wallet_identifier_generation` 对应字段 |
| 央行根签名 | `central_wallet_registration.cb_root_signature` |
| 合约标识、额度、摘要 | `smart_contract_generation` 对应字段 |
| 银行编码 | 当前主体对应的 `institution_identifier_application.bank_code` |
| 银行名称、银行卡号、银行账户初始余额 | `wallet_application` 对应字段 |
| 钱包初始余额、冻结金额 | `0.00` |
| 银行账户冻结金额 | `0.00` |
共享银行账户标识使用稳定、可重复生成的值,保证重复初始化不会产生多条账户记录。银行卡末四位由完整卡号计算。
## 模块调用关系
### 模块 4
`GET /api/v1/exchanges/context` 在读取兑换上下文前调用共享前置钱包读取服务。成功后继续通过现有 `JdbcExchangeResourceRepository` 读取钱包、证书、合约、银行卡账户及模块 2 币串库存。只有创建兑换请求时才写 `currency_exchange_order` 等模块 4 表。
### 模块 5
支付上下文加载时分别处理双方:
- 付款方:读取或初始化其模块 3 钱包运行态,并继续校验模块 4 形成的 `WALLET/AVAILABLE` 币串;没有币串时拒绝支付。
- 收款方:按收款钱包标识读取模块 3 最终结果并初始化运行态,不要求其完成模块 4。
模块 5 查询机构标识时使用钱包所属用户、学校、班级和银行编码共同限定,禁止只按 `bank_code` 取最新记录。
## 并发与幂等
- 初始化方法使用事务。
- 共享表已有唯一键继续作为并发保护;出现并发插入时重新读取并验证归属,不覆盖先写入的数据。
- 初始化只执行“缺失则插入”,不能使用会更新已有余额或额度字段的 upsert。
- 如果发现共享记录与模块 3 的钱包标识、用户或银行卡绑定不一致,返回冲突错误,不自动修正。
## 错误处理
- 模块 3 未完成:返回业务校验错误,并指出需要先完成个人数字钱包开通实验。
- 模块 1 机构标识缺失或主体不匹配:返回业务校验错误,不允许跨用户或跨班级回退。
- 模块 4 币串库存不足:沿用模块 4 现有库存错误。
- 模块 5 付款方没有模块 4 形成的钱包币串:返回余额或币串不足错误。
- 模块 3 数据与已存在共享运行态冲突:返回数据冲突错误,保留双方数据供排查。
## 测试与验收
1. 模块 3 未完成时访问模块 4接口拒绝并且五张共享运行态表没有新增记录。
2. 模块 3 完成后访问模块 4能够读取钱包、合约、证书、银行卡和模块 2 库存;模块 4 订单仍为空。
3. 重复访问模块 4 不覆盖已发生变化的钱包余额、银行卡余额和额度累计值。
4. 模块 5 付款方完成模块 3 但未取得模块 4 币串时,支付被拒绝。
5. 模块 5 收款方只完成模块 3 时,可以作为合法收款钱包被读取。
6. 相同银行编码下存在其他用户、学校或班级数据时,不会读取到错误机构标识或钱包结果。
7. 模块 4/5 读取和交易后,模块 3 的八张实验事实表内容不被修改。
8. 现有模块 2→4 币串权属和模块 4→5 支付币串链路继续通过定向集成测试。
## 不在本次范围
- 不修改模块 3 页面步骤、接口顺序或评分逻辑。
- 不把模块 3 的历史轮次迁移到共享运行态。
- 不重构模块 4/5 的交易流水、签名或央行权属模型。
- 不处理当前全量测试中与本关联改动无关的错误码断言差异。