# H1 月度归档拉取管道（2026-07-28）

## 背景

H1（1-6月）订单数据量过大（单月 1500+ work_item → 700+ 订单），一次性拉取超时。改为按月分批拉取，存档后永久复用。

## 脚本

`数据/pull_h1_archive.py`

```bash
# 单月拉取（约 60-120s/月，视订单量）
python3 pull_h1_archive.py --m01   # 1月
python3 pull_h1_archive.py --m02   # 2月
...
python3 pull_h1_archive.py --m06   # 6月

# 全量（按顺序跑 6 次）
python3 pull_h1_archive.py --h1
```

## 输出

| 文件 | 内容 |
|------|------|
| `h1_archive/m01_orders.json` | 1月订单明细 |
| ... | ... |
| `h1_archive/m06_orders.json` | 6月订单明细 |
| `h1_archive/h1_all.json` | 合并后的 H1 全量（4,063 条） |

## 关键决策

### 角色获取：用客户→销售员映射，不逐条调 get_workitem_brief

H1 存档是静态历史数据，逐条调 `get_workitem_brief` 耗时过长（700+ × 0.3s = 3.5min+/月）。改用 `mcp_customers.json` 的 `owner` 字段映射"下单人"——虽可能指向离职人员，但 H1 数据仅用于订单明细列表，不影响当前 KPI。

### H2 动态数据仍用 get_workitem_brief

H2 实时订单（`pull_orders.py`）继续调用 `get_workitem_brief` 获取"下单人"角色——有 `order_role_cache.json` 缓存，后续仅查新增订单。

## 合并到前端

`merge_workbench_data.py` 在每次管线运行时：
1. 读取 `h1_archive/h1_all.json`
2. 读取 `shipment_status.json`（H2 动态）
3. H1 订单补默认 `shipment: {status: 'archived', statusLabel: 'H1 归档'}`
4. H1 + H2 去重合并 → 注入 `shipments.orders`
5. 输出 `workbench_data.json`

```python
seen = set(o.get('orderId','') for o in h1_orders)
for o in h1_orders:
    if not o.get('shipment'):
        o['shipment'] = {'status': 'archived', 'statusLabel': 'H1 归档'}
merged = h1_orders + [o for o in h2_orders if o.get('orderId','') not in seen]
```

## 月度校对

`脚本/reconcile_monthly.py` — 每月 3 号 cron 触发：
- 对比 H1 存档 MCP 金额 vs KPI H1 实际
- H2 动态 MCP 金额 vs KPI Progress
- 全年累计达成率
- 生成 `h1_archive/reconcile_YYYY-MM.md` 报告

## 数据量参考（2026年7月实测）

| 月份 | Work Items | 唯一订单 | 税合计(MCP) |
|------|-----------|---------|------------|
| 1月 | 1,581 | 751 | 170.1万 |
| 2月 | 818 | 374 | 81.3万 |
| 3月 | 1,725 | 832 | 251.2万 |
| 4月 | 1,567 | 743 | 190.6万 |
| 5月 | 1,389 | 650 | 129.4万 |
| 6月 | 1,521 | 713 | 229.2万 |
| **合计** | **8,601** | **4,063** | **1,052.0万** |

> ⚠️ MCP 税合计 1,052 万 vs KPI H1 实际 2,164 万——差异源于 MCP `价税合计` 字段为 0。
