1
0

refactor: 统一 target name/description 可空语义,前端展示 fallback 到 id

- schema: name/description 允许省略或显式 null,TypeBox Union([Null, String])
- 类型: RawTargetConfig/ResolvedTargetBase/子类型/StoredTarget/TargetStatus name 改为 string | null
- checker resolve: name: t.name ?? null,不再 fallback 到 id
- 语义校验: 拒绝空字符串和纯空白 name
- SQLite: targets.name 列改为可空 TEXT
- 前端: 新增 getTargetDisplayName(target) 展示 name ?? id
- 测试: 覆盖 name/description null 全场景,查找改为按 id
- 文档: 更新 README/DEVELOPMENT 和 6 个 openspec specs
This commit is contained in:
2026-05-17 20:12:39 +08:00
parent f7193e98ff
commit 31fd3a2a43
29 changed files with 382 additions and 119 deletions

View File

@@ -5,7 +5,7 @@
## Requirements
### Requirement: YAML 配置文件格式
系统 SHALL 支持通过 YAML 配置文件定义全部运行参数,包括 server 配置、runtime 配置、可选的 variables 段、checker 默认值和 typed target 列表(含可选 group 字段。target MUST 使用 `id` 字段作为唯一标识符MUST 使用 `type` 字段声明 checker 类型SHALL 支持可选的 `name` 字段作为展示名称(缺省 fallback 到 id。HTTP 领域字段 MUST 放在 `http` 分组cmd 领域字段 MUST 放在 `cmd` 分组db 领域字段 MUST 放在 `db` 分组。HTTP target 的 `http` 分组 SHALL 支持可选的 `ignoreSSL`(布尔值)和 `maxRedirects`非负整数字段。Db target 的 `db` 分组 SHALL 支持 `url`(必填)和 `query`(可选)字段。
系统 SHALL 支持通过 YAML 配置文件定义全部运行参数,包括 server 配置、runtime 配置、可选的 variables 段、checker 默认值和 typed target 列表(含可选 group 字段。target MUST 使用 `id` 字段作为唯一标识符MUST 使用 `type` 字段声明 checker 类型SHALL 支持可选的 `name` 字段作为展示名称元信息SHALL 支持可选的 `description` 字段作为目标说明。`name``description` 均 SHALL 允许省略或显式配置为 `null`;省略或显式 null 时解析结果 SHALL 保留为 null。HTTP 领域字段 MUST 放在 `http` 分组cmd 领域字段 MUST 放在 `cmd` 分组db 领域字段 MUST 放在 `db` 分组。HTTP target 的 `http` 分组 SHALL 支持可选的 `ignoreSSL`(布尔值)和 `maxRedirects`非负整数字段。Db target 的 `db` 分组 SHALL 支持 `url`(必填)和 `query`(可选)字段。
`defaults.http` 分组 SHALL 仅支持 `headers`(可选)和 `maxBodyBytes`(可选)字段。`defaults.http` 分组 MUST NOT 支持 `method` 字段。
@@ -15,11 +15,11 @@
#### Scenario: 最简 HTTP 配置文件解析
- **WHEN** 系统读取只包含一个 `type: http` target`id``http.url`)的 YAML 配置文件(省略 server、runtime、variables、defaults 和 expect
- **THEN** 系统 SHALL 使用内置默认值填充未指定的字段host=127.0.0.1, port=3000, dir=./data, interval=30s, timeout=10s, runtime.maxConcurrentChecks=20, http.method=GET, http.maxBodyBytes=100MB, http.ignoreSSL=false, http.maxRedirects=0, group="default", name fallback 到 id
- **THEN** 系统 SHALL 使用内置默认值填充未指定的字段host=127.0.0.1, port=3000, dir=./data, interval=30s, timeout=10s, runtime.maxConcurrentChecks=20, http.method=GET, http.maxBodyBytes=100MB, http.ignoreSSL=false, http.maxRedirects=0, group="default"),并保留 name=null、description=null
#### Scenario: 最简 cmd 配置文件解析
- **WHEN** 系统读取只包含一个 `type: cmd` target`id``cmd.exec`)的 YAML 配置文件
- **THEN** 系统 SHALL 使用内置默认值填充未指定的字段interval=30s, timeout=10s, cmd.cwd 为配置文件所在目录, cmd.maxOutputBytes=100MB, name fallback 到 id
- **THEN** 系统 SHALL 使用内置默认值填充未指定的字段interval=30s, timeout=10s, cmd.cwd 为配置文件所在目录, cmd.maxOutputBytes=100MB),并保留 name=null、description=null
#### Scenario: per-target 配置覆盖全局默认值
- **WHEN** 某个 target 指定 interval、timeout 或对应领域分组中的默认字段
@@ -35,7 +35,7 @@
#### Scenario: 最简 db 配置文件解析
- **WHEN** 系统读取只包含一个 `type: db` target`id``db.url`)的 YAML 配置文件
- **THEN** 系统 SHALL 使用内置默认值填充未指定的字段interval=30s, timeout=10s, group="default", name fallback 到 id
- **THEN** 系统 SHALL 使用内置默认值填充未指定的字段interval=30s, timeout=10s, group="default"),并保留 name=null、description=null
#### Scenario: defaults.http.method 触发校验错误
- **WHEN** 配置文件中出现 `defaults.http.method` 字段
@@ -330,18 +330,30 @@
- **THEN** 系统 SHALL 将默认值 `./data` 基于 configDir 解析为绝对路径
### Requirement: target 通用元信息字段约束
系统 SHALL 在 YAML target 通用字段中支持 `description` 字段,并对 `id``name``description` 执行契约校验。`id` MUST 为 1 到 30 个字符,显式 `name` MUST 为 1 到 30 个字符`description` MUST 不超过 500 个字符且 MAY 为空字符串。
系统 SHALL 在 YAML target 通用字段中支持 `description` 字段,并对 `id``name``description` 执行契约校验。`id` MUST 为 1 到 30 个字符`name` MUST 为 null 或 1 到 30 个字符的字符串,且语义校验 SHALL 拒绝仅包含空白字符的 name。`description` MUST 为 null 或不超过 500 个字符的字符串,且 MAY 为空字符串。
#### Scenario: description 字段解析
- **WHEN** 系统读取包含 `description: "检查生产 API 健康状态"` 的 target
- **THEN** 系统 SHALL 将该字段解析为 target 的目标说明
#### Scenario: name 为 null 通过校验
- **WHEN** 系统读取包含 `name: null` 或省略 `name` 的 target
- **THEN** 系统 SHALL 接受该配置
#### Scenario: name 仅包含空白字符报错
- **WHEN** 系统读取包含 `name: " "` 的 target
- **THEN** 系统 SHALL 以配置错误退出,提示 name 不能为空白
#### Scenario: description 为空字符串
- **WHEN** 系统读取包含 `description: ""` 的 target
- **THEN** 系统 SHALL 接受该配置,且不触发长度错误
#### Scenario: description 为 null 通过校验
- **WHEN** 系统读取包含 `description: null` 或省略 `description` 的 target
- **THEN** 系统 SHALL 接受该配置
#### Scenario: description 类型非法
- **WHEN** YAML 中某个 target 的 `description` 字段不是字符串
- **WHEN** YAML 中某个 target 的 `description` 字段不是字符串也不是 null
- **THEN** 系统 SHALL 以错误退出,提示 description 字段类型错误
#### Scenario: description 超过最大长度
@@ -361,12 +373,12 @@
- **THEN** 系统 SHALL 在契约校验阶段以错误退出,提示 description 字段长度错误
### Requirement: 配置 schema 导出包含 target 元信息约束
系统 SHALL 在导出的 `probe-config.schema.json` 中包含 target `id``name``description` 的长度约束,用于编辑器提示和外部校验。
系统 SHALL 在导出的 `probe-config.schema.json` 中包含 target `id``name``description` 的长度约束和可空类型,用于编辑器提示和外部校验。
#### Scenario: schema 导出 description
- **WHEN** 系统导出 `probe-config.schema.json`
- **THEN** target schema SHALL 包含可选的 `description` 字段,类型为 string最大长度为 500
- **THEN** target schema SHALL 包含可选的 `description` 字段,类型为 string 或 null字符串最大长度为 500
#### Scenario: schema 导出 id 和 name 长度
#### Scenario: schema 导出 id 和 name
- **WHEN** 系统导出 `probe-config.schema.json`
- **THEN** target schema SHALL 声明 `id` 的 minLength 为 1、maxLength 为 30并声明 `name` 的 minLength 为 1、maxLength 为 30
- **THEN** target schema SHALL 声明 `id` 的 minLength 为 1、maxLength 为 30并声明 `name` 为可选字段,类型为 string 或 null字符串的 minLength 为 1、maxLength 为 30