Datenbank sichern: Backup als .tar.gz mit Server-Ablage und Client-Download

- Neuer POST /api/backup Endpoint (BackupEndpoint.cs)
- Packt gott.db in data/backup/gott-{timestamp}.tar.gz
- Gibt Archiv gleichzeitig als Download an Client zurück
- Button 'Datenbank sichern' im Header-Dropdown-Menü
- Content-Disposition Header-Parsing mit filename* UTF-8 Support
This commit is contained in:
Meleki committed 2026-02-28 18:18:51 +01:00
1 parent 5b2e8f4a11
commit d434c3ff2a
5 files changed
+91

No files matched your search

+1
View File
@@ -147,6 +147,7 @@
<div class="header-menu-dropdown" id="chatMenuDropdown" hidden>
<button class="header-menu-item" id="systemPromptBtn">System-Prompt anzeigen</button>
<button class="header-menu-item" id="archiveBtn">Archivieren</button>
<button class="header-menu-item" id="backupDbBtn">Datenbank sichern</button>
</div>
</div>
</header>
+18
View File
@@ -128,3 +128,21 @@ async function apiGetChain(chainId) {
if (!resp.ok) return null;
return resp.json();
}
async function apiBackupDb() {
const resp = await fetch('/api/backup', { method: 'POST' });
if (!resp.ok) throw new Error('Backup fehlgeschlagen');
const blob = await resp.blob();
const cd = resp.headers.get('content-disposition') || '';
const filename = cd.match(/filename\*=UTF-8''(.+?)(?:;|$)/i)?.[1]
|| cd.match(/filename="?([^";]+)"?/)?.[1]
|| 'gott-backup.tar.gz';
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
a.remove();
URL.revokeObjectURL(url);
}
+16
View File
@@ -190,6 +190,22 @@ registerPage('chat', {
clearChat();
});
// Datenbank sichern
const backupDbBtn = document.getElementById('backupDbBtn');
if (backupDbBtn) backupDbBtn.addEventListener('click', async () => {
if (chatMenuDropdown) chatMenuDropdown.hidden = true;
backupDbBtn.disabled = true;
try {
await apiBackupDb();
setMeta('✅ Backup erstellt und heruntergeladen');
} catch (e) {
console.error('Backup fehlgeschlagen:', e);
setMeta('❌ Backup fehlgeschlagen');
} finally {
backupDbBtn.disabled = false;
}
});
// State zurücksetzen und History laden
messages.length = 0;
lastKnownMessageId = 0;