feat(backup): replace JSON import/export with SQLite database backup system
Replace the JSON-based import/export with a proper backup system that copies the SQLite database file directly. Supports manual on-demand backups, periodic scheduled backups via node-cron, configurable retention, file download, and full database restore. - Add backupService with VACUUM INTO for safe DB copies - Add backupScheduler following healthcheckScheduler pattern - Add 6 admin API endpoints (create, list, download, restore, delete, schedule) - Add BackupPanel UI with backup table, confirmation dialogs, schedule config - Add backup fields to SystemSettings schema - Remove old ImportExportPanel, exportService, importService, and related code
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
import { json } from '@sveltejs/kit';
|
||||
import type { RequestHandler } from './$types';
|
||||
import { requireAdmin } from '$lib/server/middleware/authorize.js';
|
||||
import { getBackupFilePath } from '$lib/server/services/backupService.js';
|
||||
import { error } from '$lib/server/utils/response.js';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { Readable } from 'node:stream';
|
||||
|
||||
/**
|
||||
* GET /api/admin/backups/:filename/download — Download a backup file (streamed).
|
||||
*/
|
||||
export const GET: RequestHandler = async (event) => {
|
||||
requireAdmin(event);
|
||||
const { filename } = event.params;
|
||||
|
||||
const filePath = getBackupFilePath(filename);
|
||||
if (!filePath) {
|
||||
return json(error('Backup not found'), { status: 404 });
|
||||
}
|
||||
|
||||
const stats = fs.statSync(filePath);
|
||||
const stream = fs.createReadStream(filePath);
|
||||
|
||||
return new Response(Readable.toWeb(stream) as ReadableStream, {
|
||||
status: 200,
|
||||
headers: {
|
||||
'Content-Type': 'application/octet-stream',
|
||||
'Content-Disposition': `attachment; filename="${path.basename(filePath)}"`,
|
||||
'Content-Length': String(stats.size)
|
||||
}
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user