Kraft102's picture
Deploy from GitHub Actions 2025-12-15_23-41-14
bbf18eb verified
#!/usr/bin/env node
/**
* Neo4j Auto-Sync Runner
*
* Runs as a standalone service for automated Neo4j synchronization.
*
* Usage:
* npx tsx apps/backend/src/scripts/neo4j-auto-sync.ts [command]
*
* Commands:
* start - Start scheduler (default)
* sync - Run single sync now
* full - Run full sync (ignores checkpoint)
* status - Show sync status
* help - Show this help
*
* Environment Variables:
* NEO4J_LOCAL_URI - Local Neo4j URI (default: bolt://localhost:7687)
* NEO4J_LOCAL_USER - Local Neo4j user (default: neo4j)
* NEO4J_LOCAL_PASSWORD - Local Neo4j password (default: password)
* NEO4J_URI - Cloud Neo4j URI
* NEO4J_USER - Cloud Neo4j user
* NEO4J_PASSWORD - Cloud Neo4j password
* NEO4J_SYNC_SCHEDULE - Cron schedule (default: "0 *\/6 * * *" = every 6 hours)
*/
import dotenv from 'dotenv';
import path from 'path';
import fs from 'fs';
import { Neo4jAutoSync } from '../services/Neo4jAutoSync.js';
// Load environment
dotenv.config({ path: path.resolve(process.cwd(), '.env.production') });
dotenv.config({ path: path.resolve(process.cwd(), '.env') });
const STATUS_FILE = path.join(process.cwd(), '.neo4j-sync-status.json');
async function main() {
const command = process.argv[2] || 'start';
console.log('═'.repeat(60));
console.log('🔄 Neo4j Auto-Sync Service');
console.log('═'.repeat(60));
console.log('');
switch (command) {
case 'start':
await startScheduler();
break;
case 'sync':
await runSync(false);
break;
case 'full':
await runSync(true);
break;
case 'status':
showStatus();
break;
case 'help':
default:
showHelp();
break;
}
}
async function startScheduler() {
const syncService = new Neo4jAutoSync();
const schedule = process.env.NEO4J_SYNC_SCHEDULE || '0 */6 * * *';
console.log('Configuration:');
console.log(` Local: ${process.env.NEO4J_LOCAL_URI || 'bolt://localhost:7687'}`);
console.log(` Cloud: ${process.env.NEO4J_URI || '(not configured)'}`);
console.log(` Schedule: ${schedule}`);
console.log('');
// Run initial sync
console.log('Running initial sync...\n');
await syncService.sync();
// Start scheduler
syncService.startScheduler();
console.log('\n✅ Auto-sync service running. Press Ctrl+C to stop.\n');
// Keep process alive
process.on('SIGINT', () => {
console.log('\n⏹️ Shutting down...');
syncService.stopScheduler();
process.exit(0);
});
// Keep alive
setInterval(() => {
// Heartbeat
}, 60000);
}
async function runSync(forceFullSync: boolean) {
const syncService = new Neo4jAutoSync();
console.log(`Running ${forceFullSync ? 'FULL' : 'incremental'} sync...\n`);
const status = await syncService.sync(forceFullSync);
console.log('\n' + '═'.repeat(60));
console.log('Sync Result:');
console.log(` Status: ${status.status}`);
console.log(` Type: ${status.lastSyncType}`);
console.log(` Nodes: ${status.nodesSync}`);
console.log(` Relationships: ${status.relationshipsSync}`);
console.log(` Duration: ${status.lastSyncDuration}ms`);
if (status.error) {
console.log(` Error: ${status.error}`);
}
console.log('═'.repeat(60));
}
function showStatus() {
if (fs.existsSync(STATUS_FILE)) {
const status = JSON.parse(fs.readFileSync(STATUS_FILE, 'utf-8'));
console.log('Current Sync Status:');
console.log('');
console.log(` Status: ${status.status}`);
console.log(` Last Sync: ${status.lastSyncTime || 'Never'}`);
console.log(` Sync Type: ${status.lastSyncType || 'N/A'}`);
console.log(` Nodes Synced: ${status.nodesSync || 0}`);
console.log(` Rels Synced: ${status.relationshipsSync || 0}`);
console.log(` Duration: ${status.lastSyncDuration ? status.lastSyncDuration + 'ms' : 'N/A'}`);
console.log(` Next Scheduled: ${status.nextScheduledSync || 'N/A'}`);
if (status.error) {
console.log(` Error: ${status.error}`);
}
} else {
console.log('No sync status found. Run a sync first.');
}
}
function showHelp() {
console.log(`
Usage: npx tsx apps/backend/src/scripts/neo4j-auto-sync.ts [command]
Commands:
start Start the scheduler service (runs continuously)
sync Run a single sync (incremental if checkpoint exists)
full Run a full sync (ignores checkpoint, replaces all data)
status Show current sync status
help Show this help message
Environment Variables:
NEO4J_LOCAL_URI Local Neo4j URI (default: bolt://localhost:7687)
NEO4J_LOCAL_USER Local Neo4j user (default: neo4j)
NEO4J_LOCAL_PASSWORD Local Neo4j password (default: password)
NEO4J_URI Cloud Neo4j URI (required)
NEO4J_USER Cloud Neo4j user (default: neo4j)
NEO4J_PASSWORD Cloud Neo4j password (required)
NEO4J_SYNC_SCHEDULE Cron schedule (default: 0 */6 * * * = every 6 hours)
Schedule Examples:
0 */6 * * * Every 6 hours
0 */2 * * * Every 2 hours
0 0 * * * Daily at midnight
*/30 * * * * Every 30 minutes
0 9,18 * * * At 9am and 6pm
Examples:
# Start auto-sync service (runs continuously)
npx tsx apps/backend/src/scripts/neo4j-auto-sync.ts start
# Run single sync
npx tsx apps/backend/src/scripts/neo4j-auto-sync.ts sync
# Force full sync
npx tsx apps/backend/src/scripts/neo4j-auto-sync.ts full
# Check status
npx tsx apps/backend/src/scripts/neo4j-auto-sync.ts status
`);
}
main().catch(console.error);