fix: correct Statuses and Work Types sync to use picklist API

Problem:
- syncStatuses() and syncWorkTypes() were trying to query /Statuses/query
  and /WorkTypes/query endpoints which don't exist in Autotask API
- This caused 404 errors: 'File or directory not found'
- These are picklist values, not queryable entities

Solution:
- Changed syncStatuses() to use getPicklistValues('Tickets', 'status')
- Changed syncWorkTypes() to use getPicklistValues('TimeEntries', 'workType')
- Now follows same pattern as syncIssueTypes() and syncSubIssueTypes()
- Uses proper picklist API endpoint: /entity/entityInformation/fields

This fixes today's sync failures for statuses and work_types entities.
This commit is contained in:
root 2026-01-23 17:02:09 -05:00
parent a14a03140b
commit 4f99de364a

View file

@ -628,10 +628,48 @@ export class EntitySyncService {
}
/**
* Sync Statuses (Picklist)
* Sync Statuses (Picklist from Ticket field)
*/
async syncStatuses(isIncremental: boolean = false): Promise<EntitySyncStats> {
return await this.syncEntity(EntityType.STATUSES, isIncremental);
const picklistLogger = this.logger.child({ entityType: EntityType.STATUSES, syncType: 'picklist' });
const syncStartTime = picklistLogger.start('Picklist sync');
try {
// Get status picklist values from Tickets entity
const picklistValues = await this.autotaskClient.getPicklistValues('Tickets', 'status');
// Convert picklist to database format
const records = Object.entries(picklistValues).map(([value, label]) => ({
value: parseInt(value),
label: label,
is_active: true,
sort_order: parseInt(value),
synced_at: new Date(),
}));
picklistLogger.info('Found picklist values', { recordCount: records.length });
// Upsert to database
const tableName = getTableName(EntityType.STATUSES);
const upsertedCount = await postgresClient.bulkUpsert(tableName, records, ['value']);
const stats: EntitySyncStats = {
recordsAdded: upsertedCount,
recordsUpdated: 0,
recordsDeleted: 0,
};
picklistLogger.complete('Picklist sync', syncStartTime, {
recordsAdded: stats.recordsAdded,
recordsUpdated: stats.recordsUpdated,
});
return stats;
} catch (error) {
const err = error instanceof Error ? error : new Error(String(error));
picklistLogger.fail('Picklist sync', syncStartTime, err);
throw error;
}
}
/**
@ -742,10 +780,48 @@ export class EntitySyncService {
}
/**
* Sync Work Types (Picklist)
* Sync Work Types (Picklist from TimeEntry field)
*/
async syncWorkTypes(isIncremental: boolean = false): Promise<EntitySyncStats> {
return await this.syncEntity(EntityType.WORK_TYPES, isIncremental);
const picklistLogger = this.logger.child({ entityType: EntityType.WORK_TYPES, syncType: 'picklist' });
const syncStartTime = picklistLogger.start('Picklist sync');
try {
// Get work type picklist values from TimeEntries entity
const picklistValues = await this.autotaskClient.getPicklistValues('TimeEntries', 'workType');
// Convert picklist to database format
const records = Object.entries(picklistValues).map(([value, label]) => ({
value: parseInt(value),
label: label,
is_active: true,
sort_order: parseInt(value),
synced_at: new Date(),
}));
picklistLogger.info('Found picklist values', { recordCount: records.length });
// Upsert to database
const tableName = getTableName(EntityType.WORK_TYPES);
const upsertedCount = await postgresClient.bulkUpsert(tableName, records, ['value']);
const stats: EntitySyncStats = {
recordsAdded: upsertedCount,
recordsUpdated: 0,
recordsDeleted: 0,
};
picklistLogger.complete('Picklist sync', syncStartTime, {
recordsAdded: stats.recordsAdded,
recordsUpdated: stats.recordsUpdated,
});
return stats;
} catch (error) {
const err = error instanceof Error ? error : new Error(String(error));
picklistLogger.fail('Picklist sync', syncStartTime, err);
throw error;
}
}
/**