File size: 4,715 Bytes
da819ac
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
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);
    });
}