1
0
Files
DiAL/openspec/changes/backend-architecture-hardening/specs/batch-data-queries/spec.md
lanyuanxiaoyao 147a2559ae refactor: 后端架构加固 — 泛型化、批量查询、bootstrap 统一、路径修复与 pageSize 上限
- CheckerDefinition 泛型化,HTTP/Command checker 移除 resolved target 断言
- 新增 ProbeStore.getAllRecentSamples 消除 targets 路由 N+1 查询
- 统一 getAllTargetStats 与 getTargetStats 的 availability 精度
- Engine rejected 结果写入 internal error 记录,提升可观测性
- 新增 bootstrap.ts 统一 dev/production 启动序列
- dataDir 相对路径改为基于配置文件目录解析
- validatePagination 增加 pageSize 上限 200 校验
- 修复 ErrorBoundary override 标记
- 更新 README/DEVELOPMENT 文档,新增完整测试覆盖
2026-05-13 18:15:46 +08:00

2.5 KiB
Raw Blame History

ADDED Requirements

Requirement: 批量查询所有目标的最近采样数据

系统 SHALL 提供 getAllRecentSamples(limit: number) 方法,通过单次 SQL 查询获取所有 target 的最近 N 条采样数据,返回 Map<number, Array<{ timestamp: string; duration_ms: number | null; matched: number }>> 结构。

Scenario: 获取所有目标的最近采样

  • WHEN 调用 getAllRecentSamples(30)
  • THEN 系统 SHALL 通过单次 SQL 查询获取每个 target 最近 30 条记录,返回按 target_id 索引的 Map

Scenario: 目标无历史记录

  • WHEN 某 target 在 check_results 表中无任何记录
  • THEN 该 target_id 在返回的 Map 中 SHALL 不存在对应的 key

Scenario: 采样数据排序

  • WHEN 获取采样数据
  • THEN 每个 target 的记录 SHALL 按 timestamp 降序排列(最新在前)

MODIFIED Requirements

Requirement: targets 列表使用批量方法

handleTargetsroutes/targets.ts 中生成 TargetStatus[] 的逻辑SHALL 使用 getLatestChecksMapgetAllTargetStatsgetAllRecentSamples 替代逐目标查询,消除 N+1 查询。

Scenario: 目标列表使用批量查询

  • WHEN 处理 GET /api/targets 请求
  • THEN 系统 SHALL 分别调用 getLatestChecksMap()getAllTargetStats()getAllRecentSamples(30) 批量获取数据,在内存中组装 TargetStatus 数组,而非对每个 target 逐条查询数据库

Scenario: 目标无采样数据

  • WHEN 某 target 在 getAllRecentSamples 返回的 Map 中不存在
  • THEN 该 target 的 recentSamples SHALL 为空数组

Requirement: 批量查询目标统计

系统 SHALL 提供 getAllTargetStats 方法,通过单次 SQL GROUP BY 聚合查询获取所有 target 的拨测统计totalChecks 和 availability。availability 计算精度 SHALL 与 getTargetStats 一致,统一使用 Math.round(value * 100) / 100 保留两位小数。

Scenario: 获取所有目标的聚合统计

  • WHEN 调用 getAllTargetStats()
  • THEN 系统 SHALL 执行单次 GROUP BY 聚合查询,在内存中计算 availability 并返回 Map<number, { totalChecks, availability }>

Scenario: availability 精度

  • WHEN 计算 availabilityupCount / totalChecks * 100
  • THEN 结果 SHALL 使用 Math.round(value * 100) / 100 四舍五入保留两位小数,与 getTargetStats 方法一致

Scenario: 目标无历史记录

  • WHEN 某 target 在 check_results 表中无任何记录
  • THEN 该 target_id 在返回的 Map 中 SHALL 不存在对应的 key