Module 5 — Data Protection

Sauvegarde & Résilience

Mise en œuvre du stockage souverain (BYOS) et des protocoles d'immuabilité WORM. Protection automatique, résiliente et souveraine de vos données critiques.

Types de Sauvegarde

DIXX supporte 5 types de sauvegarde selon vos besoins de récupération et vos contraintes de bande passante. Seul PostgreSQL est actuellement supporté pour l'export natif via pg_dump.

Full
Recommandé
Snapshot complet de la base de données — schéma + données.
Schéma
Structure seule (DDL) — tables, index, contraintes.
Data
Données seules (DML) — sans structure.
Incrémental
Delta depuis la dernière sauvegarde réussie (parentBackupId).
Différentiel
Delta depuis le dernier backup Full (baseFullBackupId).
WORM
Sécurisé
Immuable — ne peut être ni modifié ni supprimé pendant la rétention.

Stratégie WORM — Immuabilité Logicielle

DIXX implémente une politique WORM (Write Once, Read Many). Une fois marqué WORM, un backup ne peut être ni modifié ni supprimé via l'interface ou l'API standard pendant toute sa période de rétention.

Protection Anti-Ransomware
En cas d'attaque par ransomware sur vos serveurs opérationnels, les backups WORM restent protégés et immédiatement restaurables. Le préfixe [WORM] dans le nom du fichier et le path /worm/ identifient les backups immuables.
typescript
// src/lib/services/backup-service.ts
// Identification des backups WORM
private static isWormRow(row: any) {
  return (
    String(row?.filename || "").includes("[WORM]") ||
    String(row?.storage_path || "").includes("/worm/")
  );
}

// Politique de rétention : les WORM sont exclus de la suppression automatique
const deletable = oldRows.filter((r) => !this.isWormRow(r));

// Structure du path de stockage :
// {ownerId}/{connectionId}/worm/{filename}   → WORM (immuable)
// {ownerId}/{connectionId}/standard/{fn}      → Standard (rétention normale)
Manifest JSON
Chaque backup génère un fichier .manifest.json contenant les métadonnées de chaîne (type, parentId, lineage, isWorm).
Chain Mode
Le mode single | incremental | differential est tracé viaparentBackupId et baseFullBackupId dans les métadonnées.

Stockage Souverain (BYOS)

La fonctionnalité BYOS (Bring Your Own Storage) — ou Stockage Personnel Connecté — permet de connecter votre propre infrastructure cloud directement à DIXX.

Supabase Storage
Défaut
Stockage natif DIXX. Buckets privés avec RLS, upload sécurisé.
Amazon S3 (BYOS)
Intégration via @aws-sdk/client-s3. Configuration par bucket + région.
Google Drive (BYOS)
OAuth2 avec refresh token ou service account. FolderId configurable.
typescript
// Configuration BYOS dans backup_configurations
type BackupConfiguration = {
  byos_type: "supabase" | "s3" | "google_drive";
  byos_config: {
    // Pour S3 :
    bucket_name: string;
    region: string;
    access_key_id: string;
    secret_access_key: string;
    // Pour Google Drive :
    folder_id: string;
    google_refresh_token_enc: string; // Chiffré AES-256
  };
  is_enabled: boolean;
  schedule_cron: string | null;  // ex: "0 2 * * *"
  retention_days: number;
  backup_type: "full" | "incremental" | "differential";
};
Fallback Automatique
Si Supabase Storage est indisponible lors d'un backup planifié, DIXX active automatiquement un fallback local : le fichier est sauvegardé temporairement sur le filesystem du serveur et une notification d'alerte est émise.

Workflow de Sauvegarde

1

Configuration Initiale (une seule fois)

Sélection de la fréquence (cron), du type (Full/Incrémental), du stockage (Supabase/S3/Drive) et activation de l'option WORM si nécessaire.
2

Exécution Automatique

DIXX lance pg_dump avec les paramètres appropriés, gère les métadonnées de chaîne et uploade le fichier vers le stockage configuré avec retry ×3.
3

Monitoring & Historique

Table backups_history : chaque backup est tracé avec son statut, sa taille en bytes, sa durée, son path de stockage et ses métadonnées de chaîne.
4

Restauration en Un Clic

Depuis l'interface, sélection d'un point de restauration → pg_restore --clean --if-exists avec vérification d'intégrité.

Politique de Rétention

La politique de rétention est configurée par connexion dans backup_configurations.retention_days. Les backups dépassant la période configurée sont automatiquement supprimés du stockage —sauf les backups WORM qui sont protégés jusqu'à leur période de rétention spécifique.

typescript
// Politique de rétention automatique (backup-service.ts)
private static async applyRetentionPolicy(
  connectionId: string, retentionDays: number
) {
  const cutoff = new Date(
    Date.now() - retentionDays * 24 * 60 * 60 * 1000
  ).toISOString();

  const { data: oldRows } = await supabase
    .from("backups_history")
    .select("id, filename, storage_path")
    .eq("connection_id", connectionId)
    .lt("created_at", cutoff);

  // ✅ Exclure les backups WORM de la suppression
  const deletable = oldRows.filter((r) => !this.isWormRow(r));
  
  // Suppression Supabase Storage + enregistrements DB
  await supabase.storage.from("backups").remove(paths);
  await supabase.from("backups_history").delete().in("id", ids);
}