import { NextResponse } from 'next/server'; import { getCurrentAdmin, AdminPermission, hasPermission } from '@/lib/admin-auth'; import { exec } from 'child_process'; import { promisify } from 'util'; const execAsync = promisify(exec); export const runtime = 'nodejs'; export async function POST(request: Request) { try { const admin = await getCurrentAdmin(request as any); if (!admin || !hasPermission(admin, AdminPermission.SYSTEM_BACKUP)) { return NextResponse.json( { error: 'Unauthorized' }, { status: 401 } ); } const body = await request.json(); const { type } = body; // 'database' or 'full' const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); const backupDir = '/tmp/biblical-guide-backups'; try { // Create backup directory await execAsync(`mkdir -p ${backupDir}`); let backupPath = ''; let command = ''; if (type === 'database') { // Database backup using pg_dump backupPath = `${backupDir}/db-backup-${timestamp}.sql`; const dbUrl = process.env.DATABASE_URL; if (!dbUrl) { throw new Error('Database URL not configured'); } command = `pg_dump "${dbUrl}" > "${backupPath}"`; } else if (type === 'full') { // Full system backup (excluding node_modules and .next) backupPath = `${backupDir}/full-backup-${timestamp}.tar.gz`; command = `tar -czf "${backupPath}" --exclude=node_modules --exclude=.next --exclude=.git /root/biblical-guide`; } else { return NextResponse.json( { error: 'Invalid backup type' }, { status: 400 } ); } console.log(`Starting ${type} backup...`); const { stdout, stderr } = await execAsync(command); if (stderr && !stderr.includes('Warning')) { throw new Error(`Backup failed: ${stderr}`); } // Get backup file size const { stdout: sizeOutput } = await execAsync(`ls -lh "${backupPath}" | awk '{print $5}'`); const fileSize = sizeOutput.trim(); console.log(`Admin ${admin.email} created ${type} backup: ${backupPath}`); return NextResponse.json({ success: true, backup: { type, path: backupPath, size: fileSize, timestamp: new Date().toISOString(), createdBy: admin.email } }); } catch (error) { console.error('Backup creation failed:', error); return NextResponse.json( { error: `Backup failed: ${error instanceof Error ? error.message : 'Unknown error'}` }, { status: 500 } ); } } catch (error) { console.error('Admin backup error:', error); return NextResponse.json( { error: 'Server error' }, { status: 500 } ); } } export async function GET(request: Request) { try { const admin = await getCurrentAdmin(request as any); if (!admin || !hasPermission(admin, AdminPermission.SYSTEM_BACKUP)) { return NextResponse.json( { error: 'Unauthorized' }, { status: 401 } ); } const backupDir = '/tmp/biblical-guide-backups'; try { // List existing backups const { stdout } = await execAsync(`ls -la ${backupDir} 2>/dev/null || echo ""`); if (!stdout.trim()) { return NextResponse.json({ backups: [] }); } const lines = stdout.trim().split('\n').slice(1); // Skip the first line (total) const backups = lines .filter(line => !line.startsWith('d') && line.includes('backup')) .map(line => { const parts = line.split(/\s+/); const filename = parts[parts.length - 1]; const size = parts[4]; const date = `${parts[5]} ${parts[6]} ${parts[7]}`; return { filename, size, date, type: filename.includes('db-backup') ? 'database' : 'full' }; }); return NextResponse.json({ backups: backups.reverse() // Most recent first }); } catch (error) { return NextResponse.json({ backups: [] }); } } catch (error) { console.error('Admin backup list error:', error); return NextResponse.json( { error: 'Server error' }, { status: 500 } ); } }