feat(workbench): redesign investigation reports and diagrams

This commit is contained in:
2026-10-10 16:02:47 +08:00
parent 85a9a3ab45
commit ba78a24384
27 changed files with 2380 additions and 187 deletions
@@ -0,0 +1,76 @@
import { describe, expect, it } from "vitest";
import { investigationReportSchema } from "./investigation-report";
const base = {
title: "调查报告",
current_conclusion: "无法确定原因",
conclusion_boundary: "仅有上游监测",
evidence_refs: ["query-1"],
recommendations: [],
pending_items: []
};
const result = {
...base,
stage: "final",
outcome: "insufficient_data",
stop_reason: "缺少采样",
data_gaps: [
{
gap_id: "g1",
node_id: "read",
missing_data: "末梢采样",
scope: "投诉小区,投诉时段",
impact: "无法确定异常来源",
required_data: "该时段采样结果",
evidence_refs: ["query-1"],
blocking: true
}
]
};
describe("investigation report read contract", () => {
it("preserves unknown historical facts instead of inventing a result or empty gap list", () => {
const legacy = investigationReportSchema.parse(base);
expect(legacy.outcome).toBeUndefined();
expect(legacy.data_gaps).toBeUndefined();
expect(
investigationReportSchema.parse({
...base,
stage: null,
outcome: null,
data_gaps: null,
stop_reason: null
}).data_gaps
).toBeNull();
});
it("accepts an evidenced final insufficient-data result", () => {
expect(investigationReportSchema.parse(result).outcome).toBe("insufficient_data");
});
it("reads a narrative diagram without requiring a legacy execution plan", () => {
const value = investigationReportSchema.parse({
...result,
data_gaps: [{ ...result.data_gaps[0], node_id: null }],
diagram: {
title: "调查脉络",
mermaid: 'flowchart TD\nA["查询"] --> B["判断"]',
node_refs: [{ node_id: "A", label: "查询", evidence_refs: ["query-1"] }]
}
});
expect(value.diagram?.node_refs[0]?.action_refs).toEqual([]);
expect(value.data_gaps?.[0]?.node_id).toBeNull();
});
it.each([
{ outcome: "other" },
{ stage: "interim" },
{ stop_reason: null },
{ data_gaps: [] },
{ recommendations: ["自动派单"] },
{ pending_items: ["等人工"] },
{ outcome: "concluded" },
{ data_gaps: [{ ...result.data_gaps[0], evidence_refs: [] }] },
{ data_gaps: [result.data_gaps[0], result.data_gaps[0]] },
{ schema: "invented" }
])("rejects inconsistent business facts %j", (changes) => {
expect(() => investigationReportSchema.parse({ ...result, ...changes })).toThrow();
});
});