feat: 结构化 observation 替代 statusDetail,API 层动态构造 detail
- CheckResult: statusDetail -> observation (持久化) + detail (API 动态派生) - 存储: status_detail 列 -> observation TEXT (JSON) - CheckerDefinition: 新增 buildDetail(observation) 方法 - 各 checker 返回结构化 observation,API 层通过 registry 调用 buildDetail - HTTP: bodyPreview 在 status/header 失败时也提前采集 - UDP: observation 包含 durationMs,未响应归为 error failure - CMD: 超时/输出超限时保留已收集 observation - TCP: connectTimeMs 仅含连接建立耗时,不含 banner 等待 - 新增 buildDetail 单测和 mapCheckResult 覆盖测试 - 同步 openspec 主规范,归档 checker-observation 变更
This commit is contained in:
@@ -80,7 +80,7 @@ describe("API 路由", () => {
|
||||
durationMs: 100,
|
||||
failure: null,
|
||||
matched: true,
|
||||
statusDetail: "200 OK",
|
||||
observation: null,
|
||||
targetId: targets[0]!.id,
|
||||
timestamp: "2025-01-01T00:00:00.000Z",
|
||||
});
|
||||
@@ -95,7 +95,7 @@ describe("API 路由", () => {
|
||||
phase: "status",
|
||||
},
|
||||
matched: false,
|
||||
statusDetail: null,
|
||||
observation: null,
|
||||
targetId: targets[0]!.id,
|
||||
timestamp: "2025-01-01T00:10:00.000Z",
|
||||
});
|
||||
@@ -110,7 +110,7 @@ describe("API 路由", () => {
|
||||
phase: "status",
|
||||
},
|
||||
matched: false,
|
||||
statusDetail: null,
|
||||
observation: null,
|
||||
targetId: targets[0]!.id,
|
||||
timestamp: "2025-01-01T00:20:00.000Z",
|
||||
});
|
||||
@@ -118,7 +118,7 @@ describe("API 路由", () => {
|
||||
durationMs: 200,
|
||||
failure: null,
|
||||
matched: true,
|
||||
statusDetail: "200 OK",
|
||||
observation: null,
|
||||
targetId: targets[0]!.id,
|
||||
timestamp: "2025-01-01T00:40:00.000Z",
|
||||
});
|
||||
@@ -126,7 +126,7 @@ describe("API 路由", () => {
|
||||
durationMs: 400,
|
||||
failure: null,
|
||||
matched: true,
|
||||
statusDetail: "200 OK",
|
||||
observation: null,
|
||||
targetId: targets[0]!.id,
|
||||
timestamp: "2025-01-01T01:10:00.000Z",
|
||||
});
|
||||
@@ -136,7 +136,7 @@ describe("API 路由", () => {
|
||||
durationMs: 120,
|
||||
failure: null,
|
||||
matched: true,
|
||||
statusDetail: "200 OK",
|
||||
observation: null,
|
||||
targetId: targets[0]!.id,
|
||||
timestamp: new Date(now - 90 * 60 * 1000).toISOString(),
|
||||
});
|
||||
@@ -151,7 +151,7 @@ describe("API 路由", () => {
|
||||
phase: "status",
|
||||
},
|
||||
matched: false,
|
||||
statusDetail: null,
|
||||
observation: null,
|
||||
targetId: targets[0]!.id,
|
||||
timestamp: new Date(now - 60 * 60 * 1000).toISOString(),
|
||||
});
|
||||
@@ -166,7 +166,7 @@ describe("API 路由", () => {
|
||||
phase: "status",
|
||||
},
|
||||
matched: false,
|
||||
statusDetail: null,
|
||||
observation: null,
|
||||
targetId: targets[0]!.id,
|
||||
timestamp: new Date(now - 30 * 60 * 1000).toISOString(),
|
||||
});
|
||||
@@ -428,7 +428,7 @@ describe("API 路由", () => {
|
||||
durationMs: 100,
|
||||
failure: { kind: "error", message: "test", path: "$", phase: "body" },
|
||||
matched: false,
|
||||
statusDetail: "200 OK",
|
||||
observation: null,
|
||||
targetId: t1Id,
|
||||
timestamp: "2025-06-01T00:00:00.000Z",
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user