feat: implement server-side function to save session snapshots, including input validation and database table creation fallback.

This commit is contained in:
Michael committed 2026-02-22 13:41:49 +01:00
1 parent 0bec6b953b
commit 7288b3da72
1 file changed
+37 -40
+37 -40
View File
@@ -46,49 +46,46 @@ export async function saveSnapshot(raw: unknown) {
return { success: true, snapshotId: created?.id }; return { success: true, snapshotId: created?.id };
} catch (err: any) { } catch (err: any) {
console.error("Snapshot DB error:", err); console.error("Initial snapshot save failed, attempting auto-repair...", err);
// Détection plus large (code 42P01 ou texte relation does not exist) try {
const isTableMissing = err.code === '42P01' || // Tentative systématique de création de table (no-op si déjà là)
err.message?.toLowerCase().includes("relation") || await db.execute(sql`
err.message?.toLowerCase().includes("does not exist"); CREATE TABLE IF NOT EXISTS session_snapshots (
id SERIAL PRIMARY KEY,
code_fournisseur VARCHAR(20) NOT NULL,
nom_fournisseur VARCHAR(255),
magasin VARCHAR(20) NOT NULL,
changes JSONB NOT NULL,
summary_json JSONB,
label TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
`);
if (isTableMissing) { // Deuxième tentative d'insertion
console.log("Table missing detected, attempting auto-repair..."); const [retryCreated] = await db
try { .insert(sessionSnapshots)
await db.execute(sql` .values({
CREATE TABLE IF NOT EXISTS session_snapshots ( codeFournisseur,
id SERIAL PRIMARY KEY, nomFournisseur: nomFournisseur ?? null,
code_fournisseur VARCHAR(20) NOT NULL, magasin,
nom_fournisseur VARCHAR(255), label: label ?? `Snapshot — ${new Date().toLocaleDateString("fr-FR")}`,
magasin VARCHAR(20) NOT NULL, changes,
changes JSONB NOT NULL, summaryJson: summary ?? null,
summary_json JSONB, })
label TEXT, .returning({ id: sessionSnapshots.id });
created_at TIMESTAMP DEFAULT NOW()
);
`);
// On ré-essaie l'insertion une seule fois return { success: true, snapshotId: retryCreated?.id };
const [retryCreated] = await db } catch (repairErr: any) {
.insert(sessionSnapshots) console.error("Snapshot auto-repair/retry failed:", repairErr);
.values({ // On renvoie les deux erreurs pour comprendre si c'est la création ou l'insertion qui échoue
codeFournisseur, const origMsg = (err.message || String(err)).split('\n')[0];
nomFournisseur: nomFournisseur ?? null, const retryMsg = (repairErr.message || String(repairErr)).split('\n')[0];
magasin, return {
label: label ?? `Snapshot — ${new Date().toLocaleDateString("fr-FR")}`, success: false,
changes, error: `Erreur initiale: ${origMsg} | Erreur après réparation: ${retryMsg}`
summaryJson: summary ?? null, };
})
.returning({ id: sessionSnapshots.id });
return { success: true, snapshotId: retryCreated?.id };
} catch (repairErr: any) {
console.error("Repair or retry failed:", repairErr);
return { success: false, error: `Repair/Retry failed: ${repairErr.message}` };
}
} }
return { success: false, error: `DB Error: ${err.message || String(err)}` };
} }
} }