feat(workbench): expand SCADA monitoring and investigation presentation

This commit is contained in:
2026-11-07 19:50:14 +08:00
parent 0801e161ec
commit ba71e2d529
133 changed files with 6754 additions and 1438 deletions
@@ -2,14 +2,12 @@ import { describe, expect, it } from "vitest";
import { createInvestigationDevCase, investigationDevCases } from "./investigation-dev-cases";
import { parseInvestigationDevJsonl } from "./investigation-dev-preview";
const center: [number, number] = [121.48, 31.1];
const target = { source_id: "scada", feature_id: "P1" } as const;
describe("switchable investigation Dev cases", () => {
it.each(investigationDevCases.filter((item) => !item.id.startsWith("invalid_")))(
"$label produces a valid, nonempty batch within the existing presentation contract",
({ id }) => {
const input = createInvestigationDevCase(id, center, target);
const input = createInvestigationDevCase(id);
const preview = parseInvestigationDevJsonl(input);
const records = input.split("\n").map((line) => JSON.parse(line));
expect(records.every((record) => typeof record.record_type === "string")).toBe(true);
@@ -28,50 +26,57 @@ describe("switchable investigation Dev cases", () => {
it.each(investigationDevCases.filter((item) => item.id.startsWith("invalid_")))(
"$label cannot produce an executable batch",
({ id }) => {
expect(() => parseInvestigationDevJsonl(createInvestigationDevCase(id, center))).toThrow(
expect(() => parseInvestigationDevJsonl(createInvestigationDevCase(id))).toThrow(
id === "invalid_json" ? "第 2 行不是合法 JSON" : "第 1 行展示指令不合法"
);
}
);
it("only queries an existing task target and falls back to a synthetic map point without one", () => {
const withTarget = parseInvestigationDevJsonl(
createInvestigationDevCase("map_targets", center, target)
);
expect(withTarget.commands[0]).toMatchObject({
action: "highlight_features",
layer: "scada",
feature_ids: ["P1"]
});
const withoutTarget = parseInvestigationDevJsonl(
createInvestigationDevCase("map_targets", center)
);
expect(withoutTarget.commands).toHaveLength(1);
expect(withoutTarget.commands[0]).toMatchObject({ action: "set_overlay", mode: "geometry" });
it("keeps feature locating and highlighting in map debugging rather than running another path from a synthetic case", () => {
expect(investigationDevCases.some((item) => String(item.id) === "map_targets")).toBe(false);
for (const item of investigationDevCases.filter((item) => !item.id.startsWith("invalid_"))) {
const preview = parseInvestigationDevJsonl(createInvestigationDevCase(item.id));
expect(preview.commands.some((command) => ["locate_features", "highlight_features"].includes(command.action))).toBe(false);
}
});
it("provides dense tables and full-day series without exceeding publication limits", () => {
const tables = parseInvestigationDevJsonl(createInvestigationDevCase("complex_tables"));
const nodes = tables.blocks.map((block) => Object.values(block.spec.elements)[0]);
expect(nodes[0].props.columns).toHaveLength(8);
expect(nodes[0].props.rows).toHaveLength(50);
expect(nodes[1].props.rows).toEqual([]);
const charts = parseInvestigationDevJsonl(createInvestigationDevCase("complex_charts"));
const pressure = Object.values(charts.blocks[0].spec.elements)[0].props;
expect(pressure.x_data).toHaveLength(96);
expect(pressure.series).toHaveLength(8);
});
it.each(["data_only", "candidates_table", "valves_table"] as const)(
"%s never turns synthetic asset IDs or embedded action fields into map queries or writes",
(id) => {
const preview = parseInvestigationDevJsonl(createInvestigationDevCase(id, center));
const preview = parseInvestigationDevJsonl(createInvestigationDevCase(id));
expect(preview.commands).toEqual([]);
expect(preview.records).toHaveLength(2);
expect(preview.records.every((record) => record.origin === "synthetic")).toBe(true);
}
);
it.each([
[180, 90],
[-180, -90],
[540, 85]
] as Array<[number, number]>)(
"keeps synthetic geometry within schema bounds near longitude %s, latitude %s",
(longitude, latitude) => {
for (const id of ["combined", "map_targets", "impact_area", "complaint_heatmap"] as const) {
expect(() =>
parseInvestigationDevJsonl(createInvestigationDevCase(id, [longitude, latitude]))
).not.toThrow();
it("keeps every spatial fixture inside the verified tjwater_v2 network bounds", () => {
const visit = (value: unknown) => {
if (!Array.isArray(value)) return;
if (typeof value[0] === "number" && typeof value[1] === "number") {
expect(value[0]).toBeGreaterThanOrEqual(121.3516324392188);
expect(value[0]).toBeLessThanOrEqual(121.77248154882845);
expect(value[1]).toBeGreaterThanOrEqual(30.810500094449143);
expect(value[1]).toBeLessThanOrEqual(31.00720694600021);
} else value.forEach(visit);
};
for (const id of ["combined", "complex_investigation", "impact_area", "complaint_heatmap"] as const) {
const preview = parseInvestigationDevJsonl(createInvestigationDevCase(id));
for (const command of preview.commands) if (command.action === "set_overlay") {
for (const feature of command.data.features) visit(feature.geometry.coordinates);
}
}
);
});
});