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:
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user