const mongoose = require('mongoose'); const fs = require('fs').promises; const path = require('path'); // Atlas MongoDB connection string const MONGODB_URI = 'mongodb+srv://nothingyu:wSg3lbO1PkHiRMq9@sandbox.ecysggv.mongodb.net/test?retryWrites=true&w=majority&appName=sandbox'; // Connect to MongoDB Atlas const connectDB = async () => { try { await mongoose.connect(MONGODB_URI); console.log('โœ… Connected to MongoDB Atlas'); } catch (error) { console.error('โŒ MongoDB connection error:', error); process.exit(1); } }; // Simple Automated Backup System const automatedBackup = { // Create backup async createBackup() { try { const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); const backupName = `auto-backup-${timestamp}`; console.log(`๐Ÿ’พ Creating automated backup: ${backupName}`); // Collections to backup const collections = ['subtitles', 'sourcetexts', 'submissions', 'users']; const backupData = { metadata: { backupName, timestamp: new Date(), collections, totalRecords: 0, version: '1.0', type: 'automated' }, data: {} }; // Export each collection for (const collection of collections) { try { const data = await mongoose.connection.db.collection(collection).find({}).toArray(); backupData.data[collection] = data; backupData.metadata.totalRecords += data.length; console.log(` ๐Ÿ“ฆ Exported ${data.length} records from ${collection}`); } catch (error) { console.warn(` โš ๏ธ Could not export ${collection}:`, error.message); } } // Save to backup directory const backupDir = path.join(__dirname, 'backups'); await fs.mkdir(backupDir, { recursive: true }); const backupPath = path.join(backupDir, `${backupName}.json`); await fs.writeFile(backupPath, JSON.stringify(backupData, null, 2)); // Save backup record to database const backupRecord = { backupName, timestamp: new Date(), collections, totalRecords: backupData.metadata.totalRecords, filePath: backupPath, status: 'created', type: 'automated' }; await mongoose.connection.db.collection('backups').insertOne(backupRecord); console.log(`โœ… Backup created successfully: ${backupName}`); console.log(`๐Ÿ“Š Total records: ${backupData.metadata.totalRecords}`); console.log(`๐Ÿ’พ File saved: ${backupPath}`); return backupName; } catch (error) { console.error('โŒ Error creating backup:', error); throw error; } }, // List backups async listBackups() { try { console.log('๐Ÿ“‹ Available backups:'); // List from database const dbBackups = await mongoose.connection.db.collection('backups').find({}).sort({ timestamp: -1 }).toArray(); if (dbBackups.length === 0) { console.log(' No backups found in database'); } else { console.log(' Database backups:'); dbBackups.forEach(backup => { const date = new Date(backup.timestamp).toLocaleString(); console.log(` ๐Ÿ“ฆ ${backup.backupName} (${backup.totalRecords} records, ${date})`); }); } // List from file system const backupDir = path.join(__dirname, 'backups'); try { const files = await fs.readdir(backupDir); const backupFiles = files.filter(file => file.endsWith('.json')); if (backupFiles.length > 0) { console.log(' File system backups:'); for (const file of backupFiles) { const filePath = path.join(backupDir, file); const stats = await fs.stat(filePath); console.log(` ๐Ÿ’พ ${file} (${(stats.size / 1024).toFixed(2)} KB, ${stats.mtime.toLocaleString()})`); } } } catch (error) { console.log(' No backup directory found'); } } catch (error) { console.error('โŒ Error listing backups:', error); } }, // Clean old backups (keep last 10) async cleanOldBackups() { try { console.log('๐Ÿงน Cleaning old backups...'); const backupCollection = mongoose.connection.db.collection('backups'); const allBackups = await backupCollection.find({}).sort({ timestamp: -1 }).toArray(); if (allBackups.length > 10) { const backupsToDelete = allBackups.slice(10); for (const backup of backupsToDelete) { // Delete file try { await fs.unlink(backup.filePath); console.log(` ๐Ÿ—‘๏ธ Deleted file: ${backup.backupName}`); } catch (error) { console.warn(` โš ๏ธ Could not delete file: ${backup.backupName}`); } // Delete database record await backupCollection.deleteOne({ _id: backup._id }); console.log(` ๐Ÿ—‘๏ธ Deleted record: ${backup.backupName}`); } console.log(`โœ… Cleaned ${backupsToDelete.length} old backups`); } else { console.log('โœ… No old backups to clean (keeping all backups)'); } } catch (error) { console.error('โŒ Error cleaning old backups:', error); } }, // Verify backup integrity async verifyBackup(backupName) { try { console.log(`๐Ÿ” Verifying backup: ${backupName}`); const backupPath = path.join(__dirname, 'backups', `${backupName}.json`); const backupData = JSON.parse(await fs.readFile(backupPath, 'utf8')); let verifiedCount = 0; let failedCount = 0; for (const [collection, data] of Object.entries(backupData.data)) { try { const currentCount = await mongoose.connection.db.collection(collection).countDocuments(); const backupCount = data.length; if (currentCount === backupCount) { verifiedCount++; console.log(` โœ… ${collection}: ${backupCount} records verified`); } else { failedCount++; console.log(` โŒ ${collection}: ${backupCount} in backup, ${currentCount} in database`); } } catch (error) { failedCount++; console.log(` โŒ ${collection}: verification failed`); } } console.log(`๐Ÿ” Verification complete:`); console.log(` - Verified: ${verifiedCount} collections`); console.log(` - Failed: ${failedCount} collections`); return { verifiedCount, failedCount }; } catch (error) { console.error('โŒ Error verifying backup:', error); } } }; // Main function const main = async () => { try { console.log('๐Ÿš€ Starting automated backup system...'); // Create backup const backupName = await automatedBackup.createBackup(); // List all backups await automatedBackup.listBackups(); // Clean old backups await automatedBackup.cleanOldBackups(); // Verify the backup await automatedBackup.verifyBackup(backupName); console.log('\n๐ŸŽ‰ Automated backup system ready!'); console.log('\n๐Ÿ“‹ Available functions:'); console.log(' - createBackup(): Create new backup'); console.log(' - listBackups(): List available backups'); console.log(' - cleanOldBackups(): Keep only last 10 backups'); console.log(' - verifyBackup(name): Verify backup integrity'); console.log('\nโฐ To enable daily automated backups:'); console.log(' 1. Set up a cron job or scheduled task'); console.log(' 2. Run: node simple-automated-backup.js'); console.log(' 3. Or use MongoDB Atlas automatic backups (already enabled)'); } catch (error) { console.error('โŒ Error in automated backup system:', error); } finally { await mongoose.disconnect(); console.log('๐Ÿ”Œ Disconnected from MongoDB'); } }; // Run the system connectDB().then(() => { main(); });