1
0
Files
DiAL/openspec/specs/api-route-separation/spec.md
lanyuanxiaoyao f7facb7232 refactor: 全面优化后端代码质量与架构
- app.ts 单体路由拆分为 routes/ + helpers + middleware + static 独立模块
- 类型去重:CheckFailure/CheckResult 以 shared/api.ts 为唯一源头,收紧 phase 联合类型
- es-toolkit 替换:isPlainObject/isNil/isEmptyObject/isEqual/isError/Semaphore/groupBy
- Bun 内置 API:Object.fromEntries 替代手写 headersToRecord
- bun:sqlite 规范:prepare() → query() 利用内置缓存,避免 N+1 查询
- 新增 getLatestChecksMap/allGetTargetStats 批量查询方法
- 新增 backend-code-quality/api-route-separation/batch-data-queries 规范
- 补充 openspec/config.yaml 后端开发规范与 DEVELOPMENT.md 后端开发指引
2026-05-12 15:15:36 +08:00

3.7 KiB
Raw Blame History

Purpose

定义后端 API 路由的组织规范:按端点拆分为独立 handler、共享响应工具集中管理、参数校验逻辑抽取为中间件、静态资源服务独立维护。

Requirements

Requirement: 路由按职责拆分

系统 SHALL 将 HTTP 路由处理逻辑按 API 端点拆分为独立模块,每个模块导出一个 handler 函数供 app.ts 统一注册。

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 负责处理包含参数校验、store 查询和 HistoryResponse 返回

Scenario: trend 端点独立路由

  • WHEN 客户端请求 GET /api/targets/:id/trend?from=ISO&to=ISO
  • THEN routes/trend.ts 导出的 handler 负责处理包含参数校验、store 查询和 TrendPoint[] 返回

Requirement: 共享辅助函数集中管理

系统 SHALL 将跨路由共享的响应格式化函数抽取到 helpers.ts 模块,单一职责、集中管理。

Scenario: createApiError 集中定义

  • WHEN 任意路由需要返回 API 错误响应
  • THENhelpers.ts 导入 createApiError 函数,提供错误信息和状态码

Scenario: jsonResponse 集中定义

  • WHEN 任意路由需要返回 JSON 响应
  • THENhelpers.ts 导入 jsonResponse 函数,处理 HEAD 方法、Content-Type 和安全头

Scenario: mapCheckResult 集中定义

  • WHEN 需要将 StoredCheckResult 映射为 API CheckResult
  • THENhelpers.ts 导入 mapCheckResult 函数,处理 failure JSON 解析和格式转换

Requirement: 参数校验逻辑抽取为中间件

系统 SHALL 将重复的参数校验逻辑target ID 解析、时间范围校验、分页参数校验、方法检查)抽取到 middleware.ts 模块。

Scenario: 方法检查中间件

  • WHEN 请求方法不是 GET 或 HEAD
  • THEN guardGetHead(request, mode) SHALL 返回 405 Response否则返回 null 表示放行

Scenario: Target ID 校验

  • WHEN URL 中的 id 参数不是正整数
  • THEN validateTargetId(idStr) SHALL 返回 400 ApiError

Scenario: 时间范围参数校验

  • WHEN from 或 to 参数缺失或格式无效
  • THEN validateTimeRange(from, to) SHALL 返回 400 ApiError

Scenario: 分页参数校验

  • WHEN page 或 pageSize 参数不是正整数
  • THEN validatePagination(page, pageSize) SHALL 返回 400 ApiError

Requirement: 静态资源服务独立管理

系统 SHALL 将静态资源服务、SPA fallback 和 Content-Type 映射逻辑抽取到 static.ts 模块。

Scenario: 根路径返回 index.html

  • WHEN 客户端请求 /
  • THEN static.ts 的 handler 返回 index.html设置正确的 Content-Type 和 Cache-Control

Scenario: 资源文件返回正确 Content-Type

  • WHEN 客户端请求 /assets/main.js
  • THEN static.ts 的 handler 根据文件扩展名返回正确的 Content-Type.jstext/javascript

Scenario: SPA fallback

  • WHEN 客户端请求非 API、非资源的路径/dashboard
  • THEN static.ts 的 handler 返回 index.html 实现 SPA 的客户端路由