9.9 KiB
9.9 KiB
V2 API Response Schema 细稿 — Batch Auto-Import
日期:2026-05-22
关联文档:
docs/2026-05-21-BATCH_AUTO_IMPORT_SPEC.mddocs/2026-05-21-BATCH_AUTO_IMPORT_TDD_PLAN.mddocs/2026-05-22-BATCH_AUTO_IMPORT_V2_ARCHITECTURE.mddocs/openapi.yaml
1. 目标
这份文档把 V2 结果 API 细化到 handler 和前端都可直接对照实现的粒度。
覆盖:
- 路由
- query/filter
- response schema
- error schema
- badge / 文案映射
- 示例 JSON
2. 资源模型
V2 API 只暴露 3 层资源:
runrun itemsrun 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
支持:
staterunningcompletedcompleted_with_warningsfailedcancelled
access_modesubscriptionself_service
q- 搜索
run_id / provider_id / base_url
- 搜索
limitcursor
说明:
- 页面显示可以把
completed_with_warnings渲染成warning - API 不应引入第二套
warning枚举
4.2 GET /api/batch-import/runs/{run_id}/items
支持:
current_stageprobeprovisionconfirmvalidatedone
confirmation_statuspendingconfirmedadvisoryfailed
access_statusunknownactivedegradedbroken
has_warningtrue/false
provider_idmatched_account_stateaccount_resolutionq- 搜索
provider_id / base_url / item_id
- 搜索
limitcursor
5. 通用错误结构
建议统一:
{
"error": {
"code": "invalid_request",
"message": "subscription_users is required when access_mode=subscription"
}
}
常用 code:
invalid_requestnot_foundconflictinternal_error
6. 响应 Schema
6.1 POST /api/batch-import/runs
{
"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
{
"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}
{
"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
{
"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}
{
"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 列表
默认排序:
current_stage != done的在前access_status = broken/degraded在前updated_at DESC
原因:
- 结果页首先服务“快速定位问题”
9. Handler 约束
- 列表接口只返回 projection,不返回原始 JSON 大对象
- item 详情才返回
capability_profile与events - 不在 handler 里拼装 legacy 表结果
- 任何页面要显示的 warning 文案,都从 projection 层统一生成
provision_reused、reused_from_provider_id等复用字段必须来自 projection,不允许前端自行推断matched_account_state与account_resolution也必须来自 projection,不允许前端根据 account_id 是否存在自行推断
10. 最小实现建议
实现顺序建议:
- 先做
POST /api/batch-import/runs - 再做
GET /api/batch-import/runs - 再做
GET /api/batch-import/runs/{run_id} - 再做 item 列表
- 最后做 item 详情和 event trail
理由:
- 列表页和 run 详情先能支撑运营查看批次
- 复杂度最高的是 item detail / event trail
11. 验证点
文档层:
- 是否所有状态枚举都与
SPEC/TDD/Architecture一致 - 是否还存在
warning与completed_with_warnings混用 - 是否还存在
confirmed_active等旧枚举残留
实现层:
subscription/self_service条件必填校验正确- run 列表能稳定分页
- item 详情能展示 capability + event trail
- 页面无需读取宿主数据库即可解释 warning/broken