const { db } = require('../src/database/db'); async function up() { console.log('Adding backup service tables and settings...'); // Create backup_runs table to track backup history const hasBackupRunsTable = await db.schema.hasTable('backup_runs'); if (!hasBackupRunsTable) { await db.schema.createTable('backup_runs', (table) => { table.increments('id').primary(); table.datetime('started_at').notNullable(); table.datetime('completed_at'); table.string('status').defaultTo('running'); // running, completed, failed table.string('backup_type'); // full, incremental table.integer('files_backed_up').defaultTo(0); table.bigInteger('total_size_bytes').defaultTo(0); table.integer('duration_seconds'); table.text('error_message'); table.json('statistics'); // Detailed stats about the backup table.json('file_checksums'); // Store checksums for change detection }); } // Create backup_file_states table to track individual file states const hasBackupFileStatesTable = await db.schema.hasTable('backup_file_states'); if (!hasBackupFileStatesTable) { await db.schema.createTable('backup_file_states', (table) => { table.increments('id').primary(); table.string('file_path').notNullable(); table.string('checksum').notNullable(); table.bigInteger('size_bytes'); table.datetime('last_modified'); table.datetime('last_backed_up'); table.boolean('is_archived').defaultTo(false); table.index(['file_path'], 'idx_backup_file_path'); table.index(['checksum'], 'idx_backup_checksum'); }); } // Add backup-related settings to app_settings const backupSettings = [ { setting_key: 'backup_enabled', setting_value: JSON.stringify(false), setting_type: 'backup' }, { setting_key: 'backup_schedule', setting_value: JSON.stringify('0 2 * * *'), // Default: 2 AM daily setting_type: 'backup' }, { setting_key: 'backup_destination_type', setting_value: JSON.stringify('local'), // local, rsync, s3 setting_type: 'backup' }, { setting_key: 'backup_destination_path', setting_value: JSON.stringify('/backup/picpeak'), setting_type: 'backup' }, { setting_key: 'backup_rsync_host', setting_value: JSON.stringify(''), setting_type: 'backup' }, { setting_key: 'backup_rsync_user', setting_value: JSON.stringify(''), setting_type: 'backup' }, { setting_key: 'backup_rsync_path', setting_value: JSON.stringify(''), setting_type: 'backup' }, { setting_key: 'backup_rsync_ssh_key', setting_value: JSON.stringify(''), setting_type: 'backup' }, { setting_key: 'backup_s3_endpoint', setting_value: JSON.stringify(''), setting_type: 'backup' }, { setting_key: 'backup_s3_bucket', setting_value: JSON.stringify(''), setting_type: 'backup' }, { setting_key: 'backup_s3_access_key', setting_value: JSON.stringify(''), setting_type: 'backup' }, { setting_key: 'backup_s3_secret_key', setting_value: JSON.stringify(''), setting_type: 'backup' }, { setting_key: 'backup_s3_region', setting_value: JSON.stringify('us-east-1'), setting_type: 'backup' }, { setting_key: 'backup_retention_days', setting_value: JSON.stringify(30), setting_type: 'backup' }, { setting_key: 'backup_include_archived', setting_value: JSON.stringify(true), setting_type: 'backup' }, { setting_key: 'backup_compression', setting_value: JSON.stringify(true), setting_type: 'backup' }, { setting_key: 'backup_email_on_failure', setting_value: JSON.stringify(true), setting_type: 'backup' }, { setting_key: 'backup_email_on_success', setting_value: JSON.stringify(false), setting_type: 'backup' }, { setting_key: 'backup_max_file_size_mb', setting_value: JSON.stringify(5000), // Skip files larger than 5GB setting_type: 'backup' }, { setting_key: 'backup_exclude_patterns', setting_value: JSON.stringify(['*.tmp', '.DS_Store', 'Thumbs.db']), setting_type: 'backup' } ]; // Insert backup settings if they don't exist for (const setting of backupSettings) { const exists = await db('app_settings') .where('setting_key', setting.setting_key) .first(); if (!exists) { await db('app_settings').insert(setting); } } // Add backup-related email templates const backupEmailTemplates = [ { template_key: 'backup_failed', subject_en: 'Backup Failed - Immediate Attention Required', subject_de: 'Backup fehlgeschlagen - Sofortige Aufmerksamkeit erforderlich', body_html_en: `

Backup Failed

The scheduled backup has failed and requires immediate attention.

Error Details:

Please check the system logs for more details and resolve the issue as soon as possible.

`, body_html_de: `

Backup fehlgeschlagen

Das geplante Backup ist fehlgeschlagen und erfordert sofortige Aufmerksamkeit.

Fehlerdetails:

Bitte überprüfen Sie die Systemprotokolle für weitere Details und beheben Sie das Problem so schnell wie möglich.

`, body_text_en: 'Backup Failed\n\nThe scheduled backup has failed and requires immediate attention.\n\nStart Time: {{start_time}}\nBackup Type: {{backup_type}}\nError: {{error_message}}\n\nPlease check the system logs for more details.', body_text_de: 'Backup fehlgeschlagen\n\nDas geplante Backup ist fehlgeschlagen und erfordert sofortige Aufmerksamkeit.\n\nStartzeit: {{start_time}}\nBackup-Typ: {{backup_type}}\nFehler: {{error_message}}\n\nBitte überprüfen Sie die Systemprotokolle für weitere Details.', variables: JSON.stringify(['start_time', 'backup_type', 'error_message']) }, { template_key: 'backup_completed', subject_en: 'Backup Completed Successfully', subject_de: 'Backup erfolgreich abgeschlossen', body_html_en: `

Backup Completed

The scheduled backup has been completed successfully.

Backup Summary:

`, body_html_de: `

Backup abgeschlossen

Das geplante Backup wurde erfolgreich abgeschlossen.

Backup-Zusammenfassung:

`, body_text_en: 'Backup Completed\n\nThe scheduled backup has been completed successfully.\n\nStart Time: {{start_time}}\nDuration: {{duration}}\nFiles Backed Up: {{files_count}}\nTotal Size: {{total_size}}\nBackup Type: {{backup_type}}', body_text_de: 'Backup abgeschlossen\n\nDas geplante Backup wurde erfolgreich abgeschlossen.\n\nStartzeit: {{start_time}}\nDauer: {{duration}}\nGesicherte Dateien: {{files_count}}\nGesamtgröße: {{total_size}}\nBackup-Typ: {{backup_type}}', variables: JSON.stringify(['start_time', 'duration', 'files_count', 'total_size', 'backup_type']) } ]; // Insert backup email templates if they don't exist for (const template of backupEmailTemplates) { const exists = await db('email_templates') .where('template_key', template.template_key) .first(); if (!exists) { await db('email_templates').insert(template); } } console.log('Backup service tables and settings added successfully'); } async function down() { // Remove backup tables await db.schema.dropTableIfExists('backup_file_states'); await db.schema.dropTableIfExists('backup_runs'); // Remove backup settings await db('app_settings') .where('setting_type', 'backup') .delete(); // Remove backup email templates await db('email_templates') .whereIn('template_key', ['backup_failed', 'backup_completed']) .delete(); } module.exports = { up, down };