import { expect, it } from "bun:test"; import { taskPresentationCommandSchema, type TaskPresentationCommand } from "../../src/product/task-presentation.js"; import { taskPublicationCommandSchema, taskPublicationReportSchema } from "../../.opencode/tools/task-publication-schema.js"; import { taskReportSchema } from "../../src/product/investigation-report.js"; import { OperationalTaskClientError, scadaPresentationContinuation } from "../../src/product/operational-task-client.js"; it("preserves SCADA device identities through native and host publication boundaries", () => { const command: TaskPresentationCommand = { action: "open_chart", chart_id: "flow-overview", evidence_refs: ["observations"], chart: { title: "流量当前趋势", chart_type: "line", x_data: ["05:00", "05:15"], scada: { role: "current", metric: "flow", unit: "m3/h", window_start: "2026-07-16T05:00:00+08:00", window_end: "2026-07-16T08:00:00+08:00" }, series: [{ name: "524529", device_id: "524529", day_offset: 0, type: "line", data: [-6.8, 303.3], sample_times: ["2026-07-16T05:00:00+08:00", "2026-07-16T05:15:00+08:00"] }], } }; expect(taskPresentationCommandSchema.parse(command)).toEqual(command); expect(taskPublicationCommandSchema.parse(command)).toEqual(command); const report = { title: "调查", current_conclusion: "524529仅作参考", conclusion_boundary: "待复核", stage: "final", outcome: "concluded", evidence_refs: ["observations"], data_gaps: [], scada_device_ids: ["524529"] }; expect(taskReportSchema.parse(report).scada_device_ids).toEqual(["524529"]); expect(taskPublicationReportSchema.parse(report).scada_device_ids).toEqual(["524529"]); }); it("continues an incomplete SCADA presentation with the exact missing device instead of retrying other failures", () => { const rejection = new OperationalTaskClientError(409, "缺少七天同期对比设备:524529", "SCADA_PRESENTATION_INCOMPLETE"); expect(scadaPresentationContinuation(rejection)).toContain("524529"); expect(scadaPresentationContinuation(rejection)).toContain("publish_task_presentation"); expect(scadaPresentationContinuation(new OperationalTaskClientError(403, "拒绝", "PERMISSION_DENIED"))).toBeNull(); expect(scadaPresentationContinuation(new Error("transport failed"))).toBeNull(); }); it("keeps all-null current chunks aligned to their own first slot across midnight", () => { for (const [start, end, labels, times] of [ ["2026-07-16T05:08:00+08:00", "2026-07-16T08:08:00+08:00", ["07:45", "08:00"], ["2026-07-15T07:45:00+08:00", "2026-07-15T08:00:00+08:00"]], ["2026-07-15T22:08:00+08:00", "2026-07-16T01:08:00+08:00", ["00:45", "01:00"], ["2026-07-15T00:45:00+08:00", "2026-07-15T01:00:00+08:00"]], ] as const) { const command = { action: "open_chart", chart_id: "chunk", evidence_refs: ["observations"], chart: { title: "流量同期分段", chart_type: "time_comparison", x_data: labels, scada: { role: "comparison", metric: "flow", unit: "m3/h", window_start: start, window_end: end }, series: [{ name: "current", type: "line", data: [null, null], sample_times: [null, null] }, { name: "history", type: "scatter", data: [1, 2], sample_times: times }], } }; expect(taskPresentationCommandSchema.safeParse(command).success).toBe(true); expect(taskPublicationCommandSchema.safeParse(command).success).toBe(true); } });