From 9311f1044bfdf91c0dfd04aa7ffd508bd6aa4772 Mon Sep 17 00:00:00 2001 From: lorentz Date: Tue, 21 Jul 2026 11:36:16 -0400 Subject: [PATCH] fix(quick-260721-fy8): add mimecast-sync and qbo dispatch branches to scheduler - Extend ScheduleConfig.sync_type union with 'mimecast-sync' - Add mimecast-sync branch calling runMimecastIncrementalSync() behind isMimecastConfigured(), mirroring the engagement/zoom configured-gate pattern - Add qbo branch calling getQboSyncService().incrementalSync('scheduled') behind an integration_settings disabled check, mirroring the pax8-daily disable-check pattern - Both branches previously fell through to the generic Autotask fullSync() catch-all, which also contended for the SyncService singleton mutex --- lib/services/sync-scheduler.ts | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/services/sync-scheduler.ts b/lib/services/sync-scheduler.ts index 48a0048..b907094 100644 --- a/lib/services/sync-scheduler.ts +++ b/lib/services/sync-scheduler.ts @@ -22,7 +22,7 @@ export interface ScheduleConfig { name: string; description: string; cron_expression: string; - sync_type: 'incremental' | 'full' | 'veeam-incremental' | 'veeam-full' | 'veeam-rpo-check' | 'contract-services' | 'engagement-daily' | 'zoom-daily' | 'morning-summary' | 'ticket-digest-daily' | 'ticket-digest-weekly' | 'ticket-digest-monthly' | 'device-link-reconcile' | 'integration-health' | 'qbo' | 'appgate-sessions' | 'appgate-daily' | 'tickets-reconcile' | 'pax8-daily' | 'phishing-sweep'; + sync_type: 'incremental' | 'full' | 'veeam-incremental' | 'veeam-full' | 'veeam-rpo-check' | 'contract-services' | 'engagement-daily' | 'zoom-daily' | 'morning-summary' | 'ticket-digest-daily' | 'ticket-digest-weekly' | 'ticket-digest-monthly' | 'device-link-reconcile' | 'integration-health' | 'qbo' | 'mimecast-sync' | 'appgate-sessions' | 'appgate-daily' | 'tickets-reconcile' | 'pax8-daily' | 'phishing-sweep'; years_back?: number; is_enabled: boolean; last_run?: Date; @@ -491,6 +491,28 @@ class SyncScheduler { await getPax8SyncService().fullSync('scheduled'); } } + } else if (config.sync_type === 'mimecast-sync') { + const { isMimecastConfigured } = await import('@/lib/services/mimecast-client'); + if (!isMimecastConfigured()) { + console.log('[SCHEDULER] Skipping mimecast-sync — Mimecast not configured'); + } else { + const { runMimecastIncrementalSync } = await import('@/lib/services/mimecast-sync-service'); + const result = await runMimecastIncrementalSync(); + console.log( + `[SCHEDULER] mimecast-sync: messagesUpserted=${result.messagesUpserted} threatsUpserted=${result.threatsUpserted} bodiesFetched=${result.bodiesFetched} purgedMessages=${result.purgedMessages} errors=${result.errors.length} durationMs=${result.durationMs}` + ); + } + } else if (config.sync_type === 'qbo') { + const disabledRes = await postgresClient.query<{ disabled: boolean }>( + `SELECT disabled FROM integration_settings WHERE key = 'qbo'` + ); + const isDisabled = disabledRes.rows[0]?.disabled === true; + if (isDisabled) { + console.log('[SCHEDULER] Skipping qbo sync — QBO disabled via /admin/integrations'); + } else { + const { getQboSyncService } = await import('@/lib/services/qbo-sync-service'); + await getQboSyncService().incrementalSync('scheduled'); + } } else if (config.sync_type === 'incremental') { await this.syncService.incrementalSync('scheduled'); } else {