1
0

feat: 将 demo 项目转化为 HTTP 拨测监控工具

新增 YAML 配置解析(Bun 内置 YAML)、SQLite 数据存储(bun:sqlite)、按 interval 分组并发拨测引擎、REST API(/api/summary、/api/targets、/api/targets/:id/history、/api/targets/:id/trend)、React 前端 Dashboard(统计卡片、目标表格、可展开详情面板、recharts 趋势图)。CLI 简化为仅接受配置文件路径。移除 /api/demo 路由和相关 demo 代码。保留 /health、静态资源服务和 SPA fallback。
This commit is contained in:
2026-05-09 17:04:25 +08:00
parent 9267f6585c
commit 57d3a5cfb4
43 changed files with 2910 additions and 525 deletions

View File

@@ -0,0 +1,87 @@
## Purpose
定义拨测调度引擎的行为:按 interval 分组定时、组内并发拨测、expect 结果校验和结果持久化。
## Requirements
### Requirement: 按 interval 分组调度
系统 SHALL 将拨测目标按 interval 值分组,每组使用独立的定时器进行调度。
#### Scenario: 相同 interval 的目标共享定时器
- **WHEN** 多个 target 配置了相同的 interval如 30s
- **THEN** 系统 SHALL 使用同一个 `setInterval` 定时器,每次 tick 并发拨测所有该组目标
#### Scenario: 不同 interval 的目标各自调度
- **WHEN** target A 配置 15s intervaltarget B 配置 30s interval
- **THEN** 系统 SHALL 创建两个独立定时器,分别按各自频率调度
### Requirement: 组内并发拨测
系统 SHALL 在每次调度 tick 时,使用 `Promise.all` 并发执行同组内所有目标的拨测。
#### Scenario: 同组目标并发执行
- **WHEN** 调度器触发一次 tick该组有 3 个目标
- **THEN** 系统 SHALL 同时发起 3 个 HTTP 请求,而非顺序执行
#### Scenario: 单个目标失败不影响同组其他目标
- **WHEN** 同组中某个目标的拨测请求超时或失败
- **THEN** 其他目标的拨测 SHALL 正常完成并记录结果
### Requirement: HTTP 拨测执行
系统 SHALL 对每个目标执行 HTTP 请求,支持 GET、POST、PUT、DELETE、PATCH、HEAD 方法,并携带配置的 headers 和 body。
#### Scenario: 执行 GET 请求
- **WHEN** 目标配置 method 为 GET
- **THEN** 系统 SHALL 发送 GET 请求到目标 URL
#### Scenario: 执行 POST 请求带 body
- **WHEN** 目标配置 method 为 POST 且指定了 body 和 Content-Type header
- **THEN** 系统 SHALL 发送带指定 body 的 POST 请求
#### Scenario: 携带自定义 headers
- **WHEN** 目标配置了 headers如 Authorization
- **THEN** 系统 SHALL 在请求中包含所有配置的 headers
### Requirement: 请求超时控制
系统 SHALL 对每次拨测请求实施超时控制,超时时间使用目标配置的 timeout 值。
#### Scenario: 请求超时
- **WHEN** 拨测请求在 timeout 时间内未收到响应
- **THEN** 系统 SHALL 中止该请求,记录为失败并标注超时错误
#### Scenario: 请求在超时前完成
- **WHEN** 拨测请求在 timeout 时间内收到响应
- **THEN** 系统 SHALL 正常记录响应结果
### Requirement: expect 校验
系统 SHALL 在拨测完成后根据目标的 expect 配置校验响应,校验结果记入 check result。
#### Scenario: 校验状态码
- **WHEN** 目标配置了 `expect.status: [200, 201]`
- **THEN** 系统 SHALL 检查响应状态码是否在列表中,将匹配结果记录到 matched 字段
#### Scenario: 校验响应体包含
- **WHEN** 目标配置了 `expect.bodyContains: "healthy"`
- **THEN** 系统 SHALL 检查响应体是否包含该文本,将匹配结果记录到 matched 字段
#### Scenario: 校验延迟阈值
- **WHEN** 目标配置了 `expect.maxLatencyMs: 3000`
- **THEN** 系统 SHALL 检查实际延迟是否超过阈值,将匹配结果记录到 matched 字段
#### Scenario: 无 expect 配置
- **WHEN** 目标未配置任何 expect 规则
- **THEN** 系统 SHALL 将 matched 字段设为 true
#### Scenario: 多条 expect 规则
- **WHEN** 目标同时配置了 status、bodyContains 和 maxLatencyMs
- **THEN** 系统 SHALL 所有规则全部通过时 matched 为 true任一不通过则为 false
### Requirement: 拨测结果记录
系统 SHALL 在每次拨测完成后,将结果写入 SQLite 数据存储,包含 target_id、timestamp、success、status_code、latency_ms、error、matched 字段。
#### Scenario: 成功拨测结果记录
- **WHEN** 拨测请求成功完成(收到 HTTP 响应)
- **THEN** 系统 SHALL 记录 success=true、status_code、latency_ms、matched
#### Scenario: 失败拨测结果记录
- **WHEN** 拨测请求失败(网络错误、超时等)
- **THEN** 系统 SHALL 记录 success=false、error 信息status_code 和 latency_ms 为 null