1
0
Files
DiAL/openspec/specs/probe-api/spec.md

133 lines
6.5 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.
## Purpose
定义拨测系统的 REST API 端点:总览统计、目标列表含分组和结构化采样数据、带时间范围和分页的历史记录、按时间范围的趋势聚合。
## Requirements
### Requirement: 总览统计 API
系统 SHALL 提供 `GET /api/summary` 端点,返回所有目标的总体统计信息(不含平均耗时)。
#### Scenario: 获取总览统计
- **WHEN** 客户端请求 `GET /api/summary`
- **THEN** 系统 SHALL 返回 JSON 包含 total总目标数、up正常数、down异常数、lastCheckTime最近一次检查时间
### Requirement: 目标列表 API
系统 SHALL 提供 `GET /api/targets` 端点,返回所有 typed target 及其最新状态、分组信息和结构化采样数据。
#### Scenario: 获取目标列表
- **WHEN** 客户端请求 `GET /api/targets`
- **THEN** 系统 SHALL 返回 JSON 数组每个元素包含目标基本信息id、name、group、type、target、interval、最近一次检查结果timestamp、matched、durationMs、statusDetail、failure、统计摘要totalChecks、availability和结构化采样数据 recentSamples代替原 sparkline
#### Scenario: 目标无历史记录
- **WHEN** 某目标尚未执行过任何拨测
- **THEN** 其 latestCheck 为 nullrecentSamples 为空数组
### Requirement: 历史记录 API
系统 SHALL 提供 `GET /api/targets/:id/history` 端点,支持时间范围筛选和分页返回指定目标的拨测记录。
#### Scenario: 获取指定时间范围内的历史记录
- **WHEN** 客户端请求 `GET /api/targets/1/history?from=ISO&to=ISO&page=1&pageSize=20`
- **THEN** 系统 SHALL 返回带分页信息的历史记录,包含 items、total、page、pageSize按时间倒序排列
#### Scenario: 使用默认分页参数
- **WHEN** 客户端请求 `GET /api/targets/1/history?from=ISO&to=ISO`(未指定 page 或 pageSize
- **THEN** 系统 SHALL 使用默认 page=1, pageSize=20
#### Scenario: from 或 to 参数缺失
- **WHEN** 客户端请求 `GET /api/targets/1/history` 未提供 from 或 to 参数
- **THEN** 系统 SHALL 返回 400 状态码和错误信息
### Requirement: 趋势 API 支持时间范围
系统 SHALL 提供 `GET /api/targets/:id/trend` 端点,支持 `from``to` 查询参数指定时间范围。
#### Scenario: 指定时间范围查询趋势
- **WHEN** 客户端请求 `GET /api/targets/1/trend?from=ISO&to=ISO`
- **THEN** 系统 SHALL 返回指定时间范围内按小时分组的聚合数据
#### Scenario: from 或 to 参数缺失
- **WHEN** 客户端请求 `GET /api/targets/1/trend` 未提供 from 或 to 参数
- **THEN** 系统 SHALL 返回 400 状态码和错误信息
### Requirement: 目标列表返回分组和采样数据
`GET /api/targets` SHALL 返回每个目标的分组信息和结构化采样数据,替代原有 sparkline。
#### Scenario: 返回分组信息
- **WHEN** 客户端请求 `GET /api/targets`
- **THEN** 响应中每个目标 SHALL 包含 `group` 字段,值为该目标所属的分组名称
#### Scenario: 返回 recentSamples
- **WHEN** 客户端请求 `GET /api/targets`
- **THEN** 响应中每个目标 SHALL 包含 `recentSamples` 数组,每个元素包含 `timestamp`ISO 8601`durationMs`number | null`up`booleanmatched === true
#### Scenario: recentSamples 数量
- **WHEN** 客户端请求 `GET /api/targets`
- **THEN** 每个目标的 recentSamples SHALL 最多包含 30 个元素,按时间倒序排列
#### Scenario: 目标无历史记录
- **WHEN** 某目标尚未执行过任何拨测
- **THEN** 其 recentSamples SHALL 为空数组
### Requirement: 新增共享类型
系统 SHALL 在 `src/shared/api.ts` 中定义 `CheckResult``RecentSample``HistoryResponse` 类型。
#### Scenario: CheckResult 类型
- **WHEN** 前后端共享 `CheckResult` 类型
- **THEN** 该类型 SHALL 包含 `timestamp: string``matched: boolean``durationMs: number | null``statusDetail: string | null``failure` 字段,不包含 success 字段
#### Scenario: RecentSample 类型
- **WHEN** 前后端共享 `RecentSample` 类型
- **THEN** 该类型 SHALL 包含 `timestamp: string``durationMs: number | null``up: boolean` 字段,其中 up 为 boolean 且等于 matched
#### Scenario: HistoryResponse 类型
- **WHEN** 前后端共享 `HistoryResponse` 类型
- **THEN** 该类型 SHALL 包含 `items: CheckResult[]``total: number``page: number``pageSize: number` 字段
### Requirement: 保留健康检查端点
系统 SHALL 保留 `GET /health` 端点,不受拨测功能影响。
#### Scenario: 访问健康检查
- **WHEN** 客户端请求 `GET /health`
- **THEN** 系统 SHALL 返回与之前格式一致的健康检查响应
### Requirement: API 错误处理
系统 SHALL 对不存在的目标 ID、无效参数和超出范围的分页参数返回适当的 HTTP 错误响应。
#### Scenario: 查询不存在的目标
- **WHEN** 客户端请求 `GET /api/targets/999/history`
- **THEN** 系统 SHALL 返回 404 状态码和错误信息
#### Scenario: 无效的 from/to 参数
- **WHEN** 客户端请求 `GET /api/targets/1/history?from=invalid`
- **THEN** 系统 SHALL 返回 400 状态码和错误信息
#### Scenario: 无效的分页参数
- **WHEN** 客户端请求 `GET /api/targets/1/history?from=ISO&to=ISO&page=abc`
- **THEN** 系统 SHALL 返回 400 状态码和错误信息
#### Scenario: pageSize 超过上限
- **WHEN** 客户端请求 `GET /api/targets/1/history?from=ISO&to=ISO&pageSize=201`
- **THEN** 系统 SHALL 返回 400 状态码和错误信息,提示 pageSize 不能超过 200
#### Scenario: pageSize 等于上限
- **WHEN** 客户端请求 `GET /api/targets/1/history?from=ISO&to=ISO&pageSize=200`
- **THEN** 系统 SHALL 正常返回数据
#### Scenario: from 或 to 参数缺失
- **WHEN** 客户端请求 `GET /api/targets/1/trend` 未提供 from 或 to 参数
- **THEN** 系统 SHALL 返回 400 状态码和错误信息
#### Scenario: 无效的目标 ID
- **WHEN** 客户端请求 `GET /api/targets/abc/history`
- **THEN** 系统 SHALL 返回 400 状态码和错误信息
### Requirement: 失败信息 API 契约
系统 SHALL 通过 API 返回结构化 failure 信息,供 Dashboard 展示和后续排查。
#### Scenario: 返回 expect 不匹配信息
- **WHEN** 最近一次检查结果包含 failure.kind=`mismatch`
- **THEN** `/api/targets``/api/targets/:id/history` SHALL 返回该 failure 的 kind、phase、path、expected、actual、message 字段
#### Scenario: 无失败信息
- **WHEN** 检查结果 matched=true
- **THEN** API SHALL 返回 failure 为 null