refactor: 规范审查与重组,合并细粒度规范,清理过时内容
- 合并 20+ 细粒度 spec 为粗粒度主题规范:dashboard、data-store、probe-engine、probe-api、probe-config 等 - 删除完全冗余规范:data-retention(被 probe-engine+data-store 覆盖)、backend-code-quality(DEVELOPMENT.md 已记录) - 补充 http-checker 规范至完整标准(配置+执行+expect+校验+observation),匹配代码 440 行实现 - 清理 tcp/udp/llm checker 规范中已废弃 defaults 配置段的残留 Scenario - 清理 checker-cohesion-structure 中的实现路径引用(src/server/...) - 统一所有 spec 格式(## Purpose 开头,去除 # Capability/Title 形式) - 更新 prompt-spec-review.md 审查提示文档
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
## Purpose
|
||||
|
||||
定义基于 Vite + Bun 的全栈应用运行时,包括 HTTP server、API 命名空间、健康检查、生产静态资源服务和 SPA fallback 行为。
|
||||
定义基于 Vite + Bun 的全栈应用运行时,包括统一服务 bootstrap、声明式 Bun routes、API 路由组织、HTTP server、API 命名空间、健康检查、生产静态资源服务和 SPA fallback 行为。
|
||||
|
||||
## Requirements
|
||||
|
||||
@@ -113,3 +113,108 @@
|
||||
#### Scenario: SIGINT/SIGTERM 处理
|
||||
- **WHEN** 开发模式进程收到 SIGINT 或 SIGTERM 信号
|
||||
- **THEN** 系统 SHALL 调用 engine.stop() 停止调度、调用 store.close() 关闭数据库连接后退出进程
|
||||
|
||||
### Requirement: 路径参数支持
|
||||
系统 SHALL 使用 routes 对象的 `:param` 语法声明路径参数,替代手动 regex 匹配。
|
||||
|
||||
#### Scenario: 带路径参数的 API 路由
|
||||
- **WHEN** 客户端请求 `/api/targets/123/history`
|
||||
- **THEN** 系统 SHALL 通过 `routes` 中注册的 `/api/targets/:id/history` 匹配,并通过 `req.params.id` 获取参数值 `"123"`
|
||||
|
||||
#### Scenario: 路径参数类型
|
||||
- **WHEN** route handler 接收到路径参数
|
||||
- **THEN** 参数值 SHALL 为字符串类型,handler 负责进行类型转换和校验
|
||||
|
||||
### Requirement: HTTP Method 声明
|
||||
系统 SHALL 在 routes 对象中为每个 API 端点以 per-method handler 形式声明支持的 HTTP method;未匹配 method 的 API 请求 SHALL 落入 `/api/*` 通配符并返回 JSON 404。
|
||||
|
||||
#### Scenario: 单 method 端点
|
||||
- **WHEN** API 端点只支持 GET 方法
|
||||
- **THEN** 该端点 SHALL 以 `{ GET(req) { ... } }` 形式注册
|
||||
|
||||
#### Scenario: 不支持的 method 请求
|
||||
- **WHEN** 客户端使用未声明的 method 请求 API 端点
|
||||
- **THEN** `/api/*` 通配符 SHALL 返回 JSON 格式的 404 错误响应
|
||||
|
||||
### Requirement: 路由按职责拆分
|
||||
系统 SHALL 将 HTTP 路由处理逻辑按 API 端点拆分为独立模块,每个模块导出 route handler 函数供 routes 对象统一注册。
|
||||
|
||||
#### Scenario: health 端点独立路由
|
||||
- **WHEN** 客户端请求 `GET /health`
|
||||
- **THEN** `routes/health.ts` 导出的 handler 负责处理,返回 HealthResponse JSON
|
||||
|
||||
#### Scenario: summary 端点独立路由
|
||||
- **WHEN** 客户端请求 `GET /api/summary`
|
||||
- **THEN** `routes/summary.ts` 导出的 handler 负责处理,委托 store 查询并返回 SummaryResponse JSON
|
||||
|
||||
#### Scenario: targets 端点独立路由
|
||||
- **WHEN** 客户端请求 `GET /api/targets`
|
||||
- **THEN** `routes/targets.ts` 导出的 handler 负责处理,委托 store 查询并返回 TargetStatus[] JSON
|
||||
|
||||
#### Scenario: history 端点独立路由
|
||||
- **WHEN** 客户端请求 `GET /api/targets/:id/history?from=ISO&to=ISO`
|
||||
- **THEN** `routes/history.ts` 导出的 handler 负责处理,通过 `req.params.id` 获取路径参数,包含参数校验、store 查询和 HistoryResponse 返回
|
||||
|
||||
#### Scenario: trend 端点独立路由
|
||||
- **WHEN** 客户端请求 `GET /api/targets/:id/trend?from=ISO&to=ISO`
|
||||
- **THEN** `routes/trend.ts` 导出的 handler 负责处理,通过 `req.params.id` 获取路径参数,包含参数校验、store 查询和 TrendPoint[] 返回
|
||||
|
||||
### Requirement: 共享辅助函数集中管理
|
||||
系统 SHALL 将跨路由共享的响应格式化函数抽取到 helpers.ts 模块,单一职责、集中管理。
|
||||
|
||||
#### Scenario: createApiError 集中定义
|
||||
- **WHEN** 任意路由需要返回 API 错误响应
|
||||
- **THEN** 从 `helpers.ts` 导入 `createApiError` 函数,提供错误信息和状态码
|
||||
|
||||
#### Scenario: jsonResponse 集中定义
|
||||
- **WHEN** 任意路由需要返回 JSON 响应
|
||||
- **THEN** 从 `helpers.ts` 导入 `jsonResponse` 函数,处理 HEAD 方法、Content-Type 和安全头
|
||||
|
||||
#### Scenario: mapCheckResult 集中定义
|
||||
- **WHEN** 需要将 StoredCheckResult 映射为 API CheckResult
|
||||
- **THEN** 从 `helpers.ts` 导入 `mapCheckResult` 函数,处理 failure JSON 解析和格式转换
|
||||
|
||||
### Requirement: 统一启动引导函数
|
||||
系统 SHALL 提供 `src/server/bootstrap.ts` 导出 `bootstrap(options: BootstrapOptions)` 函数,封装完整的服务启动序列:加载配置、初始化正式 logger、创建 store、同步 targets、创建并启动 engine、启动 HTTP server、注册 shutdown handler。配置加载失败发生在正式 logger 初始化之前,系统 SHALL 使用 console fallback 输出启动失败信息。配置加载成功后的启动失败 SHALL 使用正式 logger 输出 `fatal` 后退出。
|
||||
|
||||
#### Scenario: 开发模式启动
|
||||
- **WHEN** `dev.ts` 调用 `bootstrap({ configPath, mode: "development" })`
|
||||
- **THEN** 系统 SHALL 完成完整启动序列,不传入 staticAssets,并初始化运行时 logger
|
||||
|
||||
#### Scenario: 生产模式启动(带静态资源)
|
||||
- **WHEN** code-generated entry 调用 `bootstrap({ configPath, mode: "production", staticAssets })`
|
||||
- **THEN** 系统 SHALL 完成完整启动序列,将 staticAssets 传递给 startServer,并初始化运行时 logger
|
||||
|
||||
#### Scenario: 配置加载失败处理
|
||||
- **WHEN** 配置文件读取、YAML 解析或配置校验失败
|
||||
- **THEN** 系统 SHALL 通过 console fallback 输出错误信息并以非零退出码退出进程
|
||||
|
||||
#### Scenario: 配置加载后的启动失败处理
|
||||
- **WHEN** logger、store、engine 或 HTTP server 初始化失败
|
||||
- **THEN** 系统 SHALL 通过正式 logger 输出 `fatal` 日志并以非零退出码退出进程
|
||||
|
||||
#### Scenario: 优雅关机
|
||||
- **WHEN** 进程收到 SIGINT 或 SIGTERM 信号
|
||||
- **THEN** bootstrap 注册的 shutdown handler SHALL 调用 engine.stop()、store.close() 和 logger.flush() 后退出
|
||||
|
||||
### Requirement: BootstrapOptions 接口
|
||||
`bootstrap` 函数 SHALL 接受 `BootstrapOptions` 参数,包含 `configPath: string`、`mode: RuntimeMode` 和可选的 `staticAssets?: StaticAssets`。
|
||||
|
||||
#### Scenario: 最小配置(开发模式)
|
||||
- **WHEN** 仅传入 configPath 和 mode
|
||||
- **THEN** 系统 SHALL 正常启动,startServer 不接收 staticAssets 参数
|
||||
|
||||
#### Scenario: 生产模式配置
|
||||
- **WHEN** 传入 configPath、mode 和 staticAssets
|
||||
- **THEN** 系统 SHALL 将 staticAssets 传递给 startServer
|
||||
|
||||
### Requirement: dev.ts 和生产入口使用 bootstrap
|
||||
`dev.ts` 和 `src/server/main.ts` SHALL 调用 `bootstrap()` 而非各自维护启动序列。
|
||||
|
||||
#### Scenario: dev.ts 调用 bootstrap
|
||||
- **WHEN** 开发者运行 `bun run dev`
|
||||
- **THEN** `dev.ts` SHALL 调用 `bootstrap` 完成启动
|
||||
|
||||
#### Scenario: main.ts 调用 bootstrap
|
||||
- **WHEN** 生产可执行文件启动
|
||||
- **THEN** `main.ts` SHALL 调用 `bootstrap` 完成启动
|
||||
|
||||
Reference in New Issue
Block a user