import { isPassiveCanaryRuntime } from './server/portal-runtime-role.mjs'; import { healthBaselineJobIntervalMs, healthBaselineJobUserBatchLimit, isHealthBaselineJobEnabled, } from './health-baseline-worker-config.mjs'; import { listHealthBaselineJobUserIds, runHealthBaselineJob, } from './health-baseline-job.mjs'; export function startHealthBaselineWorker({ healthDataRuntime = null, eventNotificationService = null, pool = null, env = process.env, logger = console, intervalMs = healthBaselineJobIntervalMs(env), userLimit = healthBaselineJobUserBatchLimit(env), runOnStart = false, setIntervalFn = setInterval, listUserIdsFn = listHealthBaselineJobUserIds, runJobFn = runHealthBaselineJob, } = {}) { const observationStore = healthDataRuntime?.observationStore ?? null; const baselineStore = healthDataRuntime?.baselineStore ?? null; const eventStore = healthDataRuntime?.eventStore ?? null; if ( isPassiveCanaryRuntime(env) || !isHealthBaselineJobEnabled(env) || !observationStore || !baselineStore ) { return { stop() {} }; } let stopped = false; let running = false; const runOnce = async () => { if (running || stopped) return; running = true; try { const userIds = await listUserIdsFn({ observationStore, pool, limit: userLimit, }); if (!userIds.length) return; const summary = await runJobFn({ userIds, observationStore, baselineStore, eventStore, eventNotificationService, env, logger, }); if (summary.updated > 0 || summary.newEvents > 0 || summary.notificationsSent > 0) { logger.log?.( `[Health baseline job] processed=${summary.processed} updated=${summary.updated} newEvents=${summary.newEvents} notifications=${summary.notificationsSent}`, ); } } catch (error) { logger.warn?.('Health baseline job worker failed:', error); } finally { running = false; } }; if (runOnStart) { void runOnce(); } const timer = setIntervalFn(() => { void runOnce(); }, intervalMs); timer.unref?.(); return { stop() { stopped = true; clearInterval(timer); }, runOnce, }; }