diff --git a/CODE_AUDIT.md b/CODE_AUDIT.md index 7f5fff3..6764f22 100644 --- a/CODE_AUDIT.md +++ b/CODE_AUDIT.md @@ -896,6 +896,13 @@ TJSONHelper.SendJSON(AResponse, LArr); // libère LArr (AOwnsObj=True) ### 6c-9. ❓ `PRAGMA foreign_keys` — à vérifier, non tranché +> ✅ **RÉSOLU 2026-07-16.** `FConn.Params.Values['ForeignKeys'] := 'On'` ajouté +> à la config de connexion FireDAC ([PM.Database.pas](delphi-backend/Source/PM.Database.pas)). +> Correct dans les deux cas (no-op si c'était déjà le défaut). **Vérif base +> avant fix : 0 attachment / 0 history orphelin** — soit le défaut FireDAC était +> déjà On, soit aucun delete-permanent-avec-attachments n'a encore eu lieu ; +> l'explicite lève le doute pour de bon. + `PRAGMA foreign_keys` n'est défini **nulle part**. Le schéma s'appuie pourtant sur `ON DELETE CASCADE` : [Entries.pas:704](delphi-backend/Handlers/PM.Handler.Entries.pas:704) (delete permanent) ne nettoie **ni** `entry_attachments` **ni** diff --git a/delphi-backend/Source/PM.Database.pas b/delphi-backend/Source/PM.Database.pas index 110ea3e..79440b4 100644 --- a/delphi-backend/Source/PM.Database.pas +++ b/delphi-backend/Source/PM.Database.pas @@ -83,6 +83,12 @@ begin FConn.Params.Values['Synchronous'] := 'Normal'; FConn.Params.Values['BusyTimeout'] := '5000'; FConn.Params.Values['JournalMode'] := 'WAL'; + // Explicit ON: SQLite defaults foreign_keys OFF per-connection, and the + // schema relies on ON DELETE CASCADE (entry_attachments, entries_password_ + // history, recovery_keys on user/entry delete). FireDAC is *said* to default + // this On but it's undocumented for us — set it so a permanent delete never + // leaves orphaned encrypted blobs. No-op if it was already On (§6c-9). + FConn.Params.Values['ForeignKeys'] := 'On'; FConn.Open; CreateSchema; ApplyMigrations;