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:
98
packages/correlation/src/emitter.ts
Normal file
98
packages/correlation/src/emitter.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
import { correlationService } from "@shieldai/correlation";
|
||||
|
||||
export async function emitDarkWatchAlert(
|
||||
userId: string,
|
||||
exposureId: string,
|
||||
alertId: string,
|
||||
breachName: string,
|
||||
severity: string,
|
||||
channel: string,
|
||||
dataType?: string[],
|
||||
dataSource?: string
|
||||
): Promise<void> {
|
||||
try {
|
||||
await correlationService.ingestDarkWatchAlert(userId, alertId, {
|
||||
exposureId,
|
||||
breachName,
|
||||
severity,
|
||||
channel,
|
||||
dataType,
|
||||
dataSource,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(`[Correlation] DarkWatch alert emit failed:`, err);
|
||||
}
|
||||
}
|
||||
|
||||
export async function emitSpamShieldAlert(
|
||||
userId: string,
|
||||
analysisId: string,
|
||||
phoneNumber: string,
|
||||
decision: string,
|
||||
confidence: number,
|
||||
reasons?: string[],
|
||||
channel?: "call" | "sms",
|
||||
hiyaReputationScore?: number,
|
||||
truecallerSpamScore?: number
|
||||
): Promise<void> {
|
||||
try {
|
||||
await correlationService.ingestSpamShieldAlert(userId, analysisId, {
|
||||
phoneNumber,
|
||||
decision,
|
||||
confidence,
|
||||
reasons,
|
||||
channel,
|
||||
hiyaReputationScore,
|
||||
truecallerSpamScore,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(`[Correlation] SpamShield alert emit failed:`, err);
|
||||
}
|
||||
}
|
||||
|
||||
export async function emitVoicePrintAlert(
|
||||
userId: string,
|
||||
jobId: string,
|
||||
verdict: string,
|
||||
syntheticScore: number,
|
||||
confidence: number,
|
||||
matchedEnrollmentId?: string,
|
||||
matchedSimilarity?: number,
|
||||
analysisType?: string
|
||||
): Promise<void> {
|
||||
try {
|
||||
await correlationService.ingestVoicePrintAlert(userId, jobId, {
|
||||
jobId,
|
||||
verdict,
|
||||
syntheticScore,
|
||||
confidence,
|
||||
matchedEnrollmentId,
|
||||
matchedSimilarity,
|
||||
analysisType,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(`[Correlation] VoicePrint alert emit failed:`, err);
|
||||
}
|
||||
}
|
||||
|
||||
export async function emitCallAnalysisAlert(
|
||||
userId: string,
|
||||
callId: string,
|
||||
eventType?: string,
|
||||
mosScore?: number,
|
||||
anomaly?: string,
|
||||
sentiment?: { label: string; score: number }
|
||||
): Promise<void> {
|
||||
const sourceAlertId = `call-${callId}-${Date.now()}`;
|
||||
try {
|
||||
await correlationService.ingestCallAnalysisAlert(userId, sourceAlertId, {
|
||||
callId,
|
||||
eventType,
|
||||
mosScore,
|
||||
anomaly,
|
||||
sentiment,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(`[Correlation] CallAnalysis alert emit failed:`, err);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user