Files
sub2api-cn-relay-manager/docs/2026-05-22-BATCH_AUTO_IMPORT_V2_API_SCHEMAS.md
2026-05-22 14:15:41 +08:00

446 lines
9.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# V2 API Response Schema 细稿 — Batch Auto-Import
日期2026-05-22
关联文档:
- `docs/2026-05-21-BATCH_AUTO_IMPORT_SPEC.md`
- `docs/2026-05-21-BATCH_AUTO_IMPORT_TDD_PLAN.md`
- `docs/2026-05-22-BATCH_AUTO_IMPORT_V2_ARCHITECTURE.md`
- `docs/openapi.yaml`
## 1. 目标
这份文档把 V2 结果 API 细化到 handler 和前端都可直接对照实现的粒度。
覆盖:
- 路由
- query/filter
- response schema
- error schema
- badge / 文案映射
- 示例 JSON
## 2. 资源模型
V2 API 只暴露 3 层资源:
1. `run`
2. `run items`
3. `run item events`
不直接暴露:
- 宿主数据库结构
- `import_batches` 细节
- legacy repo 的内部实现字段
## 3. Endpoint 列表
### 3.1 创建 run
`POST /api/batch-import/runs`
作用:
- 创建 V2 run
- 立即返回 `run_id`
- 可选等待一个短暂 confirm window但不保证全部 item 已 done
### 3.2 列表 runs
`GET /api/batch-import/runs`
作用:
- 查看最近导入批次
- 支持状态筛选和关键词搜索
### 3.3 run 详情
`GET /api/batch-import/runs/{run_id}`
作用:
- 返回 run summary
- 返回汇总告警摘要
### 3.4 item 列表
`GET /api/batch-import/runs/{run_id}/items`
作用:
- 展示批次内各 URL/provider 的状态
- 支持按 stage/access/warning 过滤
### 3.5 item 详情
`GET /api/batch-import/runs/{run_id}/items/{item_id}`
作用:
- 返回一个 item 的全量投影
- 包括 capability、模型纠错、event trail
## 4. Query 参数约定
### 4.1 `GET /api/batch-import/runs`
支持:
- `state`
- `running`
- `completed`
- `completed_with_warnings`
- `failed`
- `cancelled`
- `access_mode`
- `subscription`
- `self_service`
- `q`
- 搜索 `run_id / provider_id / base_url`
- `limit`
- `cursor`
说明:
- 页面显示可以把 `completed_with_warnings` 渲染成 `warning`
- API 不应引入第二套 `warning` 枚举
### 4.2 `GET /api/batch-import/runs/{run_id}/items`
支持:
- `current_stage`
- `probe`
- `provision`
- `confirm`
- `validate`
- `done`
- `confirmation_status`
- `pending`
- `confirmed`
- `advisory`
- `failed`
- `access_status`
- `unknown`
- `active`
- `degraded`
- `broken`
- `has_warning`
- `true/false`
- `provider_id`
- `matched_account_state`
- `account_resolution`
- `q`
- 搜索 `provider_id / base_url / item_id`
- `limit`
- `cursor`
## 5. 通用错误结构
建议统一:
```json
{
"error": {
"code": "invalid_request",
"message": "subscription_users is required when access_mode=subscription"
}
}
```
常用 `code`
- `invalid_request`
- `not_found`
- `conflict`
- `internal_error`
## 6. 响应 Schema
### 6.1 `POST /api/batch-import/runs`
```json
{
"run_id": "run_20260522_0001",
"state": "running",
"result_page": "/batch-import/runs/run_20260522_0001",
"total_items": 2,
"active_items": 0,
"degraded_items": 0,
"broken_items": 0,
"warning_items": 0
}
```
约束:
- 这是 `run created` 语义,不是 final result
- `state` 初始一般是 `running`
### 6.2 `GET /api/batch-import/runs`
```json
{
"runs": [
{
"run_id": "run_20260522_0001",
"state": "completed_with_warnings",
"mode": "partial",
"access_mode": "subscription",
"total_items": 2,
"completed_items": 2,
"active_items": 1,
"degraded_items": 1,
"broken_items": 0,
"warning_items": 1,
"started_at": "2026-05-22T12:20:00+08:00",
"finished_at": "2026-05-22T12:20:07+08:00"
}
],
"next_cursor": null
}
```
### 6.3 `GET /api/batch-import/runs/{run_id}`
```json
{
"run": {
"run_id": "run_20260522_0001",
"state": "completed_with_warnings",
"mode": "partial",
"access_mode": "subscription",
"total_items": 2,
"completed_items": 2,
"active_items": 1,
"degraded_items": 1,
"broken_items": 0,
"warning_items": 1,
"started_at": "2026-05-22T12:20:00+08:00",
"finished_at": "2026-05-22T12:20:07+08:00"
},
"recent_warnings": [
"该批次包含 1 条 advisory item建议检查 capability profile 与 retry 轨迹"
]
}
```
### 6.4 `GET /api/batch-import/runs/{run_id}/items`
```json
{
"items": [
{
"item_id": "item_01",
"base_url": "https://kimi.a7m.com.cn/v1",
"provider_id": "kimi-a7m-7d7ac291",
"api_key_fingerprint": "sha256:8d8c4b5f",
"requested_models": ["kimi-k2.6"],
"canonical_model_families": ["kimi-k2.6"],
"resolved_smoke_model": "kimi-k2.6",
"current_stage": "done",
"confirmation_status": "advisory",
"access_status": "active",
"matched_account_state": "active",
"account_resolution": "reused",
"provision_reused": true,
"retry_count": 2,
"last_retry_at": "2026-05-22T12:20:05+08:00",
"advisory_messages": [
"该上游不支持 /v1/responses系统已自动回退到 /v1/chat/completions"
],
"last_error_stage": "confirm",
"last_error": "API returned 403: Forbidden"
}
],
"next_cursor": null
}
```
### 6.5 `GET /api/batch-import/runs/{run_id}/items/{item_id}`
```json
{
"item_id": "item_01",
"base_url": "https://kimi.a7m.com.cn/v1",
"provider_id": "kimi-a7m-7d7ac291",
"api_key_fingerprint": "sha256:8d8c4b5f",
"requested_models": ["kimi-k2.6"],
"raw_models": ["kimi-k2.6"],
"normalized_models": ["kimi-k2.6"],
"canonical_model_families": ["kimi-k2.6"],
"recommended_models": [],
"resolved_smoke_model": "kimi-k2.6",
"current_stage": "done",
"confirmation_status": "advisory",
"access_status": "active",
"matched_account_state": "deprecated",
"account_resolution": "reactivated",
"provision_reused": true,
"reused_from_provider_id": "kimi-a7m-7d7ac291",
"reused_from_account_id": 4,
"retry_count": 2,
"last_retry_at": "2026-05-22T12:20:05+08:00",
"channel_id": 12,
"account_id": 4,
"advisory_messages": [
"该上游不支持 /v1/responses系统已自动回退到 /v1/chat/completions"
],
"last_error_stage": "confirm",
"last_error": "API returned 403: Forbidden",
"capability_profile": {
"transport_profile": {
"supports_openai_models": true,
"supports_openai_chat_completions": true,
"supports_openai_responses": false,
"supports_anthropic_messages": false,
"auth_style": "bearer",
"model_id_style": "canonical",
"known_advisories": [
"responses_unsupported_but_chat_ok",
"initial_probe_race_expected"
]
},
"model_profiles": [
{
"raw_model_id": "kimi-k2.6",
"normalized_model_id": "kimi-k2.6",
"canonical_model_family": "kimi-k2.6",
"supports_stream": true,
"supports_tools": "unknown",
"supports_reasoning_fields": "unknown",
"smoke_chat_ok": true
}
]
},
"events": [
{
"event_id": "evt_01",
"event_type": "retry_scheduled",
"stage": "confirm",
"attempt": 1,
"message": "initial 503 no available accounts, retry scheduled",
"payload_json": "{\"delay_ms\":500}",
"created_at": "2026-05-22T12:20:04+08:00"
}
]
}
```
## 7. Badge / 文案映射
### 7.1 Run state badge
| API 值 | 页面 badge |
|---|---|
| `running` | 蓝色 `running` |
| `completed` | 绿色 `completed` |
| `completed_with_warnings` | 黄色 `warning` |
| `failed` | 红色 `failed` |
| `cancelled` | 灰色 `cancelled` |
### 7.2 Confirmation badge
| API 值 | 页面 badge |
|---|---|
| `pending` | 蓝色 `pending` |
| `confirmed` | 绿色 `confirmed` |
| `advisory` | 黄色 `advisory` |
| `failed` | 红色 `failed` |
### 7.3 Access badge
| API 值 | 页面 badge |
|---|---|
| `unknown` | 灰色 `unknown` |
| `active` | 绿色 `active` |
| `degraded` | 黄色 `degraded` |
| `broken` | 红色 `broken` |
### 7.4 Reuse badge
| 字段 | 页面 badge |
|---|---|
| `provision_reused=true` | 青色 `reused` |
| `provision_reused=false` | 不显示 |
### 7.5 Account state badge
| 字段 | 页面 badge |
|---|---|
| `matched_account_state=active` | 绿色 `已启用` |
| `matched_account_state=disabled` | 灰色 `已停用` |
| `matched_account_state=deprecated` | 黄色 `已弃用` |
| `matched_account_state=broken` | 红色 `已损坏` |
### 7.6 Account resolution badge
| 字段 | 页面 badge |
|---|---|
| `account_resolution=created` | 蓝色 `新建` |
| `account_resolution=reused` | 青色 `复用` |
| `account_resolution=reactivated` | 绿色 `已快速启用` |
| `account_resolution=replaced` | 红色 `已替换` |
## 8. 分页与排序建议
### 8.1 Runs 列表
默认排序:
- `started_at DESC`
### 8.2 Items 列表
默认排序:
1. `current_stage != done` 的在前
2. `access_status = broken/degraded` 在前
3. `updated_at DESC`
原因:
- 结果页首先服务“快速定位问题”
## 9. Handler 约束
1. 列表接口只返回 projection不返回原始 JSON 大对象
2. item 详情才返回 `capability_profile``events`
3. 不在 handler 里拼装 legacy 表结果
4. 任何页面要显示的 warning 文案,都从 projection 层统一生成
5. `provision_reused``reused_from_provider_id` 等复用字段必须来自 projection不允许前端自行推断
6. `matched_account_state``account_resolution` 也必须来自 projection不允许前端根据 account_id 是否存在自行推断
## 10. 最小实现建议
实现顺序建议:
1. 先做 `POST /api/batch-import/runs`
2. 再做 `GET /api/batch-import/runs`
3. 再做 `GET /api/batch-import/runs/{run_id}`
4. 再做 item 列表
5. 最后做 item 详情和 event trail
理由:
- 列表页和 run 详情先能支撑运营查看批次
- 复杂度最高的是 item detail / event trail
## 11. 验证点
文档层:
- 是否所有状态枚举都与 `SPEC/TDD/Architecture` 一致
- 是否还存在 `warning``completed_with_warnings` 混用
- 是否还存在 `confirmed_active` 等旧枚举残留
实现层:
1. `subscription/self_service` 条件必填校验正确
2. run 列表能稳定分页
3. item 详情能展示 capability + event trail
4. 页面无需读取宿主数据库即可解释 warning/broken