41 lines
3.0 KiB
Markdown
41 lines
3.0 KiB
Markdown
## MODIFIED Requirements
|
||
|
||
### Requirement: Checker 接口定义
|
||
系统 SHALL 在 `src/server/checker/runner/types.ts` 中定义面向扩展的泛型 `CheckerDefinition<TResolved extends ResolvedTargetBase = ResolvedTargetBase>`,包含 `type`、`configKey`、TypeBox 配置契约、启动期语义校验、`resolve`、`execute`、`serialize`、`buildDetail` 成员。泛型参数 SHALL 约束 `execute` 和 `serialize` 方法的 target 参数类型,使 checker 实现内部获得编译期类型安全。默认泛型参数 `= ResolvedTargetBase` 保证中间层(registry、engine、config-loader)无需指定泛型。
|
||
|
||
#### Scenario: Checker 接口包含必要方法
|
||
- **WHEN** 开发者实现一个新的 Checker
|
||
- **THEN** 该实现 MUST 提供 `type`(字符串标识)、`configKey`(配置分组名)、TypeBox 配置契约、启动期语义校验、`resolve(target, context)`(解析配置并填充默认值)、`execute(target, ctx)`(执行探测返回 CheckResult)、`serialize(target)`(返回 target 展示文本和 config JSON)和 `buildDetail(observation)`(从 observation 构造人可读摘要)
|
||
|
||
#### 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: type 与 configKey 默认一致
|
||
- **WHEN** checker 定义 `type: "tcp"`
|
||
- **THEN** checker 的 `configKey` SHALL 默认使用 `"tcp"`,对应 target 的 `tcp` 分组和 defaults.tcp 分组
|
||
|
||
#### Scenario: 接口方法使用泛型约束
|
||
- **WHEN** 开发者查看 `CheckerDefinition<TResolved>` 接口签名
|
||
- **THEN** `resolve` 的返回值 SHALL 为 `TResolved`;`execute` 的参数 SHALL 为 `TResolved`;`serialize` 的参数 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>`),实现类型擦除
|
||
|
||
#### Scenario: buildDetail 方法签名
|
||
- **WHEN** 开发者实现 buildDetail 方法
|
||
- **THEN** 方法签名 SHALL 为 `buildDetail(observation: Record<string, unknown>): string | null`,接收 observation 对象并返回人可读摘要字符串或 null
|
||
|
||
#### Scenario: buildDetail 由 API 层调用
|
||
- **WHEN** API 序列化 CheckResult
|
||
- **THEN** API 层 SHALL 通过 registry 获取对应 checker 并调用 buildDetail,而非由 execute 方法直接生成 detail
|