Add Protection Report Generator with HTML/PDF output and scheduled delivery (FRE-4575)

- Report service: data collection from all three engines, HTML rendering (Handlebars), PDF generation (pdfkit)
- REST API: /reports endpoints for generate, history, view, PDF download, scheduling
- BullMQ workers: queued report generation with retry, monthly/annual scheduler triggers
- DB: SecurityReport model with Prisma schema and type exports
- Email: report_ready template in shared-notifications
- All dependencies wired through existing packages

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
2026-05-09 22:54:46 -04:00
parent de0ddac65d
commit 2521c4e998
17 changed files with 1712 additions and 1 deletions

View File

@@ -272,3 +272,96 @@ export interface SchedulerConfig {
}
export { generateRequestId, extractOrGenerateRequestId } from "./requestId";
// ============================================
// Report Generation Types
// ============================================
export const ReportType = {
MONTHLY_PLUS: "MONTHLY_PLUS",
ANNUAL_PREMIUM: "ANNUAL_PREMIUM",
} as const;
export type ReportType = (typeof ReportType)[keyof typeof ReportType];
export const ReportStatus = {
PENDING: "PENDING",
GENERATING: "GENERATING",
COMPLETED: "COMPLETED",
FAILED: "FAILED",
DELIVERED: "DELIVERED",
} as const;
export type ReportStatus = (typeof ReportStatus)[keyof typeof ReportStatus];
export interface ReportExposureSummary {
totalExposures: number;
newExposures: number;
resolvedExposures: number;
criticalExposures: number;
warningExposures: number;
infoExposures: number;
exposuresBySource: Record<string, number>;
}
export interface ReportSpamStats {
callsBlocked: number;
textsBlocked: number;
callsFlagged: number;
textsFlagged: number;
falsePositives: number;
totalSpamEvents: number;
}
export interface ReportVoiceStats {
analysesRun: number;
threatsDetected: number;
enrollmentsActive: number;
syntheticDetections: number;
voiceMismatchEvents: number;
}
export interface ReportHomeTitleStats {
propertiesMonitored: number;
changesDetected: number;
alertsTriggered: number;
}
export interface ReportRecommendation {
category: string;
priority: 'high' | 'medium' | 'low';
title: string;
description: string;
}
export interface ReportDataPayload {
exposureSummary: ReportExposureSummary;
spamStats: ReportSpamStats;
voiceStats: ReportVoiceStats;
homeTitleStats?: ReportHomeTitleStats;
recommendations: ReportRecommendation[];
protectionScore: number;
previousProtectionScore?: number;
}
export interface GenerateReportInput {
userId: string;
subscriptionId: string;
reportType: ReportType;
periodStart?: Date;
periodEnd?: Date;
}
export interface SecurityReportOutput {
id: string;
userId: string;
reportType: ReportType;
status: ReportStatus;
periodStart: Date;
periodEnd: Date;
title: string;
summary?: string;
pdfUrl?: string;
dataPayload?: ReportDataPayload;
error?: string;
createdAt: Date;
deliveredAt?: Date;
}