feat: Veeam RPO analysis, comparison, ticket analysis + company teams table
- Add Veeam RPO analysis page (/veeam-analysis) and comparison page (/veeam-comparison) - Add API routes: /api/veeam/rpo-analyze, rpo-comparison, rpo-offline-log, ticket-analysis - Add veeam-rpo-service.ts enhancements (RPO logic, offline detection, comparison) - Add veeam-analysis-state.ts and rmm-device-resolver.ts services - Add migrations 065-068: company_teams, veeam_rpo_offline_log, rpo_comparison_tables, veeam_ticket_analysis - Add backup-status page updates and nav links for new Veeam pages - Add scripts: deactivate-cis-for-inactive-companies, workstation category updates - Add docs: mimecast-api-guide, veeam-backup-alerting-recommendation, workstation-backup-overview, ticket-analyzer-prompt - Minor: webhook-service, entity-sync, entity-mapper, sync-helpers, sync.ts, middleware.ts updates
This commit is contained in:
parent
07067bef19
commit
ea3471d38d
36 changed files with 5604 additions and 217 deletions
|
|
@ -83,6 +83,9 @@ export function mapAutotaskToDatabase(
|
|||
case EntityType.TAGS:
|
||||
mapped = mapTag(data);
|
||||
break;
|
||||
case EntityType.COMPANY_TEAMS:
|
||||
mapped = mapCompanyTeam(data);
|
||||
break;
|
||||
default:
|
||||
// Fallback: auto-convert camelCase to snake_case
|
||||
mapped = {};
|
||||
|
|
@ -826,6 +829,19 @@ function mapPicklist(data: any): Record<string, any> {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Map CompanyTeam entity
|
||||
*/
|
||||
function mapCompanyTeam(data: any): Record<string, any> {
|
||||
return {
|
||||
id: data.id,
|
||||
company_id: data.companyID,
|
||||
resource_id: data.resourceID,
|
||||
is_associated_as_comanaged: data.isAssociatedAsComanaged || false,
|
||||
is_deleted: false,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch map multiple entities
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ export function getAllEntitiesInOrder(): EntityType[] {
|
|||
EntityType.TIME_ENTRIES,
|
||||
EntityType.TAG_GROUPS,
|
||||
EntityType.TAGS,
|
||||
EntityType.COMPANY_TEAMS,
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -130,6 +131,7 @@ export function getAutotaskEntityName(entity: EntityType): string {
|
|||
[EntityType.PROJECT_PHASES]: 'Phases',
|
||||
[EntityType.COMPANY_CATEGORIES]: 'CompanyCategories',
|
||||
[EntityType.COMPANY_TYPES]: 'CompanyTypes',
|
||||
[EntityType.COMPANY_TEAMS]: 'CompanyTeams',
|
||||
};
|
||||
|
||||
return mapping[entity] || entity;
|
||||
|
|
@ -185,6 +187,7 @@ export function getLastModifiedField(entity: EntityType): string {
|
|||
[EntityType.PROJECT_PHASES]: 'lastActivityDateTime',
|
||||
[EntityType.COMPANY_CATEGORIES]: 'lastModifiedDate',
|
||||
[EntityType.COMPANY_TYPES]: 'lastModifiedDate',
|
||||
[EntityType.COMPANY_TEAMS]: 'lastModifiedDate', // No date field; incremental not supported
|
||||
};
|
||||
|
||||
return mapping[entity] || 'lastModifiedDate';
|
||||
|
|
@ -222,6 +225,7 @@ export function getActiveField(entity: EntityType): string | null {
|
|||
[EntityType.PROJECT_PHASES]: null, // No active field on phases
|
||||
[EntityType.COMPANY_CATEGORIES]: 'isActive',
|
||||
[EntityType.COMPANY_TYPES]: 'isActive',
|
||||
[EntityType.COMPANY_TEAMS]: null,
|
||||
};
|
||||
|
||||
return mapping[entity] || null;
|
||||
|
|
@ -319,6 +323,7 @@ export function buildDateRangeFilter(
|
|||
[EntityType.PROJECT_PHASES]: null,
|
||||
[EntityType.COMPANY_CATEGORIES]: null,
|
||||
[EntityType.COMPANY_TYPES]: null,
|
||||
[EntityType.COMPANY_TEAMS]: null,
|
||||
};
|
||||
|
||||
const dateField = dateFieldMapping[entity];
|
||||
|
|
@ -529,6 +534,7 @@ export function getEntityDisplayName(entity: EntityType): string {
|
|||
[EntityType.PROJECT_PHASES]: 'Project Phases',
|
||||
[EntityType.COMPANY_CATEGORIES]: 'Company Categories',
|
||||
[EntityType.COMPANY_TYPES]: 'Company Types',
|
||||
[EntityType.COMPANY_TEAMS]: 'Company Teams',
|
||||
};
|
||||
|
||||
return mapping[entity] || entity;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue