Files
web-app-launcher/src/routes/api/admin/backups/[filename]/download/+server.ts
T
alexei.dolgolyov b0439e39c4 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
2026-04-02 23:16:18 +03:00

34 lines
1.0 KiB
TypeScript

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)
}
});
};