const mongoose = require('mongoose'); const fs = require('fs').promises; const path = require('path'); const Submission = require('./models/Submission'); const SourceText = require('./models/SourceText'); const User = require('./models/User'); const MONGODB_URI = 'mongodb+srv://nothingyu:wSg3lbO1PkHiRMq9@sandbox.ecysggv.mongodb.net/?retryWrites=true&w=majority&appName=sandbox'; class BackupSystem { constructor() { this.backupDir = path.join(__dirname, 'backups'); this.ensureBackupDir(); } async ensureBackupDir() { try { await fs.mkdir(this.backupDir, { recursive: true }); } catch (error) { console.error('Failed to create backup directory:', error); } } async createBackup() { try { console.log('🔄 Creating database backup...'); await mongoose.connect(MONGODB_URI); const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); const backupData = { timestamp, collections: {} }; // Backup Users console.log('📋 Backing up users...'); const users = await User.find({}); backupData.collections.users = users.map(user => user.toObject()); // Backup SourceTexts console.log('📚 Backing up source texts...'); const sourceTexts = await SourceText.find({}); backupData.collections.sourceTexts = sourceTexts.map(text => text.toObject()); // Backup Submissions console.log('📝 Backing up submissions...'); const submissions = await Submission.find({}); backupData.collections.submissions = submissions.map(sub => sub.toObject()); // Save backup to file const backupFile = path.join(this.backupDir, `backup-${timestamp}.json`); await fs.writeFile(backupFile, JSON.stringify(backupData, null, 2)); console.log(`✅ Backup created: ${backupFile}`); console.log(`📊 Backup summary:`); console.log(` - Users: ${users.length}`); console.log(` - Source Texts: ${sourceTexts.length}`); console.log(` - Submissions: ${submissions.length}`); return backupFile; } catch (error) { console.error('❌ Backup failed:', error); throw error; } finally { await mongoose.connection.close(); } } async restoreBackup(backupFile) { try { console.log(`🔄 Restoring from backup: ${backupFile}`); await mongoose.connect(MONGODB_URI); const backupData = JSON.parse(await fs.readFile(backupFile, 'utf8')); // Clear existing data console.log('🗑️ Clearing existing data...'); await User.deleteMany({}); await SourceText.deleteMany({}); await Submission.deleteMany({}); // Restore Users console.log('👥 Restoring users...'); if (backupData.collections.users) { await User.insertMany(backupData.collections.users); } // Restore SourceTexts console.log('📚 Restoring source texts...'); if (backupData.collections.sourceTexts) { await SourceText.insertMany(backupData.collections.sourceTexts); } // Restore Submissions console.log('📝 Restoring submissions...'); if (backupData.collections.submissions) { await Submission.insertMany(backupData.collections.submissions); } console.log('✅ Backup restored successfully!'); } catch (error) { console.error('❌ Restore failed:', error); throw error; } finally { await mongoose.connection.close(); } } async listBackups() { try { const files = await fs.readdir(this.backupDir); const backups = files.filter(file => file.startsWith('backup-') && file.endsWith('.json')); console.log('📋 Available backups:'); backups.forEach(backup => { console.log(` - ${backup}`); }); return backups; } catch (error) { console.error('❌ Failed to list backups:', error); return []; } } async scheduleBackup() { // Create backup every 24 hours setInterval(async () => { try { await this.createBackup(); console.log('✅ Scheduled backup completed'); } catch (error) { console.error('❌ Scheduled backup failed:', error); } }, 24 * 60 * 60 * 1000); // 24 hours } } // Export for use in other files module.exports = BackupSystem; // If run directly, create a backup if (require.main === module) { const backupSystem = new BackupSystem(); backupSystem.createBackup() .then(() => { console.log('🎉 Backup completed successfully!'); process.exit(0); }) .catch(error => { console.error('💥 Backup failed:', error); process.exit(1); }); }