#!/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);