51 lines
1.7 KiB
TypeScript
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,
|
||
|
|
};
|
||
|
|
}
|