# 钱包系统分离提案

## Why

当前所有钱包类型（代理钱包、卡钱包）混在同一张表 `tb_wallet` 中，通过 `resource_type` 和 `wallet_type` 字段区分。业务方担心未来某个钱包业务的代码问题会影响其他钱包类型，特别是代理钱包作为核心资产需要最高等级的稳定性保障。在系统复杂度增长前，需要提前做预防性架构优化，将代理钱包和卡钱包在数据层和代码层完全隔离。

## What Changes

### 数据库层变更

**新增表**：
- `tb_agent_wallet` - 代理钱包主表（店铺级别）
- `tb_agent_wallet_transaction` - 代理钱包交易记录表
- `tb_agent_recharge_record` - 代理充值记录表
- `tb_card_wallet` - 卡钱包主表（物联网卡和设备）
- `tb_card_wallet_transaction` - 卡钱包交易记录表
- `tb_card_recharge_record` - 卡充值记录表

**删除表** - **BREAKING**：
- `tb_wallet` - 统一钱包表（由新的两张表替代）
- `tb_wallet_transaction` - 统一交易记录表（由新的两张表替代）
- `tb_recharge_record` - 统一充值记录表（由新的两张表替代）

### 代码层变更

**新增 Model**：
- `internal/model/agent_wallet.go` - 代理钱包相关 Model（AgentWallet、AgentWalletTransaction、AgentRechargeRecord）
- `internal/model/card_wallet.go` - 卡钱包相关 Model（CardWallet、CardWalletTransaction、CardRechargeRecord）

**删除 Model** - **BREAKING**：
- `internal/model/wallet.go` - 统一钱包 Model（由新的两个文件替代）

**新增 Store**：
- `internal/store/postgres/agent_wallet_store.go` - 代理钱包数据访问层
- `internal/store/postgres/agent_wallet_transaction_store.go` - 代理钱包交易记录访问层
- `internal/store/postgres/agent_recharge_store.go` - 代理充值记录访问层
- `internal/store/postgres/card_wallet_store.go` - 卡钱包数据访问层
- `internal/store/postgres/card_wallet_transaction_store.go` - 卡钱包交易记录访问层
- `internal/store/postgres/card_recharge_store.go` - 卡充值记录访问层

**删除 Store** - **BREAKING**：
- `internal/store/postgres/wallet_store.go` - 统一钱包 Store（由新的 Store 替代）
- `internal/store/postgres/wallet_transaction_store.go` - 统一交易记录 Store（由新的 Store 替代）

**重构 Service**：
- `internal/service/commission_*` - 佣金相关服务改用 `AgentWalletStore`
- `internal/service/order` - 订单服务改用 `CardWalletStore`
- `internal/service/recharge` - 充值服务拆分为代理充值和卡充值两个独立服务

**更新常量定义**：
- `pkg/constants/wallet.go` - 按钱包类型隔离常量定义和 Redis Key 生成函数

**更新依赖注入**：
- `internal/bootstrap/stores.go` - 注册新的 Store 实例
- `internal/bootstrap/services.go` - 更新 Service 依赖注入

### 监控和运维

**新增监控指标**（建议）：
- `agent_wallet_transaction_count` - 代理钱包交易量
- `agent_wallet_error_rate` - 代理钱包错误率
- `card_wallet_transaction_count` - 卡钱包交易量
- `card_wallet_error_rate` - 卡钱包错误率

**告警策略差异化**：
- 代理钱包错误率阈值更严格（建议 P0 级别告警）
- 卡钱包错误率阈值相对宽松（建议 P1 级别告警）

## Capabilities

### New Capabilities

- `agent-wallet`: 代理钱包系统，提供店铺级别的主钱包和分佣钱包管理，支持充值、扣款、冻结、提现等操作
- `card-wallet`: 卡钱包系统，提供物联网卡和设备级别的钱包管理，支持充值、套餐扣费、余额查询等操作

### Modified Capabilities

- `wallet`: 需求变更 - 废弃统一钱包设计，拆分为 `agent-wallet` 和 `card-wallet` 两个完全独立的系统，要求在数据表、Model、Store、部分 Service 层面完全隔离

## Impact

### 受影响的模块

| 模块类型 | 受影响组件 | 变更类型 |
|---------|-----------|---------|
| **数据库** | `tb_wallet`、`tb_wallet_transaction`、`tb_recharge_record` | 删除并替换为 6 张新表 |
| **Model** | `internal/model/wallet.go` | 删除并替换为 2 个新文件 |
| **Store** | `internal/store/postgres/wallet_*.go` | 删除并替换为 6 个新 Store |
| **Service** | `internal/service/commission_*` | 依赖注入改为 `AgentWalletStore` |
| **Service** | `internal/service/order` | 依赖注入改为 `CardWalletStore` |
| **Service** | `internal/service/recharge` | 拆分为两个独立服务 |
| **Bootstrap** | `internal/bootstrap/stores.go`、`services.go` | 更新依赖注入配置 |
| **常量** | `pkg/constants/wallet.go` | 按钱包类型重构常量定义 |
| **Redis Key** | 钱包相关缓存 Key | 按钱包类型隔离（`agent_wallet:*`、`card_wallet:*`） |

### API 影响

**无 API 破坏性变更** - 所有对外 API 接口保持不变，仅内部实现重构

### 性能影响

**预期正向影响**：
- 代理钱包和卡钱包数据量独立，查询性能提升
- 索引优化可针对不同钱包类型的查询模式独立调优
- 减少单表数据量，降低锁竞争概率

### 部署影响

**当前处于开发阶段**：
- 无需数据迁移
- 删除旧表，创建新表
- 一次性部署代码变更

**如果未来生产环境部署**（预留方案）：
- 需要制定数据迁移脚本
- 需要停机窗口或在线双写迁移方案

### 风险评估

| 风险项 | 风险等级 | 缓解措施 |
|-------|---------|---------|
| 代码重构引入 Bug | 中 | 充分的手动测试，验证核心流程 |
| 遗漏依赖点导致编译失败 | 低 | 编译检查，逐步重构 |
| 数据表设计遗漏字段 | 低 | 参考现有 Model 设计，保持字段完整性 |
| 性能回退 | 低 | 索引设计参考现有表，预期性能持平或提升 |

### 测试策略

**手动测试覆盖**：
- 代理钱包：佣金发放、提现、余额查询
- 卡钱包：订单支付、充值、余额查询
- 边界场景：余额不足、并发扣款、冻结/解冻

**数据一致性验证**：
- 验证代理钱包交易记录的 `balance_before` 和 `balance_after` 准确性
- 验证卡钱包交易记录的余额变动准确性
- 验证乐观锁（version 字段）在并发场景下的有效性

### 时间估算

**预估工作量**：
- 数据库迁移文件编写：0.5 天
- Model 和 Store 重构：2 天
- Service 层重构：2 天
- Bootstrap 和常量更新：0.5 天
- 手动测试和验证：1 天
- **总计：6 天**

### 依赖和前置条件

- ✅ 项目处于开发阶段，可直接重构
- ✅ 无生产数据，无需迁移方案
- ✅ 技术栈符合项目规范（GORM、PostgreSQL、Redis）
