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.
This commit is contained in:
@@ -21,6 +21,8 @@ use App\Module\Core\Infrastructure\Doctrine\DoctrineUserRepository;
|
||||
// (targetEntity) via FQCN string, ce qui est obligatoire pour Doctrine.
|
||||
// SiteNotAuthorizedException est importee depuis Shared (sa location canonique).
|
||||
use App\Module\Sites\Domain\Entity\Site;
|
||||
use App\Shared\Domain\Attribute\Auditable;
|
||||
use App\Shared\Domain\Attribute\AuditIgnore;
|
||||
use App\Shared\Domain\Contract\SiteInterface;
|
||||
use App\Shared\Domain\Exception\SiteNotAuthorizedException;
|
||||
use DateTimeImmutable;
|
||||
@@ -63,6 +65,7 @@ use Symfony\Component\Serializer\Attribute\SerializedName;
|
||||
)]
|
||||
#[ORM\Entity(repositoryClass: DoctrineUserRepository::class)]
|
||||
#[ORM\Table(name: '`user`')]
|
||||
#[Auditable]
|
||||
class User implements UserInterface, PasswordAuthenticatedUserInterface
|
||||
{
|
||||
#[ORM\Id]
|
||||
@@ -155,9 +158,11 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
|
||||
private ?SiteInterface $currentSite = null;
|
||||
|
||||
#[ORM\Column]
|
||||
#[AuditIgnore]
|
||||
private ?string $password = null;
|
||||
|
||||
#[Groups(['user:write'])]
|
||||
#[AuditIgnore]
|
||||
private ?string $plainPassword = null;
|
||||
|
||||
#[ORM\Column(type: 'datetime_immutable')]
|
||||
|
||||
Reference in New Issue
Block a user