Add tier-based scan scheduler and webhook triggers (FRE-4498)

- ScanScheduler: tier-based scheduling (BASIC=24h, PLUS=6h, PREMIUM=1h)
- WebhookHandler: HMAC-verified webhook ingestion with SCAN_TRIGGER support
- API routes: /scheduler and /webhooks endpoints under /api/v1/darkwatch
- Jobs: scheduled scan checker + webhook retry processor via BullMQ
- Schema: ScanSchedule, WebhookEvent models; ScanJob.scheduledBy field
- Types: ScheduleStatus, WebhookEventType, WebhookTriggerInput
- Tests: scheduler lifecycle + webhook signature/processing tests

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
2026-04-30 10:57:56 -04:00
parent 76d431e1ec
commit 9fb5379b7a
43 changed files with 7819 additions and 93 deletions

View File

@@ -141,3 +141,38 @@ export interface VoiceEnrollmentOutput {
durationSec?: number;
createdAt: Date;
}
export const ScheduleStatus = {
ACTIVE: "ACTIVE",
PAUSED: "PAUSED",
} as const;
export type ScheduleStatus = (typeof ScheduleStatus)[keyof typeof ScheduleStatus];
export const WebhookEventType = {
SCAN_TRIGGER: "SCAN_TRIGGER",
BREACH_DETECTED: "BREACH_DETECTED",
SUBSCRIPTION_CHANGE: "SUBSCRIPTION_CHANGE",
} as const;
export type WebhookEventType = (typeof WebhookEventType)[keyof typeof WebhookEventType];
export interface WebhookTriggerInput {
eventType: string;
payload: Record<string, unknown>;
source?: string;
signature?: string;
}
export interface ScanScheduleOutput {
id: string;
userId: string;
intervalMinutes: number;
cronExpression: string;
status: ScheduleStatus;
lastScanAt?: Date;
nextScanAt?: Date;
}
export interface SchedulerConfig {
intervalMinutes: number;
cronExpression: string;
}