docs: 全套文档与代码对齐(P1-1,数据源收敛 bzzoiro 后的存量漂移清理)
- 数据源:全部文档统一为 bzzoiro 唯一来源,删除 understat/api-football 作为现行数据源的表述(仅保留历史注记);.env.example/docs/06 移除 失效的 API_FOOTBALL_KEY - 多 Agent:injuries 阵容完整性 → standings 联赛排名 (README/01/04 的专家表、数据流图、no_data 示例、agent_weights、 prompt 清单全部对齐 form/stats/home_away/standings/h2h) - 数据库:6 张表 → 12 张表,补 standings/app_settings/schedules 与 4 张治理表说明(标注 raw_events/data_quality_checks/data_lineage 为预留未启用,ingest_failures 已启用),predictions 补 agent_weights 列 - API 文档(03):新增鉴权模型三档表;context/standings/leagues 公开端点 补全;predictions/eval/backtest 标注需管理员;ingest/bzzoiro 补 task/limit/season 参数契约,删除 understat/injuries 端点小节 - 目录树(README/01/07):与真实 src/、frontend/src 结构一致 (core 7 文件、data 7 文件、移除不存在的 retry.py) - 采集命令(02/05):understat 回填 → task=stats/standings; 补管理员凭据提示;docs/08 文首标注历史/过时
This commit is contained in:
+80
-34
@@ -4,18 +4,30 @@ Base URL: `http://localhost:8000` · 交互式文档: `/docs`(Swagger)与 `/redo
|
||||
|
||||
所有数据端点返回 JSON。错误统一为 `{"detail": "<message>"}` + 对应 HTTP 状态码。
|
||||
|
||||
## 鉴权模型
|
||||
|
||||
| 级别 | 端点 | 说明 |
|
||||
|---|---|---|
|
||||
| **公开只读** | `GET /leagues`、`GET /matches`、`GET /matches/{id}`、`GET /matches/{id}/context`、`GET /standings`、`GET /health*` | 无需任何凭据;公开站直接调用 |
|
||||
| **公开 + 限流** | `POST /predict` | 内存滑动窗口限流(10 次/分钟/IP) |
|
||||
| **需管理员** | `GET /predictions*`、`POST /ingest/bzzoiro`、`/eval/*`、`POST /backtest`、`/admin/**` | Cookie 会话(`POST /auth/login` 颁发)或 `X-API-Key` 头 |
|
||||
|
||||
管理端点在生产环境未配置鉴权时 fail-closed(503),不会静默放行。
|
||||
|
||||
---
|
||||
|
||||
## 数据查询
|
||||
## 数据查询(公开只读)
|
||||
|
||||
### `GET /api/v1/leagues`
|
||||
|
||||
列出已入库联赛。
|
||||
列出已入库联赛(P1-3: 公开站联赛筛选动态加载来源)。
|
||||
|
||||
```json
|
||||
[{"id": 1, "code": "E0", "name": "Premier League", "country": "England"}]
|
||||
```
|
||||
|
||||
仅返回 `id/code/name/country` 四个展示字段,不含任何配置或密钥信息。
|
||||
|
||||
### `GET /api/v1/matches`
|
||||
|
||||
比赛列表,游标分页。
|
||||
@@ -47,7 +59,44 @@ Base URL: `http://localhost:8000` · 交互式文档: `/docs`(Swagger)与 `/redo
|
||||
|
||||
### `GET /api/v1/matches/{id}`
|
||||
|
||||
单场比赛详情,字段同上。
|
||||
单场比赛详情,字段同上,另含 `stats`(统计)与 `recent_predictions`(最近 5 条预测摘要)。
|
||||
|
||||
### `GET /api/v1/matches/{id}/context`
|
||||
|
||||
比赛上下文(公开只读,P1-2: 公开站详情页「近况/交锋」数据来源;不触发 LLM):
|
||||
|
||||
- `home_recent`: 主队最近 5 场已完赛
|
||||
- `away_recent`: 客队最近 5 场已完赛
|
||||
- `h2h`: 双方最近 5 次交手
|
||||
|
||||
```json
|
||||
{
|
||||
"home_recent": [
|
||||
{"match_date": "2026-09-12T14:00:00+00:00", "home_team": "阿森纳",
|
||||
"away_team": "切尔西", "home_goals": 2, "away_goals": 1}
|
||||
],
|
||||
"away_recent": [],
|
||||
"h2h": []
|
||||
}
|
||||
```
|
||||
|
||||
数据不足时对应列表为空(前端展示空态)。比赛不存在返回 404。
|
||||
|
||||
### `GET /api/v1/standings`
|
||||
|
||||
联赛积分榜(公开只读)。参数:`league`(联赛代码,空 = 全部)、`season`(空 = 各联赛最新赛季)。
|
||||
|
||||
```json
|
||||
{"leagues": [
|
||||
{"league_code": "E0", "league_name": "Premier League", "season": "2026-2027",
|
||||
"retrieved_at": "2026-09-20T08:00:00+00:00",
|
||||
"rows": [{"position": 1, "team": "阿森纳", "team_en": "Arsenal",
|
||||
"played": 5, "won": 4, "drawn": 1, "lost": 0,
|
||||
"goals_for": 11, "goals_against": 3, "goal_diff": 8,
|
||||
"points": 13, "xg_for": 9.8, "xg_against": 3.9,
|
||||
"form": "WWWDW", "zone": "UEFA Champions League"}]}
|
||||
]}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -96,13 +145,13 @@ Base URL: `http://localhost:8000` · 交互式文档: `/docs`(Swagger)与 `/redo
|
||||
"exp_home_goals": null, "exp_away_goals": null, "probable_score": null,
|
||||
"model": "gpt-4o-mini", "latency_ms": 2100,
|
||||
"prompt_tokens": 380, "completion_tokens": 120},
|
||||
{"agent": "injuries", "status": "no_data", "data_sufficiency": "none",
|
||||
{"agent": "standings", "status": "no_data", "data_sufficiency": "none",
|
||||
"analysis": "该维度无数据,跳过分析。", "home_edge": null, "subjective_confidence": null,
|
||||
"key_evidence": [], "exp_home_goals": null, "exp_away_goals": null,
|
||||
"probable_score": null, "model": "", "latency_ms": null,
|
||||
"prompt_tokens": null, "completion_tokens": null}
|
||||
],
|
||||
"agent_weights": {"form": 0.9, "stats": 0.8, "home_away": 0.7, "injuries": 0.0, "h2h": 0.8},
|
||||
"agent_weights": {"form": 0.9, "stats": 0.8, "home_away": 0.7, "standings": 0.8, "h2h": 0.8},
|
||||
"context": "[5 份报告的 JSON 串]",
|
||||
"latency_ms": 9800
|
||||
}
|
||||
@@ -112,11 +161,11 @@ Base URL: `http://localhost:8000` · 交互式文档: `/docs`(Swagger)与 `/redo
|
||||
|
||||
错误:404 比赛不存在;502 LLM 调用失败(终裁失败时整体失败,专家失败不会)。
|
||||
|
||||
### `GET /api/v1/predictions?match_id=&limit=`
|
||||
### `GET /api/v1/predictions?match_id=&limit=`(需管理员)
|
||||
|
||||
预测历史(倒序),含 `settled` 与实际比分回填状态。
|
||||
|
||||
### `GET /api/v1/predictions/{id}`
|
||||
### `GET /api/v1/predictions/{id}`(需管理员)
|
||||
|
||||
单条预测详情(含完整 `agent_outputs`)。
|
||||
|
||||
@@ -124,40 +173,34 @@ Base URL: `http://localhost:8000` · 交互式文档: `/docs`(Swagger)与 `/redo
|
||||
|
||||
## 数据采集
|
||||
|
||||
### `POST /api/v1/ingest/bzzoiro`
|
||||
### `POST /api/v1/ingest/bzzoiro`(需管理员)
|
||||
|
||||
从 bzzoiro 采集赛果/赛程并入库(幂等,重复跑安全)。
|
||||
从 bzzoiro(唯一数据源)采集数据并入库(幂等,重复跑安全)。任务在后台异步执行,请求立即返回。
|
||||
|
||||
```json
|
||||
{"leagues": ["E0", "SP1"], "date_from": "2025-08-01", "date_to": "2026-09-08", "status": "finished"}
|
||||
{"task": "all", "leagues": ["E0", "SP1"], "date_from": "2025-08-01", "date_to": "2026-09-08", "status": "finished"}
|
||||
```
|
||||
|
||||
- `status` 还可传 `scheduled` 拉未来赛程
|
||||
| 字段 | 默认 | 说明 |
|
||||
|---|---|---|
|
||||
| `task` | `events` | 采集任务:`events`(比赛)/ `standings`(积分榜)/ `stats`(统计回填,含 xG)/ `all` |
|
||||
| `leagues` | 全部已知联赛 | 联赛代码列表,如 `["E0", "SP1"]` |
|
||||
| `date_from` / `date_to` | 空 | 日期范围(`YYYY-MM-DD`) |
|
||||
| `status` | 空(两者都采) | `finished`(已完赛)/ `scheduled`(未来赛程) |
|
||||
| `season` | 当前赛季 | standings 赛季,如 `"2026-2027"` |
|
||||
| `limit` | 100 | stats 回填单次最大比赛数(1–500) |
|
||||
|
||||
- 响应含每联赛 `inserted`/`updated`/`errors` 统计
|
||||
- `task=stats` 只补空字段、不创建比赛(xG/射门/控球等统计回填)
|
||||
|
||||
### `POST /api/v1/ingest/understat`
|
||||
|
||||
回填 xG(只补空字段,不创建比赛):
|
||||
|
||||
```json
|
||||
{"league": "E0", "season": 2025}
|
||||
```
|
||||
|
||||
`season=2025` 表示 2025-2026 赛季。仅支持五大联赛。
|
||||
|
||||
### `POST /api/v1/ingest/injuries`
|
||||
|
||||
采集伤停(需 `API_FOOTBALL_KEY`,当前只返回计数,尚未接入 context):
|
||||
|
||||
```json
|
||||
{"date": "2026-09-10"}
|
||||
```
|
||||
> 历史版本曾有独立的 understat(xG)与 injuries(伤停)采集端点,
|
||||
> 已随数据源收敛为 bzzoiro 唯一来源而移除。
|
||||
|
||||
---
|
||||
|
||||
## 评估
|
||||
|
||||
### `POST /api/v1/eval/settle`
|
||||
### `POST /api/v1/eval/settle`(需管理员)
|
||||
|
||||
赛后回填实际比分:
|
||||
|
||||
@@ -165,7 +208,7 @@ Base URL: `http://localhost:8000` · 交互式文档: `/docs`(Swagger)与 `/redo
|
||||
{"prediction_id": 7, "home_goals": 2, "away_goals": 1}
|
||||
```
|
||||
|
||||
### `GET /api/v1/eval/summary`
|
||||
### `GET /api/v1/eval/summary`(需管理员)
|
||||
|
||||
按 `provider × model` 聚合已结算预测:
|
||||
|
||||
@@ -183,7 +226,10 @@ Base URL: `http://localhost:8000` · 交互式文档: `/docs`(Swagger)与 `/redo
|
||||
|
||||
## 基础
|
||||
|
||||
| 端点 | 说明 |
|
||||
|---|---|
|
||||
| `GET /health` | 存活检查 |
|
||||
| `GET /docs` | Swagger UI |
|
||||
| 端点 | 权限 | 说明 |
|
||||
|---|---|---|
|
||||
| `GET /health` | 公开 | 存活检查 |
|
||||
| `GET /docs`、`GET /redoc` | 公开 | Swagger UI / ReDoc |
|
||||
| `POST /auth/login`、`POST /auth/logout`、`GET /auth/me` | 公开 | 管理员 Cookie 会话登录/登出/当前用户 |
|
||||
| `POST /auth/change-password` | 需管理员 | 修改管理员密码 |
|
||||
| `POST /backtest` | 需管理员 | 历史回测(对已完赛比赛批量预测并评估) |
|
||||
|
||||
Reference in New Issue
Block a user