/** * Run Cleanup Jobs Edge Function * * Executes all automated cleanup tasks for the Sacred Pipeline: * - Expired idempotency keys * - Stale temporary references * - Abandoned locks (deleted/banned users, expired locks) * - Old approved/rejected submissions (90 day retention) * * Designed to be called daily via pg_cron */ import { createClient } from 'https://esm.sh/@supabase/supabase-js@2.57.4'; import { createEdgeFunction } from '../_shared/edgeFunctionWrapper.ts'; import { edgeLogger } from '../_shared/logger.ts'; interface CleanupResult { idempotency_keys?: { deleted: number; success: boolean; error?: string; }; temp_refs?: { deleted: number; oldest_date: string | null; success: boolean; error?: string; }; locks?: { released: number; details: { deleted_user_locks: number; banned_user_locks: number; expired_locks: number; }; success: boolean; error?: string; }; old_submissions?: { deleted: number; by_status: Record; oldest_date: string | null; success: boolean; error?: string; }; execution: { started_at: string; completed_at: string; duration_ms: number; }; } export default createEdgeFunction( { name: 'run-cleanup-jobs', requireAuth: false, }, async (req, context, supabase) => { const startTime = Date.now(); edgeLogger.info('Starting automated cleanup jobs', { timestamp: new Date().toISOString(), requestId: context.requestId, }); // Execute the master cleanup function const { data, error } = await supabase.rpc('run_all_cleanup_jobs'); if (error) { edgeLogger.error('Cleanup jobs failed', { error: error.message, code: error.code, duration_ms: Date.now() - startTime, requestId: context.requestId, }); throw error; } const result = data as CleanupResult; // Log detailed results edgeLogger.info('Cleanup jobs completed successfully', { idempotency_keys_deleted: result.idempotency_keys?.deleted || 0, temp_refs_deleted: result.temp_refs?.deleted || 0, locks_released: result.locks?.released || 0, submissions_deleted: result.old_submissions?.deleted || 0, duration_ms: result.execution.duration_ms, requestId: context.requestId, }); // Log any individual task failures if (!result.idempotency_keys?.success) { edgeLogger.warn('Idempotency keys cleanup failed', { error: result.idempotency_keys?.error, }); } if (!result.temp_refs?.success) { edgeLogger.warn('Temp refs cleanup failed', { error: result.temp_refs?.error, }); } if (!result.locks?.success) { edgeLogger.warn('Locks cleanup failed', { error: result.locks?.error, }); } if (!result.old_submissions?.success) { edgeLogger.warn('Old submissions cleanup failed', { error: result.old_submissions?.error, }); } return new Response( JSON.stringify({ success: true, results: result, total_duration_ms: Date.now() - startTime, }), { headers: { 'Content-Type': 'application/json' } } ); } );