feat(02-04): add runHealthProbes scheduled Cloud Function export
- Runs every 5 minutes, separate from processDocumentJobs (PITFALL-2, HLTH-03) - Calls healthProbeService.runAllProbes() then alertService.evaluateAndAlert() - Uses dynamic import() pattern matching processDocumentJobs - retryCount: 0 — probes re-run in 5 minutes, no retry needed - Lists all required secrets: anthropicApiKey, openaiApiKey, databaseUrl, supabaseServiceKey, supabaseAnonKey
This commit is contained in:
@@ -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
|
// Scheduled function to clean up old database records
|
||||||
// Runs daily at 3 AM UTC to enforce retention policies
|
// Runs daily at 3 AM UTC to enforce retention policies
|
||||||
export const cleanupOldData = onSchedule({
|
export const cleanupOldData = onSchedule({
|
||||||
|
|||||||
Reference in New Issue
Block a user