Unify live session streaming and evidence fetching

- Route live terminal data through a shared live session socket
- Fetch missing evidence for alerts and classifier hits
- Add live type definitions and storage/API tests
This commit is contained in:
dirtydishes 2026-04-27 13:14:10 -04:00
parent 824b7f2fa0
commit d30513119a
10 changed files with 1923 additions and 258 deletions

View file

@ -1,4 +1,5 @@
import { describe, expect, it } from "bun:test";
import { createClickHouseClient, fetchFlowPacketById, fetchFlowPacketsBefore } from "../src/clickhouse";
import {
flowPacketsTableDDL,
FLOW_PACKETS_TABLE,
@ -36,4 +37,24 @@ describe("flow-packets storage helpers", () => {
expect(restored.features).toEqual(packet.features);
expect(restored.join_quality).toEqual(packet.join_quality);
});
it("builds before-history and id lookup queries", async () => {
const queries: string[] = [];
const client = createClickHouseClient({ url: "http://127.0.0.1:8123" });
client.query = async ({ query }) => {
queries.push(query);
return {
async json<T>() {
return [] as T;
}
};
};
await fetchFlowPacketsBefore(client, 200, 3, 15);
await fetchFlowPacketById(client, "fp-1");
expect(queries[0]).toContain("(source_ts, seq) < (200, 3)");
expect(queries[0]).toContain("ORDER BY source_ts DESC, seq DESC LIMIT 15");
expect(queries[1]).toContain("WHERE id = 'fp-1'");
});
});

View file

@ -1,4 +1,5 @@
import { describe, expect, it } from "bun:test";
import { createClickHouseClient, fetchOptionPrintsBefore, fetchOptionPrintsByTraceIds } from "../src/clickhouse";
import { normalizeOptionPrint, optionPrintsTableDDL, OPTION_PRINTS_TABLE } from "../src/option-prints";
const basePrint = {
@ -24,4 +25,25 @@ describe("option-prints storage helpers", () => {
expect(ddl).toContain(OPTION_PRINTS_TABLE);
expect(ddl).toContain("CREATE TABLE IF NOT EXISTS");
});
it("builds before/history and trace lookup queries", async () => {
const queries: string[] = [];
const client = createClickHouseClient({ url: "http://127.0.0.1:8123" });
client.query = async ({ query }) => {
queries.push(query);
return {
async json<T>() {
return [] as T;
}
};
};
await fetchOptionPrintsBefore(client, 100, 5, 20, "alpaca");
await fetchOptionPrintsByTraceIds(client, ["trace-1", "trace-2"]);
expect(queries[0]).toContain("(ts, seq) < (100, 5)");
expect(queries[0]).toContain("startsWith(trace_id, 'alpaca')");
expect(queries[0]).toContain("ORDER BY ts DESC, seq DESC LIMIT 20");
expect(queries[1]).toContain("trace_id IN ('trace-1', 'trace-2')");
});
});