- TIMESTAMP(6) WITH TIME ZONE + tie-breaker id DESC sur l'ORDER BY pour
garantir un tri deterministe quand plusieurs lignes partagent la meme
timestamp (batch fixture, bulk flush < 1µs).
- Suppression de la clause ESCAPE '\\' redondante (`\` est deja
l'echappement LIKE par defaut en PostgreSQL) et fragile sur
standard_conforming_strings. Le str_replace des wildcards reste.
- paginationMaximumItemsPerPage : 100 -> 50. Reduit le pire cas de
reponse lourde sur un endpoint admin (changes JSONB volumineux).
Implemente le journal d'audit append-only sur toutes les mutations Doctrine
des entites portant #[Auditable]. Couvre les 5 tickets de doc/audit-log.md :
1. Table PG audit_log (uuid PK, jsonb changes, index entity/time/performer)
+ AuditLogWriter (DBAL connexion dediee audit, blacklist defense-in-depth
sur password/plainPassword/token/secret) + RequestIdProvider (UUID v4 par
requete HTTP principale).
2. Attributs Auditable / AuditIgnore dans Shared/Domain/Attribute/
+ AuditListener (onFlush capture + postFlush ecriture hors transaction ORM,
pattern swap-and-clear, erreurs loguees jamais propagees). User annote.
3. API Platform read-only /api/audit-logs (permission core.audit_log.view)
avec filtres entity_type / entity_id / action / performed_by / plage
performed_at + DbalPaginator implementant PaginatorInterface (hydra:view
genere automatiquement).
4. Page admin /admin/audit-log : tableau pagine, filtres persistes en query
params, row expandable (diff + timeline de l'entite), entree sidebar avec
permission. Composable useAuditLog avec resetAuditLog() auto-enregistre
sur onAuthSessionCleared.
5. Composant AuditTimeline reutilisable : garde permission, lazy loading,
dates relatives FR, skeleton loader.
Fix connexe : phpunit.dist.xml forcait APP_ENV=dev via <env> ce qui cablait
framework.test=false et rendait test.service_container indisponible ; le
JWT_PASSPHRASE ne matchait pas non plus les cles dev. Corrige en meme temps
pour debloquer la suite de tests.