diff --git a/lib/services/entity-sync.ts b/lib/services/entity-sync.ts index a3c7129..2fd77a8 100644 --- a/lib/services/entity-sync.ts +++ b/lib/services/entity-sync.ts @@ -136,6 +136,9 @@ export class EntitySyncService { params.filter = filters; } } + + // Track whether any filters were applied - if so, skip soft deletes + const hasAppliedFilters = params.filter && params.filter.length > 0; // Fetch data from Autotask with pagination entityLogger.phase(SyncPhase.FETCHING, 'Fetching records from Autotask API'); @@ -345,16 +348,11 @@ export class EntitySyncService { entityLogger.info('Upserted records to PostgreSQL', { upsertedCount }); // For full sync, soft delete records not in the fetched set - // IMPORTANT: Only delete for entities without date filters to avoid deleting records outside sync window + // IMPORTANT: Skip soft deletes if ANY filters were applied (date, status, active, etc.) + // because we cannot know what records exist outside the filter criteria let deletedCount = 0; - const hasDateFilter = entity === EntityType.TICKETS || - entity === EntityType.TASKS || - entity === EntityType.TIME_ENTRIES || - entity === EntityType.BILLING_ITEMS || - entity === EntityType.PROJECTS || - entity === EntityType.CONTRACTS; - if (!isIncremental && !hasDateFilter) { + if (!isIncremental && !hasAppliedFilters) { entityLogger.phase(SyncPhase.DELETING, 'Checking for records to soft delete'); syncProgressTracker.updateProgress(trackingId, { phase: 'deleting' }); @@ -367,8 +365,8 @@ export class EntitySyncService { entityLogger.warn('Soft delete failed, continuing sync', {}, err); // Don't throw - soft delete failure shouldn't fail the entire sync } - } else if (!isIncremental && hasDateFilter) { - entityLogger.info('Skipping soft-delete for date-filtered sync (would delete records outside sync window)'); + } else if (!isIncremental && hasAppliedFilters) { + entityLogger.info('Skipping soft-delete because filters were applied (would delete records outside filter criteria)'); } // Calculate added vs updated (simplified - actual count would require tracking)