feat(live): task 1.5.5 — snapshot-on-subscribe
Adds snapshot provider that queries the latest non-faulty position per device registered to an event, returned in the `subscribed` reply so the SPA map is populated immediately rather than waiting for the first live broadcast batch. Key changes: - src/live/snapshot.ts: createSnapshotProvider factory using DISTINCT ON (device_id) ... ORDER BY device_id, ts DESC with WHERE faulty=false; converts Date ts to epoch ms; omits speed/course when 0 (matching broadcast convention) - src/main.ts: injects createSnapshotProvider(pool) into createSubscriptionRegistry - test/live-snapshot.test.ts: 7 unit tests covering: two-device result, empty event, faulty exclusion, DISTINCT ON semantics, parameterized query, metrics observation, and error propagation The snapshot query requires the positions_device_ts_idx created in migration 0002 (task 1.5.4). Snapshot failures fail open — registry.fetchSnapshot returns [] so the subscription still succeeds with an empty initial state.
This commit is contained in:
+3
-1
@@ -24,6 +24,7 @@ import { createAuthzClient } from './live/authz.js';
|
||||
import { createSubscriptionRegistry } from './live/registry.js';
|
||||
import { createBroadcastConsumer } from './live/broadcast.js';
|
||||
import { createDeviceEventMap } from './live/device-event-map.js';
|
||||
import { createSnapshotProvider } from './live/snapshot.js';
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Startup: validate config (fail fast on bad env), build logger
|
||||
@@ -139,7 +140,8 @@ async function main(): Promise<void> {
|
||||
// 10. Build the live WebSocket server (tasks 1.5.2 and 1.5.3).
|
||||
const authClient = createAuthClient(config, logger, metrics);
|
||||
const authzClient = createAuthzClient(config, logger, metrics);
|
||||
const registry = createSubscriptionRegistry(authzClient, config, logger, metrics);
|
||||
const snapshotProvider = createSnapshotProvider(pool, logger, metrics);
|
||||
const registry = createSubscriptionRegistry(authzClient, config, logger, metrics, snapshotProvider);
|
||||
|
||||
const messageHandler = async (
|
||||
conn: LiveConnection,
|
||||
|
||||
Reference in New Issue
Block a user