diff --git a/src/App.svelte b/src/App.svelte
index b51a9a0..d1fee48 100644
--- a/src/App.svelte
+++ b/src/App.svelte
@@ -81,6 +81,7 @@
let backups: Array<{ filename: string; size_bytes: number; modified_at: string | null }> = [];
let backupError = '';
let backupBusy = false;
+ let restoreBusy = false;
let activeView = 'Live dashboard';
let sessionToken = '';
let authenticated = false;
@@ -320,6 +321,26 @@
}
}
+ async function restoreBackup(filename: string) {
+ if (!window.confirm(`Restore ${filename}? This replaces the current database and cannot be undone.`)) return;
+ restoreBusy = true;
+ backupError = '';
+ try {
+ const response = await fetch(`${serverAddress}/api/v1/admin/backups/restore`, {
+ method: 'POST',
+ headers: { 'content-type': 'application/json', authorization: `Bearer ${sessionToken}` },
+ body: JSON.stringify({ filename, confirmation: 'RESTORE' }),
+ });
+ const result: { status?: string; reason?: string | null } = await response.json();
+ if (!response.ok || result.status !== 'ok') throw new Error(result.reason || 'Database restore failed.');
+ backupError = 'Database restored. Restart the server before continuing to use the dashboard.';
+ } catch (error) {
+ backupError = error instanceof Error ? error.message : 'Database restore failed.';
+ } finally {
+ restoreBusy = false;
+ }
+ }
+
async function replaceCredentials() {
authBusy = true;
authError = '';
@@ -1236,7 +1257,7 @@
{:else if activeView === 'Overlays'}
{:else if activeView === 'Settings'}
- Daily backups use the server's local schedule. Restore remains a destructive recovery workflow and is not started from this list. Daily backups use the server's local schedule. Restore replaces the current database and is permanently destructive.