1
0
Files
DiAL/docs/development/backend.md
lanyuanxiaoyao 714b635aef docs: 重构文档体系
- 合并 DEVELOPMENT.md 至 docs/development/README.md
- 合并 CONTRIBUTING.md 至 docs/development/checker.md
- 合并 build-release.md 至 release.md
- 合并 testing-quality.md 内容至各专题文档
- 合并 status-model.md 至 expectations.md
- 新增 docs/user/README.md 用户入口
- 简化 docs/README.md 文档路由
- 各专题文档新增适用场景和更新触发条件
- 更新 openspec/config.yaml 文档规则
2026-05-25 10:47:52 +08:00

8.6 KiB
Raw Blame History

后端开发

本文档说明 DiAL 后端的 API、配置加载、存储、拨测引擎、日志、expect 和错误模型开发约定。

适用场景:修改 src/server/src/shared/api.ts、后端测试、配置契约、API 响应、store、engine、logger 或 expect 基础设施。

库使用优先级

优先级 来源 典型用途
1 Bun 内置 API Bun.servebun:sqliteBun.spawnBun.fileBun.YAML
2 es-toolkit 类型判断、深度比较、错误判断、并发控制、集合操作
3 标准 Web API Object.fromEntriesHeadersfetchAbortController
4 主流三方库 cheerio、xpath、@xmldom/xmldom
5 自行实现 仅在以上都无法满足时

新增依赖前必须先检查上述每一层是否已有可用方案。

API 路由开发

路由文件位于 src/server/routes/,每个端点一个文件。路由通过 server.tsBun.serve({ routes }) 声明式注册,使用 per-method handler 对象。

新增路由步骤:

  1. src/server/routes/ 下创建 <name>.ts
  2. 实现 handler 函数并 export。
  3. server.tsroutes 对象中注册路径和 method handler。
  4. tests/server/app.test.ts 中添加集成测试。

请求参数校验使用 middleware.ts 提供的 validateTargetIdvalidateTimeRangevalidatePaginationvalidateDashboardWindowvalidateRecentLimitvalidateMetricsBucket

共享 helpers

函数 用途
createApiError(error, status) 构造 API 错误体
createHeaders(mode, init) 创建响应 Headers生产模式附加安全头
createHealthResponse() 构造健康检查响应
formatDuration(ms) 毫秒转为可读时长字符串
jsonResponse(body, options) JSON 响应构造
mapCheckResult(row, type) 数据库行转 API CheckResult

类型规范

  • 共享类型以 src/shared/api.ts 为唯一源头。
  • 严格联合类型优先于宽类型。
  • 存储层类型与 API 类型分离。
  • checker 具体类型在各自目录定义,中间层通过 base interface 和 registry 完成类型擦除。
  • 纯类型导入使用 import type

配置契约与校验

配置加载流程固定为:unknown -> AuthoringProbeConfig -> NormalizedProbeConfig -> ValidatedProbeConfig -> ResolvedConfig

层级 职责
Authoring 用户 YAML 可书写形态,允许变量引用和 expect 简写
Normalized 变量替换和 expect 简写展开后的契约校验形态
Validated 通过契约校验和语义校验的形态
Resolved checker resolve() 后的运行期配置

Ajv 保持严格拒绝模式:allErrors: true、不启用类型强制转换、不注入默认值、不自动删除未知字段。默认对象策略是 additionalProperties: false,只有明确的动态键值表可以开放任意键名。

新增或修改配置字段时必须同步更新 TypeBox schema fragments、probe-config.schema.json、语义 validator、测试和对应用户文档并运行 bun run schema:check

数据存储

存储层基于 bun:sqliteWAL 模式运行,数据库文件位于配置的 dataDir 下。

方法 用途
syncTargets(targets) 启动期同步 targets
insertCheckResult() 写入单条检查结果
getTargets() 查询全部 targets
getLatestChecksMap() 批量获取每个 target 的最新检查结果
getAllTargetWindowStats(from, to) 批量获取窗口基础计数
getDashboardIncidentStates(from, to) 获取 Dashboard 窗口状态序列
getAllRecentSamples(limit) 批量获取最近采样
getTargetCheckpoints(targetId, from, to) 获取单目标窗口检查点序列
getTargetDurations(targetId, from, to) 获取单目标成功耗时数组
getHistory() 分页查询历史记录
prune(retentionMs) 清理过期数据

数据库只负责存储、筛选、排序、分页、LIMIT 和基础聚合。指标语义在后端应用层实现。

拨测引擎

  • 按 interval 分组,每组独立定时触发。
  • 使用 es-toolkit/Semaphore 限制全局最大并发数。
  • 通过 checkerRegistry.get(target.type) 选择 runner。
  • 每次检查创建 AbortController 并按 target.timeoutMs 触发 abort。
  • 状态变化通过注入的 Logger 输出结构化日志。

日志模块

后端运行时代码统一通过 Logger 接口输出日志,禁止直接使用 console.*。配置加载失败前使用 ConsoleFallbackLogger

实现 用途
PinoLoggerWrapper 生产运行时,封装 Pino、pino-pretty、pino-roll
NoopLogger 静默丢弃日志
MemoryLogger 测试替身
ConsoleFallbackLogger 配置加载失败前的降级日志

敏感信息会自动 redact authorizationcookieset-cookieauthTokenkeypasswordtokenapiKey 及其嵌套路径。

expect 系统

共享断言基础设施位于 src/server/checker/expect/。新增或修改 checker 的 expect 字段时,按以下原则选择模型:

模型 用途 典型字段
enum / boolean 状态类结果,结果集合小且稳定 HTTP status、Cmd exitCode、TCP connected、UDP responded、ICMP alive
ValueMatcher 数字指标和字符串元数据 durationMs、rowCount、finishReason、usage
ContentExpectations 返回内容或半结构化内容 body、stdout、stderr、banner、response、output、result
KeyedExpectations 动态键值断言 headers、DB rows 列值

详细 checker 开发流程见 Checker 开发

错误模型

  • API 错误:{ error: "描述", status: <code> }
  • CheckFailure{ kind: "error" | "mismatch", phase, path, expected?, actual?, message }

expect 校验失败记录首个失败原因;网络、超时、进程崩溃统一为 kind: "error"

后端测试与验证

变更类型 测试重点
API 路由 tests/server/app.test.ts 集成行为
配置 schema 或语义校验 schema 导出、合法配置、非法配置
store SQLite 写入、查询、分页、聚合和清理
engine 调度、并发、超时、结果写入和状态变化日志
expect 基础设施 matcher 语义、快速失败、错误信息
checker runner Checker 开发

后端运行时代码统一通过注入的 Logger 输出日志,禁止直接使用 console.*。新增或修改后端逻辑通常需要运行 bun run check;影响构建产物或前后端集成时运行 bun run verify

更新触发条件

修改后端 API、共享类型、配置契约、store、engine、logger、expect 基础设施、错误模型或后端测试规范时,必须更新本文档。