Add cross-service alert correlation system FRE-4500

- Unified alert types (AlertSource, AlertCategory, CorrelationStatus, EntityType)
- NormalizedAlert and CorrelationGroup Prisma models
- AlertNormalizer for all 4 services (DarkWatch, SpamShield, VoicePrint, CallAnalysis)
- CorrelationEngine with temporal + entity-based correlation detection
- CorrelationService orchestrator with dashboard API
- Correlation API routes (/api/v1/correlation/*)
- Service emitters wired to DarkWatch, SpamShield, VoicePrint
- pnpm workspace config for monorepo
This commit is contained in:
Senior Engineer
2026-05-02 01:10:44 -04:00
committed by Michael Freno
parent 685fb57e53
commit 03276dde2d
35 changed files with 8072 additions and 31 deletions

View File

@@ -13,12 +13,106 @@ export const SubscriptionTier = {
export type SubscriptionTier = (typeof SubscriptionTier)[keyof typeof SubscriptionTier];
export const Severity = {
LOW: "LOW",
INFO: "INFO",
MEDIUM: "MEDIUM",
WARNING: "WARNING",
HIGH: "HIGH",
CRITICAL: "CRITICAL",
} as const;
export type Severity = (typeof Severity)[keyof typeof Severity];
export const AlertSource = {
DARKWATCH: "DARKWATCH",
SPAMSHIELD: "SPAMSHIELD",
VOICEPRINT: "VOICEPRINT",
CALL_ANALYSIS: "CALL_ANALYSIS",
} as const;
export type AlertSource = (typeof AlertSource)[keyof typeof AlertSource];
export const AlertCategory = {
BREACH_EXPOSURE: "BREACH_EXPOSURE",
SPAM_CALL: "SPAM_CALL",
SPAM_SMS: "SPAM_SMS",
SYNTHETIC_VOICE: "SYNTHETIC_VOICE",
VOICE_MISMATCH: "VOICE_MISMATCH",
CALL_QUALITY: "CALL_QUALITY",
CALL_ANOMALY: "CALL_ANOMALY",
CALL_EVENT: "CALL_EVENT",
} as const;
export type AlertCategory = (typeof AlertCategory)[keyof typeof AlertCategory];
export const CorrelationStatus = {
ACTIVE: "ACTIVE",
RESOLVED: "RESOLVED",
FALSE_POSITIVE: "FALSE_POSITIVE",
} as const;
export type CorrelationStatus = (typeof CorrelationStatus)[keyof typeof CorrelationStatus];
export const EntityTypes = {
PHONE_NUMBER: "PHONE_NUMBER",
EMAIL: "EMAIL",
USER_ID: "USER_ID",
CALL_ID: "CALL_ID",
IP_ADDRESS: "IP_ADDRESS",
} as const;
export type EntityType = (typeof EntityTypes)[keyof typeof EntityTypes];
export interface NormalizedAlertInput {
source: AlertSource;
category: AlertCategory;
severity: Severity;
userId: string;
title: string;
description: string;
entities: Array<{ type: EntityType; value: string }>;
sourceAlertId: string;
payload: Record<string, unknown>;
timestamp?: Date;
}
export interface CorrelationGroupOutput {
id: string;
groupId: string;
alertCount: number;
highestSeverity: Severity;
status: CorrelationStatus;
entities: Array<{ type: EntityType; value: string }>;
sources: AlertSource[];
categories: AlertCategory[];
createdAt: Date;
updatedAt: Date;
}
export interface CorrelatedAlertOutput {
id: string;
source: AlertSource;
category: AlertCategory;
severity: Severity;
userId: string;
title: string;
description: string;
entities: Array<{ type: EntityType; value: string }>;
sourceAlertId: string;
groupId: string;
payload: Record<string, unknown>;
createdAt: Date;
}
export interface CorrelationQuery {
userId?: string;
groupId?: string;
source?: AlertSource;
category?: AlertCategory;
severity?: Severity;
status?: CorrelationStatus;
entityType?: EntityType;
entityId?: string;
timeWindowMinutes?: number;
limit?: number;
offset?: number;
}
export const AlertChannel = {
EMAIL: "EMAIL",
PUSH: "PUSH",