1
0
Files
DiAL/openspec/changes/backend-architecture-hardening/specs/checker-runner-abstraction/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

3.4 KiB
Raw Blame History

MODIFIED Requirements

Requirement: Checker 接口定义

系统 SHALL 在 src/server/checker/runner/types.ts 中定义面向扩展的泛型 CheckerDefinition<TResolved extends ResolvedTargetBase = ResolvedTargetBase>,包含 typeconfigKey、TypeBox 配置契约、启动期语义校验、resolveexecuteserialize 成员。泛型参数 SHALL 约束 executeserialize 方法的 target 参数类型,使 checker 实现内部获得编译期类型安全。默认泛型参数 = ResolvedTargetBase 保证中间层registry、engine、config-loader无需指定泛型。

Scenario: Checker 接口包含必要方法

  • WHEN 开发者实现一个新的 Checker
  • THEN 该实现 MUST 提供 type(字符串标识)、configKey配置分组名、TypeBox 配置契约、启动期语义校验、resolve(target, context): TResolved(解析配置并填充默认值)、execute(target: TResolved, ctx)(执行探测返回 CheckResultserialize(target: TResolved)(返回 target 展示文本和 config JSON

Scenario: CheckerContext 注入 signal

  • WHEN 引擎调用 checker.execute(target, ctx)
  • THEN ctx.signal SHALL 是一个由引擎创建的 AbortSignal,在超时或引擎关闭时 abort

Scenario: resolve 不承担通用契约校验

  • WHEN config-loader 调用 checker.resolve()
  • THEN checker.resolve() SHALL 假定配置已经通过 TypeBox/Ajv 契约校验和启动期语义校验,只负责默认值填充、路径解析和领域配置转换

Scenario: 接口方法使用泛型约束

  • WHEN 开发者查看 CheckerDefinition<TResolved> 接口签名
  • THEN resolve 的返回值 SHALL 为 TResolvedexecute 的参数 SHALL 为 TResolvedserialize 的参数 SHALL 为 TResolved

Scenario: checker 实现无需手动断言

  • WHEN HttpChecker 实现 CheckerDefinition<ResolvedHttpTarget>
  • THEN execute 方法的 target 参数类型 SHALL 直接为 ResolvedHttpTarget,无需在方法内部使用 as 类型断言

Scenario: registry 使用默认泛型参数

  • WHEN CheckerRegistry 存储和返回 checker 实例
  • THEN registry 内部 SHALL 使用 CheckerDefinition(等价于 CheckerDefinition<ResolvedTargetBase>),实现类型擦除

Requirement: CheckerRegistry 注册中心

系统 SHALL 在 src/server/checker/runner/registry.ts 中提供 CheckerRegistry 类,支持 register(checker)get(type)supportedTypes。重复注册同一 type SHALL 抛出错误。registry 内部 SHALL 存储 CheckerDefinition(使用默认泛型参数),对外提供类型擦除后的接口。

Scenario: 注册并获取 Checker

  • WHEN 调用 registry.register(new HttpChecker()) 后再调用 registry.get("http")
  • THEN 返回的 SHALL 是之前注册的 HttpChecker 实例(类型为 CheckerDefinition

Scenario: 获取未注册的 type

  • WHEN 调用 registry.get("unknown") 且未注册对应 type 的 checker
  • THEN 系统 SHALL 抛出错误,提示不支持的 probe type

Scenario: 重复注册

  • WHEN 同一 type 值被重复 register()
  • THEN 系统 SHALL 抛出错误,提示该 type 已注册

Scenario: 查询支持的 type 列表

  • WHEN 注册了 "http" 和 "command" 两个 checker 后查询 registry.supportedTypes
  • THEN 返回的数组 SHALL 包含 ["http", "command"](按注册顺序)