wulf-pulse/dev/test-full-sync.ts
root 6eee14f8af Add comprehensive admin features and multi-system integration
- Add admin dashboard with sync controls and data browser
- Implement RMM, Auvik, and Addigy organization mappings
- Add chunked ticket sync with progress tracking
- Implement entity sync service with rate limiting
- Add analytics engine and performance optimizer
- Create data browser for all PSA entities
- Add navigation components and UI improvements
- Implement background processing and sync services
- Add comprehensive documentation and migration scripts
- Update configuration items with multi-system support
- Enhance contact management and purchase history
- Add issue type assignment and LLM analyzer
- Improve error handling and logging utilities
2025-11-19 14:18:16 -05:00

200 lines
7.8 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Test script for full sync with Autotask
* Run with: npx tsx dev/test-full-sync.ts
*
* This script tests the full sync functionality with a small dataset
* by limiting the number of records fetched from Autotask.
*/
import dotenv from 'dotenv';
import path from 'path';
// Load environment variables from .env.local FIRST
dotenv.config({ path: path.resolve(__dirname, '../.env.local') });
import { AutotaskClient } from '../lib/services/autotask-client';
import { createSyncService } from '../lib/services/sync-service';
import { EntityType } from '../lib/types/sync';
import postgresClient from '../lib/services/postgres-client';
async function testFullSync() {
console.log('🔍 Testing Full Sync with Autotask\n');
// Check environment variables
console.log('Environment Configuration:');
console.log(' AUTOTASK_API_URL:', process.env.AUTOTASK_API_URL);
console.log(' AUTOTASK_USERNAME:', process.env.AUTOTASK_USERNAME ? '[SET]' : '[NOT SET]');
console.log(' AUTOTASK_SECRET:', process.env.AUTOTASK_SECRET ? '[SET]' : '[NOT SET]');
console.log(' AUTOTASK_API_INTEGRATION_CODE:', process.env.AUTOTASK_API_INTEGRATION_CODE ? '[SET]' : '[NOT SET]');
console.log(' POSTGRES_HOST:', process.env.POSTGRES_HOST);
console.log(' POSTGRES_DB:', process.env.POSTGRES_DB);
console.log();
// Validate required environment variables
if (!process.env.AUTOTASK_API_URL || !process.env.AUTOTASK_USERNAME ||
!process.env.AUTOTASK_SECRET || !process.env.AUTOTASK_API_INTEGRATION_CODE) {
console.error('❌ Missing required Autotask environment variables');
console.error('Please ensure .env.local contains:');
console.error(' - AUTOTASK_API_URL');
console.error(' - AUTOTASK_USERNAME');
console.error(' - AUTOTASK_SECRET');
console.error(' - AUTOTASK_API_INTEGRATION_CODE');
process.exit(1);
}
try {
// Test 1: Database connection
console.log('Test 1: Verify database connection');
const dbConnected = await postgresClient.testConnection();
if (!dbConnected) {
console.error('❌ Database connection failed');
process.exit(1);
}
console.log('✅ Database connection successful\n');
// Test 2: Create Autotask client
console.log('Test 2: Initialize Autotask client');
const autotaskClient = new AutotaskClient({
apiUrl: process.env.AUTOTASK_API_URL!,
username: process.env.AUTOTASK_USERNAME!,
password: process.env.AUTOTASK_SECRET!,
apiIntegrationCode: process.env.AUTOTASK_API_INTEGRATION_CODE!,
});
console.log('✅ Autotask client initialized\n');
// Test 3: Test Autotask API connection with a simple query
console.log('Test 3: Test Autotask API connection');
try {
// Try to fetch a small number of companies to test the connection
const testCompanies = await autotaskClient.queryEntity('Companies', {
filter: [{ field: 'isActive', op: 'eq', value: true }],
maxRecords: 5,
});
console.log(`✅ Autotask API connection successful (fetched ${testCompanies.length} test companies)\n`);
} catch (error) {
console.error('❌ Autotask API connection failed:', error);
console.error('\nPlease verify:');
console.error(' 1. API credentials are correct');
console.error(' 2. API integration code is valid');
console.error(' 3. Network connectivity to Autotask API');
process.exit(1);
}
// Test 4: Create sync service
console.log('Test 4: Initialize sync service');
const syncService = createSyncService(autotaskClient);
console.log('✅ Sync service initialized\n');
// Test 5: Sync a single entity (Companies) as a small test
console.log('Test 5: Sync Companies entity (limited dataset)');
console.log('Note: This will sync only active companies to limit data volume\n');
const startTime = Date.now();
try {
const result = await syncService.syncEntities(
[EntityType.COMPANIES],
undefined,
'test-script'
);
const duration = Date.now() - startTime;
console.log('\n=== SYNC RESULTS ===');
console.log(`Sync ID: ${result.syncId}`);
console.log(`Status: ${result.status}`);
console.log(`Duration: ${duration}ms`);
console.log(`\nRecords:`);
console.log(` Added: ${result.totalRecordsAdded}`);
console.log(` Updated: ${result.totalRecordsUpdated}`);
console.log(` Deleted: ${result.totalRecordsDeleted}`);
if (result.errors && result.errors.length > 0) {
console.log(`\nErrors:`);
result.errors.forEach(error => console.log(` - ${error}`));
}
console.log('\n=== ENTITY DETAILS ===');
result.entities.forEach(entity => {
const status = entity.success ? '✅' : '❌';
console.log(`${status} ${entity.entityType}:`);
console.log(` Added: ${entity.recordsAdded}, Updated: ${entity.recordsUpdated}, Deleted: ${entity.recordsDeleted}`);
console.log(` Duration: ${entity.duration}ms`);
if (entity.error) {
console.log(` Error: ${entity.error}`);
}
});
if (result.status === 'completed') {
console.log('\n✅ Companies sync completed successfully!');
} else {
console.log('\n⚠ Companies sync completed with errors');
}
} catch (error) {
console.error('\n❌ Sync failed:', error);
throw error;
}
// Test 6: Verify data in database
console.log('\nTest 6: Verify synced data in database');
const companyCount = await postgresClient.count('companies', { is_deleted: false });
console.log(`✅ Found ${companyCount} companies in database\n`);
// Test 7: Check sync history
console.log('Test 7: Check sync history');
const syncHistory = await syncService.getSyncHistory(5, EntityType.COMPANIES);
console.log(`✅ Found ${syncHistory.length} sync history records`);
if (syncHistory.length > 0) {
const latest = syncHistory[0];
console.log(` Latest sync:`);
console.log(` Entity: ${latest.entity_type}`);
console.log(` Status: ${latest.status}`);
console.log(` Started: ${latest.started_at}`);
console.log(` Completed: ${latest.completed_at}`);
console.log(` Records: +${latest.records_added} ~${latest.records_updated} -${latest.records_deleted}`);
}
console.log();
// Optional: Test 8: Sync multiple entities (commented out to keep test small)
/*
console.log('Test 8: Sync multiple entities');
const multiResult = await syncService.syncEntities(
[EntityType.COMPANIES, EntityType.RESOURCES, EntityType.STATUSES],
undefined,
'test-script-multi'
);
console.log(`✅ Multi-entity sync completed: ${multiResult.status}`);
console.log(` Total records: +${multiResult.totalRecordsAdded} ~${multiResult.totalRecordsUpdated} -${multiResult.totalRecordsDeleted}\n`);
*/
console.log('🎉 All sync tests passed successfully!');
console.log('\n=== SUMMARY ===');
console.log('✅ Database connection working');
console.log('✅ Autotask API connection working');
console.log('✅ Sync service operational');
console.log('✅ Entity sync working');
console.log('✅ Data persisted to database');
console.log('✅ Sync history tracking working');
} catch (error) {
console.error('\n❌ Test failed with error:', error);
if (error instanceof Error) {
console.error('Stack trace:', error.stack);
}
process.exit(1);
} finally {
// Close database connection
await postgresClient.close();
console.log('\n🔌 Database connection closed');
}
}
// Run the tests
testFullSync()
.then(() => {
console.log('\n✅ Test script completed successfully');
process.exit(0);
})
.catch((error) => {
console.error('\n❌ Test script failed:', error);
process.exit(1);
});