diff --git a/backend/src/index.ts b/backend/src/index.ts index dcec121..39b7f48 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -336,6 +336,59 @@ export const processDocumentJobs = onSchedule({ } }); +// Health probe scheduler — separate from document processing (PITFALL-2, HLTH-03) +export const runHealthProbes = onSchedule({ + schedule: 'every 5 minutes', + timeoutSeconds: 60, + memory: '256MiB', + retryCount: 0, // Probes should not retry — they run again in 5 minutes anyway + secrets: [ + anthropicApiKey, // for LLM probe + openaiApiKey, // for OpenAI probe fallback + databaseUrl, // for Supabase probe + supabaseServiceKey, + supabaseAnonKey, + ], +}, async (_event) => { + const { healthProbeService } = await import('./services/healthProbeService'); + const { alertService } = await import('./services/alertService'); + + const results = await healthProbeService.runAllProbes(); + await alertService.evaluateAndAlert(results); + + logger.info('runHealthProbes: complete', { + probeCount: results.length, + statuses: results.map(r => ({ service: r.service_name, status: r.status })), + }); +}); + +// Retention cleanup — weekly, separate from document processing (PITFALL-7, INFR-03) +export const runRetentionCleanup = onSchedule({ + schedule: 'every monday 02:00', + timeoutSeconds: 120, + memory: '256MiB', + secrets: [databaseUrl, supabaseServiceKey, supabaseAnonKey], +}, async (_event) => { + const { HealthCheckModel } = await import('./models/HealthCheckModel'); + const { AlertEventModel } = await import('./models/AlertEventModel'); + const { deleteProcessingEventsOlderThan } = await import('./services/analyticsService'); + + const RETENTION_DAYS = 30; + + const [hcCount, alertCount, eventCount] = await Promise.all([ + HealthCheckModel.deleteOlderThan(RETENTION_DAYS), + AlertEventModel.deleteOlderThan(RETENTION_DAYS), + deleteProcessingEventsOlderThan(RETENTION_DAYS), + ]); + + logger.info('runRetentionCleanup: complete', { + retentionDays: RETENTION_DAYS, + deletedHealthChecks: hcCount, + deletedAlerts: alertCount, + deletedProcessingEvents: eventCount, + }); +}); + // Scheduled function to clean up old database records // Runs daily at 3 AM UTC to enforce retention policies export const cleanupOldData = onSchedule({