# warehouse-writer 数仓写入服务

## 服务定位

数仓写入服务负责把订单、账本、回调、商户资金等事件写入 ClickHouse/Doris，用于后台统计、报表和风控分析。第一阶段先提供 HTTP 批量写入接口和内存仓储，模拟后续列式明细表与聚合索引，不接入真实 ClickHouse/Doris。

## 核心职责

- 接收上游服务投递的数仓事件。
- 以 `event_id` 做幂等，重复写入返回 `duplicated`，不重复追加明细。
- 批量写入 ClickHouse/Doris 明细表模型。
- 维护后台统计可直接读取的聚合索引模型。
- 对单条事件返回 `accepted` / `duplicated` / `failed` 状态。
- 保证统计链路不阻塞主交易链路。

## 第一阶段支持事件

| event_type | 来源建议 | 统计含义 |
| --- | --- | --- |
| bet.created | bet-order-service | 注单创建、下注额 |
| wallet.debit.succeeded | ledger-service / ledger-writer-service | 扣款流水、余额快照 |
| bet.settled | bet-order-service / settlement-service | 结算、派彩金额 |
| callback.succeeded | callback-service | 商户回调成功 |
| merchant.transfer | merchant-gateway / admin-gateway | 商户资金调拨 |

## 禁止事项

- 不能影响下注扣款主链路。
- 不能反向修改业务库。
- 不能把 ClickHouse 作为订单事实源。
- 不能让后台统计查询反查主交易库。

## 本地命令

```bash
cd /Users/amumu/Desktop/beifen/golang新架构/数据服务/warehouse-writer
go test ./...
go build ./cmd/warehouse-writer
PORT=8110 go run ./cmd/warehouse-writer
```

## 健康检查

```bash
curl http://127.0.0.1:8110/health
curl http://127.0.0.1:8110/ready
```

## HTTP 接口

### POST /warehouse/events

批量写入数仓事件。批量上限由 `WAREHOUSE_WRITER_MAX_BATCH_SIZE` 控制，默认 500。

```bash
curl -X POST http://127.0.0.1:8110/warehouse/events \
  -H 'Content-Type: application/json' \
  -H 'X-Request-ID: trace_demo_001' \
  -d '{
    "events": [
      {
        "event_id": "evt_bet_001",
        "event_type": "bet.created",
        "trace_id": "trace_demo_001",
        "merchant_id": "merchant_001",
        "player_id": "player_001",
        "round_id": "round_001",
        "bet_order_id": "bet_001",
        "game_code": "slots_demo",
        "schema_version": "v1",
        "occurred_at": "2026-06-06T10:30:00Z",
        "source_service": "bet-order-service",
        "payload": {
          "bet_amount": 100,
          "currency": "CNY",
          "odds": "1.80"
        }
      }
    ]
  }'
```

返回示例：

```json
{
  "code": "OK",
  "message": "success",
  "request_id": "trace_demo_001",
  "data": {
    "total": 1,
    "accepted": 1,
    "duplicated": 0,
    "failed": 0,
    "results": [
      {
        "event_id": "evt_bet_001",
        "event_type": "bet.created",
        "status": "accepted",
        "record_id": "warehouse_event_xxx",
        "stored_sinks": [
          "clickhouse.warehouse_events",
          "doris.warehouse_events",
          "memory.aggregate_indexes"
        ],
        "message": "warehouse event accepted"
      }
    ]
  }
}
```

同一个 `event_id` 再次写入时返回 `duplicated`，并复用原 `record_id`。不支持的事件类型或缺少必要字段时，该事件返回 `failed`，批量中其他合法事件仍可写入。

### GET /warehouse/events/{id}

查询已写入事件状态。

```bash
curl http://127.0.0.1:8110/warehouse/events/evt_bet_001
```

未找到返回 `404` 和 `NOT_FOUND`。

## 配置

示例配置位于：

```text
数据服务/warehouse-writer/configs/config.example.yaml
```

当前代码读取环境变量：

| 环境变量 | 默认值 | 说明 |
| --- | --- | --- |
| PORT | 8110 | `httpserver.RunHealthService` 使用的 HTTP 端口 |
| WAREHOUSE_WRITER_MAX_BATCH_SIZE | 500 | 单批事件上限 |

## 与 report-service 的边界

- `warehouse-writer` 只负责接收事件、幂等写入和维护可查询的数仓模型。
- `report-service` 只负责面向后台/API 的报表查询、分页、导出和权限过滤。
- 后台统计读取优先走 `report-service`，由 `report-service` 查询 ClickHouse/Doris 的明细表或聚合表。
- `report-service` 不能要求 `warehouse-writer` 同步返回复杂报表；`warehouse-writer` 也不能反向调用 `report-service` 修正数据。

## OpenAPI

```text
数据服务/warehouse-writer/api/openapi/warehouse-writer.openapi.yaml
```
