Spaces:
Paused
Paused
| /** | |
| * 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); | |