Spaces:
Sleeping
Sleeping
| 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); | |
| } | |
| }; | |
| // Backup and Version Control System | |
| const backupVersionControl = { | |
| // Create comprehensive backup | |
| async createBackup(customBackupName = null) { | |
| try { | |
| const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); | |
| const backupName = customBackupName || `comprehensive-backup-${timestamp}`; | |
| console.log(`πΎ Creating comprehensive backup: ${backupName}`); | |
| const collections = ['subtitles', 'sourcetexts', 'submissions', 'users', 'securitylogs']; | |
| const backupData = { | |
| metadata: { | |
| backupName, | |
| timestamp: new Date(), | |
| collections: collections, | |
| totalRecords: 0, | |
| version: '1.0', | |
| createdBy: 'system' | |
| }, | |
| data: {} | |
| }; | |
| // Export all collections | |
| 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 backup to file system | |
| 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)); | |
| // Create backup record in database | |
| const backupRecord = { | |
| backupName, | |
| timestamp: new Date(), | |
| collections: collections, | |
| totalRecords: backupData.metadata.totalRecords, | |
| filePath: backupPath, | |
| status: 'created', | |
| createdBy: 'system' | |
| }; | |
| // Save to backup collection | |
| const backupCollection = mongoose.connection.db.collection('backups'); | |
| await backupCollection.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; | |
| } | |
| }, | |
| // Restore from backup | |
| async restoreFromBackup(backupName) { | |
| try { | |
| console.log(`π Restoring from backup: ${backupName}`); | |
| // Load backup file | |
| const backupPath = path.join(__dirname, 'backups', `${backupName}.json`); | |
| const backupData = JSON.parse(await fs.readFile(backupPath, 'utf8')); | |
| console.log(`π Backup metadata:`, backupData.metadata); | |
| // Confirm restoration | |
| console.log('β οΈ This will overwrite existing data. Are you sure? (y/N)'); | |
| // In a real implementation, you'd get user confirmation here | |
| // Restore each collection | |
| for (const [collection, data] of Object.entries(backupData.data)) { | |
| try { | |
| // Clear existing data | |
| await mongoose.connection.db.collection(collection).deleteMany({}); | |
| // Insert backup data | |
| if (data.length > 0) { | |
| await mongoose.connection.db.collection(collection).insertMany(data); | |
| } | |
| console.log(` β Restored ${data.length} records to ${collection}`); | |
| } catch (error) { | |
| console.error(` β Error restoring ${collection}:`, error.message); | |
| } | |
| } | |
| console.log(`β Restoration completed: ${backupName}`); | |
| } catch (error) { | |
| console.error('β Error restoring from backup:', error); | |
| throw error; | |
| } | |
| }, | |
| // List available backups | |
| async listBackups() { | |
| try { | |
| console.log('π Available backups:'); | |
| // List from database | |
| const backupCollection = mongoose.connection.db.collection('backups'); | |
| const dbBackups = await backupCollection.find({}).sort({ timestamp: -1 }).toArray(); | |
| if (dbBackups.length === 0) { | |
| console.log(' No backups found in database'); | |
| } else { | |
| console.log(' Database backups:'); | |
| dbBackups.forEach(backup => { | |
| console.log(` π¦ ${backup.backupName} (${backup.totalRecords} records, ${new Date(backup.timestamp).toLocaleString()})`); | |
| }); | |
| } | |
| // 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); | |
| } | |
| }, | |
| // Version control for content changes | |
| async createVersionControl() { | |
| try { | |
| console.log('π Creating version control system...'); | |
| const versionControlSchema = new mongoose.Schema({ | |
| documentId: { type: String, required: true }, | |
| collection: { type: String, required: true }, | |
| version: { type: Number, required: true }, | |
| changes: mongoose.Schema.Types.Mixed, | |
| timestamp: { type: Date, default: Date.now }, | |
| userId: String, | |
| commitMessage: String, | |
| previousVersion: Number, | |
| checksum: String | |
| }); | |
| const VersionControl = mongoose.model('VersionControl', versionControlSchema); | |
| // Create indexes for efficient querying | |
| await VersionControl.createIndexes(); | |
| console.log('β Version control system created'); | |
| return VersionControl; | |
| } catch (error) { | |
| console.error('β Error creating version control:', error); | |
| } | |
| }, | |
| // Track content changes | |
| async trackChange(collection, documentId, changes, userId, commitMessage) { | |
| try { | |
| const VersionControl = mongoose.model('VersionControl'); | |
| // Get current version | |
| const latestVersion = await VersionControl.findOne({ | |
| documentId, | |
| collection | |
| }).sort({ version: -1 }); | |
| const newVersion = (latestVersion?.version || 0) + 1; | |
| // Create version record | |
| await VersionControl.create({ | |
| documentId, | |
| collection, | |
| version: newVersion, | |
| changes, | |
| userId, | |
| commitMessage, | |
| previousVersion: latestVersion?.version || null, | |
| timestamp: new Date() | |
| }); | |
| console.log(`π Version ${newVersion} created for ${collection}/${documentId}`); | |
| } catch (error) { | |
| console.error('β Error tracking change:', error); | |
| } | |
| }, | |
| // Get content history | |
| async getContentHistory(collection, documentId) { | |
| try { | |
| const VersionControl = mongoose.model('VersionControl'); | |
| const history = await VersionControl.find({ | |
| documentId, | |
| collection | |
| }).sort({ version: -1 }); | |
| console.log(`π Version history for ${collection}/${documentId}:`); | |
| history.forEach(version => { | |
| console.log(` v${version.version} (${new Date(version.timestamp).toLocaleString()}) - ${version.commitMessage}`); | |
| }); | |
| return history; | |
| } catch (error) { | |
| console.error('β Error getting content history:', error); | |
| } | |
| }, | |
| // Automated backup scheduling | |
| async scheduleBackups() { | |
| try { | |
| console.log('β° Setting up automated backup scheduling...'); | |
| const scheduleSchema = new mongoose.Schema({ | |
| scheduleType: { type: String, enum: ['daily', 'weekly', 'monthly'], required: true }, | |
| lastBackup: Date, | |
| nextBackup: Date, | |
| isActive: { type: Boolean, default: true }, | |
| createdBy: String | |
| }); | |
| const Schedule = mongoose.model('Schedule', scheduleSchema); | |
| // Create default daily backup schedule | |
| await Schedule.create({ | |
| scheduleType: 'daily', | |
| lastBackup: null, | |
| nextBackup: new Date(Date.now() + 24 * 60 * 60 * 1000), // Tomorrow | |
| isActive: true, | |
| createdBy: 'system' | |
| }); | |
| console.log('β Automated backup schedule created (daily)'); | |
| } catch (error) { | |
| console.error('β Error setting up backup scheduling:', error); | |
| } | |
| }, | |
| // Verify backup integrity | |
| async verifyBackupIntegrity(backupName) { | |
| try { | |
| console.log(`π Verifying backup integrity: ${backupName}`); | |
| const backupPath = path.join(__dirname, 'backups', `${backupName}.json`); | |
| const backupData = JSON.parse(await fs.readFile(backupPath, 'utf8')); | |
| let verifiedCount = 0; | |
| let failedCount = 0; | |
| // Verify each collection | |
| 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(`π Integrity verification complete:`); | |
| console.log(` - Verified: ${verifiedCount} collections`); | |
| console.log(` - Failed: ${failedCount} collections`); | |
| return { verifiedCount, failedCount }; | |
| } catch (error) { | |
| console.error('β Error verifying backup integrity:', error); | |
| } | |
| } | |
| }; | |
| // Main function | |
| const main = async () => { | |
| try { | |
| console.log('π Starting backup and version control system...'); | |
| // Create comprehensive backup | |
| const backupName = await backupVersionControl.createBackup(); | |
| // Create version control system | |
| await backupVersionControl.createVersionControl(); | |
| // Set up automated backups | |
| await backupVersionControl.scheduleBackups(); | |
| // List available backups | |
| await backupVersionControl.listBackups(); | |
| console.log('\nπ Backup and version control system ready!'); | |
| console.log('\nπ Available functions:'); | |
| console.log(' - createBackup(): Create new backup'); | |
| console.log(' - restoreFromBackup(name): Restore from backup'); | |
| console.log(' - listBackups(): List available backups'); | |
| console.log(' - trackChange(): Track content changes'); | |
| console.log(' - getContentHistory(): Get version history'); | |
| console.log(' - verifyBackupIntegrity(): Verify backup integrity'); | |
| } catch (error) { | |
| console.error('β Error in backup and version control system:', error); | |
| } finally { | |
| await mongoose.disconnect(); | |
| console.log('π Disconnected from MongoDB'); | |
| } | |
| }; | |
| // Run the system | |
| connectDB().then(() => { | |
| main(); | |
| }); |