# MCP 数据管道架构模式

## 核心模式：H1归档 + H2实时 + 自动归档

2026全量4128条/2303.9万价税。全量刷新需5分钟/8MB。分层后H2仅343条/30秒刷新。

```
全量MCP拉取(去掉物流单号过滤, 10096行) 
    → 按单据编号合并(金额/价税/数量累加)
    → 分类:
        H1(≤2026-06-30) → h1_archive.json (3KB纯汇总)
        H2已签收>7天 → 自动归档到H1
        H2其它 → h2_live.json + shipment_status.json (实时)
```

### 关键决策点

| 决策 | 说明 |
|------|------|
| 按单据编号合并而非物流单号 | 同一订单多行物料需累加金额，否则金额严重偏低 |
| 去掉物流单号过滤 | 无物流订单也要计入金额统计（标注"无物流"） |
| H1仅保留汇总 | 3536条H1明细 → 3KB月度/客户/部门汇总 |
| H2保留明细 | 343条实时数据 → shipment_status.json + 顺丰轨迹 |
| 已签收>7天自动归档 | `get_delivery_date() <= (today - 7天)` → 归入H1 |

### 文件结构

```
数据/
├── h1_archive.json       3KB   H1汇总(月度金额/客户/部门/Top10)
├── h2_live.json          1.5MB H2实时明细(含顺丰轨迹)
├── mcp_customers.json    200KB 全量客户+2026金额汇总
├── orders_dashboard.json  1KB   看板用聚合(H1+H2)
└── shipment_status.json  2MB   H2明细+H1汇总指标(前端主数据源)
```

### shipment_status.json 结构

```json
{
  "updated_at": "2026-07-25 00:14:00",
  "total": 343,
  "orders": [...],
  "h1_summary": {
    "total_orders": 3785,
    "total_tax": 21546400,
    "delivered": 685
  },
  "full_year_tax": 23039000,
  "mcp_customer_count": 1678,
  "mcp_contact_count": 7723
}
```

### 刷新策略

| 层级 | 频率 | 方式 | 耗时 |
|------|------|------|------|
| H1归档 | 季度末手动 | 全量MCP拉取+顺丰查询 | 5分钟 |
| H2实时 | 每日cron | 仅拉H2未签收订单+顺丰轨迹 | 30秒 |
| 客户表 | 按月 | MCP客户表拉取+订单金额汇总 | 3分钟 |
| 联系人数 | 按月 | MCP客户`联系人数量`字段汇总 | 30秒 |

### 自动归档逻辑

```python
archive_cutoff = (datetime.now() - timedelta(days=7)).strftime("%Y-%m-%d")

for order in all_orders:
    if order["createDate"] <= "2026-06-30":
        h1_archive.append(order)  # H1全部归档
    elif order["shipment"]["status"] == "delivered":
        dd = order["shipment"]["routes"][-1]["acceptTime"][:10]
        if dd <= archive_cutoff:
            h1_archive.append(order)  # 已签收>7天 → 归档
    else:
        h2_live.append(order)
```

### MCP 直连 RPC 模式

```python
URL = "https://project.feishu.cn/mcp_server/v1"
TOKEN = "m-abfb29e8-3104-434f-9944-8d0bb592f8cd"  # 从 config.yaml

# 初始化
resp, sid = rpc({"jsonrpc":"2.0","id":1,"method":"initialize",
    "params":{"protocolVersion":"2024-11-05","capabilities":{},
              "clientInfo":{"name":"script","version":"1.0"}}})
# 通知
rpc({"jsonrpc":"2.0","method":"notifications/initialized"}, sid)

# 查询
call = {"jsonrpc":"2.0","id":2,"method":"tools/call",
        "params":{"name":"search_by_mql",
                  "arguments":{"project_key":"6593cd71471290e3cc6be6e6","mql":"..."}}}
resp, sid = rpc(call, sid)
```

### Pitfalls

1. **MCP会话过期**：单个session拉63页约第34页开始全部失败 → 每20页重建session
2. **JSON解析**：用 `JSONDecoder.raw_decode(content.strip())` 代替 `re.search(r"\{.*\}", content)`
3. **文件覆盖保护**：写入前 `shutil.copy2(OUTPUT, OUTPUT + ".bak")`
4. **字段类型处理**：`user_value_list` → 取 `name_cn` 非 `name`；`double_value` → 取 `double_value` 非 `string_value`
5. **delegate_task限制**：MCP+顺丰API同时做 → 10分钟超时；K3配额 → HTTP 403。大数据任务用终端直跑Python脚本
