feat(settings): backup/restore de la base de données (amelioration #4)
- service dbBackup : createBackup (VACUUM INTO → archive .db cohérente), validateSqlite (header + integrity_check + schéma), prepareRestore (sauvegarde de sécurité auto + dépôt <db>.incoming) - swap hors-ligne au démarrage (db/client.ts) : aucune corruption d'une base ouverte ; restauration appliquée au redémarrage - routes GET /system/db/info|backup, POST /system/db/restore - lib api : dbInfo / dbBackup (download navigateur) / dbRestore (upload) - SettingsModal : onglet « Base de données » (taille, télécharger, restaurer avec confirmation Popup), icônes database/upload, styles DS variables only Testé end-to-end : backup 184 Ko valide, restore + safety .bak + swap au boot, fichier invalide rejeté. tsc 0 erreur · 91 tests · build OK. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+14
-2
@@ -1,15 +1,27 @@
|
||||
// server/db/client.ts
|
||||
import Database from "better-sqlite3";
|
||||
import { drizzle } from "drizzle-orm/better-sqlite3";
|
||||
import { mkdirSync } from "node:fs";
|
||||
import { mkdirSync, existsSync, rmSync, renameSync } from "node:fs";
|
||||
import { dirname } from "node:path";
|
||||
import { env } from "../env.js";
|
||||
import * as schema from "./schema.js";
|
||||
|
||||
mkdirSync(dirname(env.dbPath), { recursive: true });
|
||||
|
||||
// Restauration en attente : un fichier `<db>.incoming` déposé par /system/db/restore
|
||||
// est appliqué au démarrage (swap hors-ligne = aucune corruption d'une base ouverte).
|
||||
const incoming = `${env.dbPath}.incoming`;
|
||||
if (existsSync(incoming)) {
|
||||
for (const ext of ["", "-wal", "-shm"]) {
|
||||
const p = `${env.dbPath}${ext}`;
|
||||
if (existsSync(p)) rmSync(p, { force: true });
|
||||
}
|
||||
renameSync(incoming, env.dbPath);
|
||||
}
|
||||
|
||||
const sqlite = new Database(env.dbPath);
|
||||
sqlite.pragma("journal_mode = WAL");
|
||||
sqlite.pragma("foreign_keys = ON");
|
||||
|
||||
export const db = drizzle(sqlite, { schema });
|
||||
export { schema };
|
||||
export { schema, sqlite };
|
||||
|
||||
Reference in New Issue
Block a user