201 lines
7.8 KiB
TypeScript
201 lines
7.8 KiB
TypeScript
|
|
/**
|
|||
|
|
* 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);
|
|||
|
|
});
|