build_campaign_timeline flattens a campaign's child Runs into offset-sorted
per-Run entries (distinct from the report's 12-bucket aggregation), reusing a
shared _run_window_offset口径 so both views place a run identically. Exposes
GET /campaigns/{id}/timeline and the api.ts type/call. (v0.6 ticket 06)
15 lines
1.5 KiB
Markdown
15 lines
1.5 KiB
Markdown
# 06 — 后端时间轴接缝 + `GET /campaigns/{id}/timeline`
|
||
|
||
**What to build:** 一个纯函数把某活动的全部子 Run 映射成「逐 Run 时间轴条目」——每条含 run_id、场景 id/名、加速后窗口偏移(`(started_at − campaign.started_at) × time_scale`,clamp 到 `[0, window_seconds]`)、状态、通过率(取子 Run summary,只读不重算)、平均时延、started_at;未开始/取消的子 Run 在函数内有明确定义的处理。再暴露一个只读端点 `GET /campaigns/{id}/timeline` 返回 `{entries: [...]}`(逐 Run 扁平数组,区别于报告的 12 桶聚合),并在前端 `api.ts` 加对应类型与调用。curl / 测试即可验证。
|
||
|
||
**Blocked by:** 无 —— 可立即开始。
|
||
|
||
**Status:** ready-for-agent
|
||
|
||
- [ ] 新增纯函数 `build_campaign_timeline(campaign, runs)`(放 `evaluation/report.py` 或紧邻模块),偏移口径复用现有报告的 `× time_scale` + clamp。
|
||
- [ ] 单测覆盖:正常偏移(含 time_scale 压缩)、clamp 到窗口边界、未开始子 Run、取消/失败子 Run、字段映射(pass_rate 取自 summary、场景名映射)、空活动。仿 `test_campaign_report.py`。
|
||
- [ ] 新增 `GET /campaigns/{id}/timeline` → `{entries}`;404 当活动不存在。
|
||
- [ ] 端点集成测试(200 字段形状 + 404),仿现有 campaigns router 测试。
|
||
- [ ] `api.ts` 增加 `CampaignTimelineEntry` 类型与 `campaignsApi.timeline(id)`。
|
||
- [ ] `pytest` 全绿、`ruff check backend/` 通过。
|