import { getQueue, type QueueName } from './index'; import { logger } from '@/lib/logger'; interface RecurringJobDef { queue: QueueName; name: string; pattern: string; } /** * Register all recurring jobs from 11-REALTIME-AND-BACKGROUND-JOBS.md Section 3.2. * Called once on server startup. */ export async function registerRecurringJobs(): Promise { const recurring: RecurringJobDef[] = [ // Documenso signature fallback poll — primary is webhooks, this is safety net { queue: 'documents', name: 'signature-poll', pattern: '0 */6 * * *' }, // Reminder checks { queue: 'notifications', name: 'reminder-check', pattern: '0 * * * *' }, { queue: 'notifications', name: 'reminder-overdue-check', pattern: '*/15 * * * *' }, // Google Calendar background sync { queue: 'maintenance', name: 'calendar-sync', pattern: '*/30 * * * *' }, // Daily checks at 08:00 { queue: 'notifications', name: 'invoice-overdue-check', pattern: '0 8 * * *' }, { queue: 'notifications', name: 'tenure-expiry-check', pattern: '0 8 * * *' }, // Exchange rate refresh every 6 hours { queue: 'maintenance', name: 'currency-refresh', pattern: '0 */6 * * *' }, // Database backup / cleanup { queue: 'maintenance', name: 'database-backup', pattern: '0 2 * * *' }, { queue: 'maintenance', name: 'backup-cleanup', pattern: '0 3 * * 0' }, // Sunday 03:00 // Session cleanup { queue: 'maintenance', name: 'session-cleanup', pattern: '0 4 * * *' }, // Report scheduler — checks every minute for reports due to run { queue: 'reports', name: 'report-scheduler', pattern: '* * * * *' }, // Notification digest — configurable per user; placeholder fires hourly // TODO(L2): make per-user schedule configurable (read from user_settings) { queue: 'email', name: 'notification-digest', pattern: '0 * * * *' }, // Cleanup jobs { queue: 'maintenance', name: 'temp-file-cleanup', pattern: '0 5 * * *' }, { queue: 'maintenance', name: 'form-expiry-check', pattern: '0 * * * *' }, ]; for (const job of recurring) { const queue = getQueue(job.queue); await queue.upsertJobScheduler( job.name, { pattern: job.pattern }, { data: {}, name: job.name }, ); logger.info({ queue: job.queue, job: job.name, pattern: job.pattern }, 'Registered recurring job'); } logger.info({ count: recurring.length }, 'All recurring jobs registered'); }