feat: Autotask webhook integration, TicketNotes, Datto RMM, workflow engine, Veeam agents/alarms, AI triage, misc improvements

This commit is contained in:
lorentz 2026-02-20 10:28:15 -05:00
parent 347cf4e298
commit d7c3dc7168
74 changed files with 37844 additions and 322 deletions

View file

@ -57,6 +57,9 @@ export function mapAutotaskToDatabase(
case EntityType.TIME_ENTRIES:
mapped = mapTimeEntry(data);
break;
case EntityType.TICKET_NOTES:
mapped = mapTicketNote(data);
break;
case EntityType.STATUSES:
case EntityType.ISSUE_TYPES:
case EntityType.SUB_ISSUE_TYPES:
@ -201,6 +204,26 @@ function mapTicket(data: any): Record<string, any> {
};
}
/**
* Map TicketNote entity
*/
function mapTicketNote(data: any): Record<string, any> {
return {
id: data.id,
ticket_id: data.ticketID,
title: data.title,
description: data.description,
note_type: data.noteType,
publish: data.publish,
creator_resource_id: data.creatorResourceID,
creator_type: data.creatorType,
last_activity_date: data.lastActivityDate,
create_date_time: data.createDateTime,
synced_at: data.synced_at,
is_deleted: data.is_deleted || false,
};
}
/**
* Map Task entity
*/

View file

@ -56,6 +56,9 @@ export function getAllEntitiesInOrder(): EntityType[] {
EntityType.ISSUE_TYPES,
EntityType.SUB_ISSUE_TYPES,
EntityType.WORK_TYPES,
EntityType.QUEUES,
EntityType.PRIORITIES,
EntityType.TICKET_CATEGORIES,
EntityType.CONTACTS,
EntityType.PROJECTS,
EntityType.TICKETS,
@ -92,11 +95,15 @@ export function getAutotaskEntityName(entity: EntityType): string {
[EntityType.ISSUE_TYPES]: 'IssueTypes',
[EntityType.SUB_ISSUE_TYPES]: 'SubIssueTypes',
[EntityType.WORK_TYPES]: 'WorkTypes',
[EntityType.QUEUES]: 'Queues',
[EntityType.PRIORITIES]: 'Priorities',
[EntityType.TICKET_CATEGORIES]: 'TicketCategories',
[EntityType.BILLING_ITEMS]: 'BillingItems',
[EntityType.CONFIGURATION_ITEMS]: 'ConfigurationItems',
[EntityType.CONTACTS]: 'Contacts',
[EntityType.CONTRACTS]: 'Contracts',
[EntityType.TIME_ENTRIES]: 'TimeEntries',
[EntityType.TICKET_NOTES]: 'TicketNotes',
};
return mapping[entity] || entity;
@ -113,6 +120,9 @@ export function isPicklistEntity(entity: EntityType): boolean {
EntityType.ISSUE_TYPES,
EntityType.SUB_ISSUE_TYPES,
EntityType.WORK_TYPES,
EntityType.QUEUES,
EntityType.PRIORITIES,
EntityType.TICKET_CATEGORIES,
].includes(entity);
}
@ -133,10 +143,14 @@ export function getLastModifiedField(entity: EntityType): string {
[EntityType.CONTRACTS]: 'lastModifiedDateTime',
[EntityType.BILLING_ITEMS]: 'itemDate',
[EntityType.TIME_ENTRIES]: 'dateWorked',
[EntityType.TICKET_NOTES]: 'lastActivityDate',
[EntityType.STATUSES]: 'lastModifiedDate',
[EntityType.ISSUE_TYPES]: 'lastModifiedDate',
[EntityType.SUB_ISSUE_TYPES]: 'lastModifiedDate',
[EntityType.WORK_TYPES]: 'lastModifiedDate',
[EntityType.QUEUES]: 'lastModifiedDate',
[EntityType.PRIORITIES]: 'lastModifiedDate',
[EntityType.TICKET_CATEGORIES]: 'lastModifiedDate',
};
return mapping[entity] || 'lastModifiedDate';
@ -159,10 +173,14 @@ export function getActiveField(entity: EntityType): string | null {
[EntityType.CONTRACTS]: null, // Use status field instead
[EntityType.BILLING_ITEMS]: null,
[EntityType.TIME_ENTRIES]: null, // Time entries don't have active status
[EntityType.TICKET_NOTES]: null, // Ticket notes don't have active status
[EntityType.STATUSES]: 'isActive',
[EntityType.ISSUE_TYPES]: 'isActive',
[EntityType.SUB_ISSUE_TYPES]: 'isActive',
[EntityType.WORK_TYPES]: 'isActive',
[EntityType.QUEUES]: 'isActive',
[EntityType.PRIORITIES]: 'isActive',
[EntityType.TICKET_CATEGORIES]: 'isActive',
};
return mapping[entity] || null;
@ -245,10 +263,14 @@ export function buildDateRangeFilter(
[EntityType.RESOURCES]: null,
[EntityType.CONTACTS]: null,
[EntityType.CONFIGURATION_ITEMS]: null,
[EntityType.TICKET_NOTES]: null,
[EntityType.STATUSES]: null,
[EntityType.ISSUE_TYPES]: null,
[EntityType.SUB_ISSUE_TYPES]: null,
[EntityType.WORK_TYPES]: null,
[EntityType.QUEUES]: null,
[EntityType.PRIORITIES]: null,
[EntityType.TICKET_CATEGORIES]: null,
};
const dateField = dateFieldMapping[entity];
@ -427,11 +449,15 @@ export function getEntityDisplayName(entity: EntityType): string {
[EntityType.ISSUE_TYPES]: 'Issue Types',
[EntityType.SUB_ISSUE_TYPES]: 'Sub-Issue Types',
[EntityType.WORK_TYPES]: 'Work Types',
[EntityType.QUEUES]: 'Queues',
[EntityType.PRIORITIES]: 'Priorities',
[EntityType.TICKET_CATEGORIES]: 'Ticket Categories',
[EntityType.BILLING_ITEMS]: 'Billing Items',
[EntityType.CONFIGURATION_ITEMS]: 'Configuration Items',
[EntityType.CONTACTS]: 'Contacts',
[EntityType.CONTRACTS]: 'Contracts',
[EntityType.TIME_ENTRIES]: 'Time Entries',
[EntityType.TICKET_NOTES]: 'Ticket Notes',
};
return mapping[entity] || entity;