# wallet-shard-service 钱包分片服务

## 服务职责

wallet-shard-service 按玩家或商户玩家维度对钱包事件分片，保障同一个玩家的扣款、派奖、退款、冲正顺序处理。

## 分片规则

推荐分片 key：

```text
hash(merchant_id + ":" + player_id) % shard_count
```

## 核心约束

- 同一玩家同一时间只能在一个分片内顺序处理钱包事件。
- 不允许多个服务并发修改同一玩家余额。
- 分片处理结果必须产生账本事件。

## 下游依赖

- Redpanda wallet topics
- ledger-service
- PostgreSQL wallet_db
- Redis

## 命令

```bash
cd /Users/amumu/Desktop/beifen/golang新架构/平台服务/wallet-shard-service
go test ./...
PORT=8092 go run ./cmd/wallet-shard-service
docker build -t registry.local/wallet-shard-service:v1 .
kubectl apply -f deploy/k8s/deployment.yaml
```

## 当前代码目录

```text
平台服务/wallet-shard-service
├── cmd/wallet-shard-service      进程入口
├── api/openapi                   HTTP API 契约
├── configs                       配置模板
├── internal/bootstrap            服务启动组装
├── internal/config               环境变量读取
├── internal/domain               领域错误
├── internal/handler/http         Hertz 路由和请求响应适配
├── internal/middleware           中间件预留
├── internal/model                请求和响应模型
├── internal/repository/redpanda  Redpanda consumer/producer 预留
└── internal/service              分片、幂等、钱包扣款请求事件生成
```

## 第一阶段已实现

当前已经从健康检查占位升级为可运行服务：

```text
POST /wallet/debit-request
```

当前具备：

- 稳定分片：`hash(merchant_id + ":" + player_id) % shard_count`。
- 同一玩家稳定落到同一 shard。
- `bet_order_id` 幂等。
- 从 `order.ingested` 语义请求生成 `wallet.debit.requested` 事件。
- 事件包含 `shard_id`、`partition_key`、`amount`、`currency`、`source_event_id`。
- 单元测试覆盖分片稳定性、事件生成、幂等和参数校验。

注意：当前 producer 是内存实现，下一阶段要接真实 Redpanda consumer/producer，让服务从 `order.ingested` topic 消费，并写入 `wallet.debit.requested` topic。

## 本地请求示例

```bash
curl -sS http://127.0.0.1:8092/wallet/debit-request \
  -H 'Content-Type: application/json' \
  -H 'X-Request-ID: wallet-local-001' \
  -d '{
    "event_id": "evt_order_001",
    "trace_id": "trace_001",
    "merchant_id": "DEMO",
    "player_id": "player_001",
    "round_id": "round_001",
    "bet_order_id": "bet_001",
    "client_request_id": "req_001",
    "bet_amount": 100,
    "currency": "CNY"
  }'
```

## 环境变量

```text
WALLET_SHARD_COUNT=64
```

## 下一阶段必须补齐

- Redpanda consumer：消费 `order.ingested`。
- Redpanda producer：写入 `wallet.debit.requested`。
- 真实钱包余额读取和扣款预留。
- 与 wallet-service/ledger-service 的内部契约。
- Prometheus 指标。
- OpenTelemetry trace。
- 压测脚本和报告。
