fix(audit-log) : reset pendingLogs sur onFlush + valide filtres + documente contrat rollback
Trois corrections issues du code review multi-agent sur la PR audit-log : - AuditListener : reset defensif de pendingLogs en debut de onFlush. Si un flush precedent a leve une exception avant postFlush (qui n'est jamais appele sur un flush rate), le state listener gardait des changements jamais committes, ecrits a tort par le prochain postFlush reussi — audit_log pouvait donc contenir des lignes decrivant des evenements qui n'ont pas eu lieu en DB. Test de regression via Reflection pour injecter un log orphelin et verifier qu'il n'arrive pas dans audit_log. - AuditLogProvider : validation explicite des filtres performed_at[after] et performed_at[before] (strtotime) + whitelist stricte sur `action` (create|update|delete). Avant, un input malforme remontait jusqu'a Postgres et faisait un 500 (SQLSTATE[22007]). Desormais 400 explicite, pas de log pollue. - doc/audit-log.md : ajoute une section "Contrat" qui explicite ce que audit_log garantit (journal des intentions appliquees par l'ORM) et ne garantit PAS (reflet exact du commit outermost — une ligne audit peut persister si une transaction outermost rollback apres un flush inner reussi, parce que l'audit ecrit sur une connexion DBAL dediee). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -89,6 +89,19 @@ Table non geree par Doctrine ORM (pas d'entite). Ecriture via DBAL uniquement po
|
||||
- **`performed_by` denormalise** : string, pas FK — le nom persiste meme si l'utilisateur est supprime
|
||||
- **Migration** : dans `migrations/` (namespace racine `DoctrineMigrations`) a cause du bug de tri alphabetique FQCN de Doctrine Migrations 3.x entre namespaces
|
||||
|
||||
### Contrat : ce que `audit_log` garantit (et ne garantit pas)
|
||||
|
||||
`audit_log` enregistre les **tentatives de modification** capturees par le `postFlush` Doctrine, ecrites via une connexion DBAL dediee (`audit_connection`). Ce choix est intentionnel : les lignes d'audit survivent au rollback eventuel de la transaction metier principale, ce qui permet de tracer les tentatives meme en cas d'echec applicatif.
|
||||
|
||||
**Conséquence à connaître** : si un controller enveloppe plusieurs operations dans une transaction explicite sur la connexion `default` et que cette transaction outermost rollback apres un flush intermediaire reussi, la ligne audit correspondante **persiste** sur la connexion `audit` alors que la modification metier a ete annulee. L'audit log peut donc contenir des lignes decrivant un etat qui n'existe pas en base metier.
|
||||
|
||||
En pratique :
|
||||
- Ce cas est rare dans un CRM interne (les rollbacks explicites outermost sont marginaux par rapport aux flushes atomiques).
|
||||
- La ligne audit garde son `request_id` qui permet une correlation post-mortem avec les logs applicatifs pour distinguer une tentative avortee d'un commit reussi.
|
||||
- Le comportement est volontaire — pas un bug. Pour un besoin de garantie « audit = reflet exact du commit outermost », il faudrait basculer l'audit sur la meme connexion que le metier (voir `AuditLogWriter`), au prix de perdre la resilience au rollback partiel.
|
||||
|
||||
L'audit est donc un **journal des intentions appliquees par l'ORM**, pas une source de verite transactionnelle sur l'etat final de la DB.
|
||||
|
||||
---
|
||||
|
||||
## Composants backend
|
||||
|
||||
Reference in New Issue
Block a user