258 lines
8.4 KiB
JavaScript
258 lines
8.4 KiB
JavaScript
const EnhancedCKGMigrationService = require('./enhanced-ckg-migration-service');
|
|
const ComprehensiveNamespaceMigrationService = require('./comprehensive-namespace-migration');
|
|
|
|
/**
|
|
* Automatic CKG Migration Service
|
|
* Handles automatic migration of templates and features to Neo4j CKG
|
|
* Generates permutations, combinations, and tech stack mappings
|
|
*/
|
|
class AutoCKGMigrationService {
|
|
constructor() {
|
|
this.migrationService = new EnhancedCKGMigrationService();
|
|
this.comprehensiveMigrationService = new ComprehensiveNamespaceMigrationService();
|
|
this.isRunning = false;
|
|
this.lastMigrationTime = null;
|
|
}
|
|
|
|
/**
|
|
* Initialize auto-migration on service startup
|
|
*/
|
|
async initialize() {
|
|
console.log('🚀 Initializing Auto CKG Migration Service...');
|
|
|
|
try {
|
|
// Run initial migration on startup
|
|
await this.runStartupMigration();
|
|
|
|
// Set up periodic migration checks
|
|
this.setupPeriodicMigration();
|
|
|
|
console.log('✅ Auto CKG Migration Service initialized');
|
|
} catch (error) {
|
|
console.error('❌ Failed to initialize Auto CKG Migration Service:', error.message);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Run migration on service startup
|
|
*/
|
|
async runStartupMigration() {
|
|
console.log('🔄 Running startup CKG migration...');
|
|
|
|
try {
|
|
// Step 1: Run comprehensive namespace migration for all templates
|
|
console.log('🚀 Starting comprehensive namespace migration...');
|
|
const comprehensiveResult = await this.comprehensiveMigrationService.runComprehensiveMigration();
|
|
|
|
if (comprehensiveResult.success) {
|
|
console.log('✅ Comprehensive namespace migration completed successfully');
|
|
console.log(`📊 Migration stats:`, comprehensiveResult.stats);
|
|
} else {
|
|
console.error('❌ Comprehensive namespace migration failed:', comprehensiveResult.error);
|
|
// Continue with legacy migration as fallback
|
|
await this.runLegacyMigration();
|
|
}
|
|
|
|
this.lastMigrationTime = new Date();
|
|
console.log('✅ Startup CKG migration completed');
|
|
|
|
} catch (error) {
|
|
console.error('❌ Startup CKG migration failed:', error.message);
|
|
console.error('🔍 Error details:', error.stack);
|
|
// Don't throw error, continue with service startup
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Run legacy migration as fallback
|
|
*/
|
|
async runLegacyMigration() {
|
|
console.log('🔄 Running legacy CKG migration as fallback...');
|
|
|
|
try {
|
|
// Check existing templates and their CKG status
|
|
console.log('🔍 Checking existing templates for CKG data...');
|
|
const templates = await this.migrationService.getAllTemplatesWithFeatures();
|
|
console.log(`📊 Found ${templates.length} templates to check`);
|
|
|
|
let processedCount = 0;
|
|
let skippedCount = 0;
|
|
|
|
for (const template of templates) {
|
|
const hasExistingCKG = await this.migrationService.checkTemplateHasCKGData(template.id);
|
|
if (hasExistingCKG) {
|
|
console.log(`⏭️ Template ${template.id} already has CKG data, skipping...`);
|
|
skippedCount++;
|
|
} else {
|
|
console.log(`🔄 Template ${template.id} needs CKG migration...`);
|
|
await this.migrationService.migrateTemplateToEnhancedCKG(template);
|
|
processedCount++;
|
|
}
|
|
}
|
|
|
|
console.log(`✅ Legacy migration completed: ${processedCount} processed, ${skippedCount} skipped`);
|
|
|
|
} catch (error) {
|
|
console.error('❌ Legacy migration failed:', error.message);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set up periodic migration checks
|
|
*/
|
|
setupPeriodicMigration() {
|
|
// DISABLED: Periodic migration was causing infinite loops
|
|
// Check for new data every 10 minutes
|
|
// setInterval(async () => {
|
|
// await this.checkAndMigrateNewData();
|
|
// }, 10 * 60 * 1000); // 10 minutes
|
|
|
|
console.log('⏰ Periodic CKG migration checks DISABLED to prevent infinite loops');
|
|
}
|
|
|
|
/**
|
|
* Check for new data and migrate if needed
|
|
*/
|
|
async checkAndMigrateNewData() {
|
|
if (this.isRunning) {
|
|
console.log('⏳ CKG migration already in progress, skipping...');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
this.isRunning = true;
|
|
|
|
// Check if there are new templates or features since last migration
|
|
const hasNewData = await this.checkForNewData();
|
|
|
|
if (hasNewData) {
|
|
console.log('🔄 New data detected, running CKG migration...');
|
|
const stats = await this.migrationService.migrateAllTemplates();
|
|
this.lastMigrationTime = new Date();
|
|
console.log('✅ Auto CKG migration completed');
|
|
console.log(`📊 Migration stats: ${JSON.stringify(stats)}`);
|
|
} else {
|
|
console.log('📊 No new data detected, skipping CKG migration');
|
|
}
|
|
} catch (error) {
|
|
console.error('❌ Auto CKG migration failed:', error.message);
|
|
console.error('🔍 Error details:', error.stack);
|
|
} finally {
|
|
this.isRunning = false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if there's new data since last migration
|
|
*/
|
|
async checkForNewData() {
|
|
try {
|
|
const database = require('../config/database');
|
|
|
|
// Check for new templates
|
|
const templatesQuery = this.lastMigrationTime
|
|
? 'SELECT COUNT(*) as count FROM templates WHERE created_at > $1 OR updated_at > $1'
|
|
: 'SELECT COUNT(*) as count FROM templates';
|
|
|
|
const templatesParams = this.lastMigrationTime ? [this.lastMigrationTime] : [];
|
|
const templatesResult = await database.query(templatesQuery, templatesParams);
|
|
|
|
// Check for new features
|
|
const featuresQuery = this.lastMigrationTime
|
|
? 'SELECT COUNT(*) as count FROM template_features WHERE created_at > $1 OR updated_at > $1'
|
|
: 'SELECT COUNT(*) as count FROM template_features';
|
|
|
|
const featuresParams = this.lastMigrationTime ? [this.lastMigrationTime] : [];
|
|
const featuresResult = await database.query(featuresQuery, featuresParams);
|
|
|
|
const newTemplates = parseInt(templatesResult.rows[0].count) || 0;
|
|
const newFeatures = parseInt(featuresResult.rows[0].count) || 0;
|
|
|
|
if (newTemplates > 0 || newFeatures > 0) {
|
|
console.log(`📊 Found ${newTemplates} new templates and ${newFeatures} new features`);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
} catch (error) {
|
|
console.error('❌ Error checking for new data:', error.message);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Trigger immediate migration (for webhook/API calls)
|
|
*/
|
|
async triggerMigration() {
|
|
console.log('🔄 Manual CKG migration triggered...');
|
|
|
|
if (this.isRunning) {
|
|
console.log('⏳ Migration already in progress, queuing...');
|
|
return { success: false, message: 'Migration already in progress' };
|
|
}
|
|
|
|
try {
|
|
this.isRunning = true;
|
|
const stats = await this.migrationService.migrateAllTemplates();
|
|
this.lastMigrationTime = new Date();
|
|
|
|
console.log('✅ Manual CKG migration completed');
|
|
console.log(`📊 Migration stats: ${JSON.stringify(stats)}`);
|
|
return { success: true, message: 'Migration completed successfully', stats: stats };
|
|
} catch (error) {
|
|
console.error('❌ Manual CKG migration failed:', error.message);
|
|
console.error('🔍 Error details:', error.stack);
|
|
return { success: false, message: error.message };
|
|
} finally {
|
|
this.isRunning = false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Migrate specific template to CKG
|
|
*/
|
|
async migrateTemplate(templateId) {
|
|
console.log(`🔄 Migrating template ${templateId} to CKG...`);
|
|
|
|
try {
|
|
await this.migrationService.migrateTemplateToCKG(templateId);
|
|
console.log(`✅ Template ${templateId} migrated to CKG`);
|
|
return { success: true, message: 'Template migrated successfully' };
|
|
} catch (error) {
|
|
console.error(`❌ Failed to migrate template ${templateId}:`, error.message);
|
|
return { success: false, message: error.message };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get migration status
|
|
*/
|
|
async getStatus() {
|
|
try {
|
|
const stats = await this.migrationService.getMigrationStats();
|
|
return {
|
|
success: true,
|
|
data: {
|
|
lastMigration: this.lastMigrationTime,
|
|
isRunning: this.isRunning,
|
|
stats: stats
|
|
}
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
success: false,
|
|
error: error.message
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Close connections
|
|
*/
|
|
async close() {
|
|
await this.migrationService.close();
|
|
}
|
|
}
|
|
|
|
module.exports = AutoCKGMigrationService;
|