const archiver = require('archiver'); const fs = require('fs').promises; const path = require('path'); const { db } = require('../database/db'); const logger = require('../utils/logger'); const ACTIVE_PATH = path.join(__dirname, '../../../storage/events/active'); const ARCHIVE_PATH = path.join(__dirname, '../../../storage/events/archived'); async function archiveEvent(event) { try { const eventPath = path.join(ACTIVE_PATH, event.slug); const archiveName = `${event.slug}.zip`; const archivePath = path.join(ARCHIVE_PATH, archiveName); // Ensure archive directory exists await fs.mkdir(ARCHIVE_PATH, { recursive: true }); // Create archive const output = require('fs').createWriteStream(archivePath); const archive = archiver('zip', { zlib: { level: 9 } // Maximum compression }); archive.on('error', (err) => { throw err; }); output.on('close', async () => { logger.info(`Archive created: ${archiveName} (${archive.pointer()} bytes)`); // Update database await db('events').where('id', event.id).update({ is_archived: true, archive_path: path.relative(path.join(__dirname, '../../../storage'), archivePath), archived_at: new Date() }); // Delete original files await fs.rm(eventPath, { recursive: true }); // Delete thumbnails const photos = await db('photos').where('event_id', event.id); for (const photo of photos) { if (photo.thumbnail_path) { const thumbPath = path.join(__dirname, '../../../storage', photo.thumbnail_path); await fs.unlink(thumbPath).catch(() => {}); // Ignore if already deleted } } // Queue completion email await db('email_queue').insert({ event_id: event.id, recipient_email: event.admin_email, email_type: 'archive_complete', email_data: JSON.stringify({ event_name: event.event_name, archive_size: archive.pointer() }) }); }); archive.pipe(output); archive.directory(eventPath, false); await archive.finalize(); } catch (error) { logger.error(`Error archiving event ${event.slug}:`, error); throw error; } } module.exports = { archiveEvent };