import { sql } from "drizzle-orm"; import { db } from "../db/db.controller.js"; import { createLogger } from "../logger/logger.controller.js"; const log = createLogger({ module: "db", subModule: "notifications", }); /** * Creates/updates Postgres notification functions + triggers. * * Safe to run on every app startup. * CREATE OR REPLACE updates the function. * DROP TRIGGER IF EXISTS prevents duplicate triggers. */ export async function setupDbNotifications() { log.info({}, "Setting up DB notifications"); await setupLogsNotifications(); await setupDockScansNotifications(); log.info({}, "DB notifications setup complete"); } /** * Logs notification setup. * * Flow: * 1. app inserts into logs table * 2. trigger runs after insert * 3. Postgres sends NOTIFY logs_inserted with the new log id * 4. Node listener receives id and fetches/emits full row */ async function setupLogsNotifications() { await db.execute(sql` CREATE OR REPLACE FUNCTION notify_logs_inserted() RETURNS trigger AS $$ BEGIN PERFORM pg_notify( 'logs_inserted', json_build_object( 'table', TG_TABLE_NAME, 'action', TG_OP, 'id', NEW.id )::text ); RETURN NEW; END; $$ LANGUAGE plpgsql; `); await db.execute(sql` DROP TRIGGER IF EXISTS logs_inserted_notify_trigger ON logs; `); await db.execute(sql` CREATE TRIGGER logs_inserted_notify_trigger AFTER INSERT ON logs FOR EACH ROW EXECUTE FUNCTION notify_logs_inserted(); `); log.info({}, "Logs DB notification trigger ready"); } async function setupDockScansNotifications() { await db.execute(sql` CREATE OR REPLACE FUNCTION notify_dock_scan_inserted() RETURNS trigger AS $$ BEGIN PERFORM pg_notify( 'dock_scan_inserted', json_build_object( 'table', TG_TABLE_NAME, 'action', TG_OP, 'id', NEW.id )::text ); RETURN NEW; END; $$ LANGUAGE plpgsql; `); await db.execute(sql` DROP TRIGGER IF EXISTS dock_scan_inserted_notify_trigger ON dock_door_scans; `); await db.execute(sql` CREATE TRIGGER dock_scan_inserted_notify_trigger AFTER INSERT ON dock_door_scans FOR EACH ROW EXECUTE FUNCTION notify_dock_scan_inserted(); `); log.info({}, "Dock scan DB notification trigger ready"); }