# Wave 1 F2-1 — 恢复 OpenAPI 抓取脚本 + 重抓 backend-api.json

| 字段 | 值 |
|---|---|
| 日期 | 2026-05-04 |
| Wave | 1 / Wave 2 前(立即处理) |
| 范围 | F2-1A 恢复 `_export_openapi.py` + 重抓 backend-api.json + diff 核对 |
| 文件改动 | 2 文件(脚本恢复 + JSON 重抓)|

## 一、恢复操作

### 1.1 从 _DEL/ 恢复脚本

```bash
cp _DEL/_DEL/scripts/ops/_export_openapi.py scripts/ops/_export_openapi.py
```

文件内容(13 行):
```python
"""从运行中的 FastAPI app 导出 OpenAPI spec 到 docs/contracts/openapi/backend-api.json"""
import json
import pathlib
import sys

sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[2] / "apps" / "backend"))
from app.main import app

spec = app.openapi()
out = pathlib.Path(r"C:\Project\NeoZQYY\docs\contracts\openapi\backend-api.json")
out.write_text(json.dumps(spec, ensure_ascii=False, indent=2), encoding="utf-8")
print(f"Done: {len(spec['paths'])} paths, {len(spec['components']['schemas'])} schemas")
```

**未做改动**(脚本本身无 bug,仅是被误归档)。

### 1.2 立即重抓

```bash
.venv/Scripts/python.exe scripts/ops/_export_openapi.py
# Done: 167 paths, 234 schemas
```

## 二、Diff 核对(Neo 反馈"看下 json 内容是否和当前情况相一致")

| 维度 | git HEAD(2026-04-06)| 重抓(2026-05-04)| 差异 |
|---|---|---|---|
| paths | 137 | **167** | **+30** |
| schemas | 194 | **234** | +40 |
| removed | 0 | 0 | 后端无废弃 |

### 30 个新增端点(28 天积累)

按业务模块分组:

**admin-ai 系列**(5):
- `/api/admin/ai/prewarm/progress`
- `/api/admin/ai/run/{app_type}`
- `/api/admin/ai/trigger-event`
- `/api/admin/ai/triggers`(GET&PATCH)
- `/api/admin/ai/triggers/{trigger_id}`

**admin-runtime-context 系列**(3):
- `/api/admin/runtime-context`
- `/api/admin/runtime-context/sites`
- `/api/config/runtime-context`

**admin-task-engine 系列**(7):
- `/api/admin/task-engine/clear-all-tasks`(P0-6 高危)
- `/api/admin/task-engine/config`、`/config/{param_id}`
- `/api/admin/task-engine/pending-review`、`/pending-review/{task_id}/close`、`/reassign`
- `/api/admin/task-engine/transfer-log`、`/transfer-log/{member_id}/history`

**admin-triggers**(1):
- `/api/admin/triggers/unified`(P1-6 三 API 之一)

**admin-db-health**(1):
- `/api/admin/db-health`

**execution / internal / trigger-jobs**(5):
- `/api/execution/cleanup-output`
- `/api/internal/etl-completed`
- `/api/internal/run-job`
- `/api/trigger-jobs`、`/trigger-jobs/{job_id}/config`、`/{job_id}/run`

**xcx 系列**(5):
- `/api/xcx/avatar/upload`、`/avatar/{user_id}`
- `/api/xcx/coaches/{coach_id}/banner`
- `/api/xcx/customers/{customer_id}/consumption-records`
- `/api/xcx/runtime/clock`
- `/api/xcx/tasks/by-member/{member_id}`

**结论**:30 个新增端点全部为 28 天内合理迭代,**0 个 removed**(无废弃),与代码完全一致。

## 三、修正 W1-T7 批 1 PRD 总览的端点数

之前 `docs/_overview/admin-api-prd/00-overview.md` 写"151 端点 / 34 标签",来源是旧 backend-api.json。**正确数字应为 167 端点**。

W1-T7 批 1 内的 23 端点中,Wave 0 标记"OpenAPI 缺 10 个" — 现已全部出现在新 spec 中(本次重抓覆盖到了)。

## 四、风险与回滚

| 项 | 风险 | 回滚 |
|---|---|---|
| 脚本恢复 | 低 — 13 行简单逻辑 | `git rm scripts/ops/_export_openapi.py` |
| backend-api.json 重抓 | 低 — 内容反映真实 router | `git checkout HEAD -- docs/contracts/openapi/backend-api.json` |

## 五、F2-1B(后续):防御机制

**留 Wave 2-3 实施**:
1. 加 PostToolUse hook 匹配 `apps/backend/app/routers/*.py`,提醒"router 已改,记得跑 `python scripts/ops/_export_openapi.py`"
2. 在 `.claude/commands/spec-close.md` L45 补脚本调用命令(从"手工同步"升级为"具体命令")
3. (可选)CI 加一步:对比 `/openapi.json` vs `backend-api.json`,不一致则失败

## 六、commit 建议

```
fix(tools): 恢复 OpenAPI 抓取脚本 + 重抓 backend-api.json (W1 / F2-1A)

历史: 2026-04-06 commit 779b2f6 大批量清理时被 Claude Opus 4.6 误归档
     到 _DEL/_DEL/scripts/ops/_export_openapi.py, 28 天 stale。

恢复:
- cp _DEL/_DEL/scripts/ops/_export_openapi.py scripts/ops/
- 跑脚本重抓: 137 -> 167 paths (新增 30) / 194 -> 234 schemas
- 0 个 removed (后端无废弃)

新增 30 端点分布: admin-ai 5 + runtime-context 3 + task-engine 7 +
triggers 1 + db-health 1 + execution/internal/trigger-jobs 5 + xcx 5

详细 diff 见审计文档。
```
