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>
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,
|
|
};
|
|
}
|