Files
pn-new-crm/src/lib/services/alert-engine.ts
Matt Ciaccio 8699f81879
Some checks failed
Build & Push Docker Images / lint (push) Failing after 1m18s
Build & Push Docker Images / build-and-push (push) Has been skipped
chore(style): codebase em-dash sweep + minor layout polish
Replaces every em-dash and en-dash with regular ASCII hyphens
across comments, JSX strings, and dev-facing logs. Mostly cosmetic
but stops the inconsistent mix that crept in over the last few
months (some files used em-dashes in comments, others didn't,
some used both).

Bundles two small dashboard-layout tweaks that touch a couple of
already-modified files:
- (dashboard)/layout.tsx main padding goes from p-6 to pt-3 px-6
  pb-6 so page content sits closer to the topbar.
- Sidebar now receives the ports list it needs for the footer
  port switcher.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 22:57:01 +02:00

51 lines
1.7 KiB
TypeScript

/**
* Alert engine - runs every rule against every port. Called by the
* BullMQ recurring job 'alerts-evaluate' every 5 minutes; exposed as a
* function so integration tests can drive it without a worker.
*/
import { logger } from '@/lib/logger';
import { db } from '@/lib/db';
import { ports } from '@/lib/db/schema/ports';
import { reconcileAlertsForPort } from './alerts.service';
import { RULE_REGISTRY, listRuleIds } from './alert-rules';
export interface EngineRunSummary {
portsScanned: number;
rulesEvaluated: number;
errors: Array<{ portId: string; ruleId: string; message: string }>;
}
/** Evaluate every rule for every port, upsert + auto-resolve. */
export async function runAlertEngine(): Promise<EngineRunSummary> {
const allPorts = await db.select({ id: ports.id, slug: ports.slug }).from(ports);
return runAlertEngineForPorts(allPorts.map((p) => p.id));
}
/** Same engine scoped to a specific list of port IDs (used by tests + the
* per-port webhook trigger). */
export async function runAlertEngineForPorts(portIds: string[]): Promise<EngineRunSummary> {
const ruleIds = listRuleIds();
const errors: EngineRunSummary['errors'] = [];
for (const portId of portIds) {
for (const ruleId of ruleIds) {
try {
const candidates = await RULE_REGISTRY[ruleId](portId);
await reconcileAlertsForPort(portId, ruleId, candidates);
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
logger.warn({ portId, ruleId, err }, 'alert rule evaluator failed');
errors.push({ portId, ruleId, message });
}
}
}
return {
portsScanned: portIds.length,
rulesEvaluated: portIds.length * ruleIds.length,
errors,
};
}