Files
Coltura/src/Shared/Domain/Attribute/AuditIgnore.php
matthieu de39fe6a3e feat : add audit log (table, writer, listener, API, admin UI, timeline)
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.
2026-04-20 20:51:10 +02:00

20 lines
627 B
PHP

<?php
declare(strict_types=1);
namespace App\Shared\Domain\Attribute;
use Attribute;
/**
* Marqueur a poser sur une propriete d'entite pour l'exclure du tracking audit.
*
* Usage typique : champs sensibles (password, token), champs bruyants (updatedAt
* si recalcule sur chaque ecriture), champs derives. L'AuditLogWriter porte
* deja une blacklist exact-match sur les noms les plus dangereux (password,
* plainPassword, token, secret) en defense-in-depth, mais la regle de base
* reste : annoter explicitement ce qu'on ne veut pas voir trace.
*/
#[Attribute(Attribute::TARGET_PROPERTY)]
final class AuditIgnore {}