feat: Audit trail pour actions sensibles

Story 1.7 - Implémente un système complet d'audit trail pour tracer
toutes les actions sensibles (authentification, modifications de données,
exports) avec immuabilité garantie par PostgreSQL.

Fonctionnalités principales:
- Table audit_log append-only avec contraintes PostgreSQL (RULE)
- AuditLogger centralisé avec injection automatique du contexte
- Correlation ID pour traçabilité distribuée (HTTP + async)
- Handlers pour événements d'authentification
- Commande d'archivage des logs anciens
- Pas de PII dans les logs (emails/IPs hashés)

Infrastructure:
- Middlewares Messenger pour propagation du Correlation ID
- HTTP middleware pour génération/propagation du Correlation ID
- Support multi-tenant avec TenantResolver
This commit is contained in:
2026-02-04 00:11:58 +01:00
parent b823479658
commit 2ed60fdcc1
38 changed files with 4179 additions and 81 deletions

View File

@@ -0,0 +1,65 @@
<?php
declare(strict_types=1);
namespace App\Shared\Application\Port;
use Ramsey\Uuid\UuidInterface;
/**
* Port for audit logging.
*
* Infrastructure implementation writes to append-only database table.
*
* @see Story 1.7 - T2: AuditLogger Service
*/
interface AuditLogger
{
/**
* Log authentication events (login success/failure, account blocked, etc.).
*
* @param array<string, mixed> $payload Event-specific data
* @param string|null $tenantId Override tenant from event (for async handlers without TenantContext)
*/
public function logAuthentication(
string $eventType,
?UuidInterface $userId,
array $payload,
?string $tenantId = null,
): void;
/**
* Log data changes (notes, absences, student data modifications).
*
* @param array<string, mixed> $oldValues Previous values
* @param array<string, mixed> $newValues New values
*/
public function logDataChange(
string $aggregateType,
UuidInterface $aggregateId,
string $eventType,
array $oldValues,
array $newValues,
?string $reason = null,
): void;
/**
* Log export operations (CSV, PDF, RGPD data exports).
*/
public function logExport(
string $exportType,
int $recordCount,
?string $targetDescription = null,
): void;
/**
* Log access to sensitive data (student records, etc.).
*
* @param array<string, mixed> $context Additional context (screen, action)
*/
public function logAccess(
string $resourceType,
UuidInterface $resourceId,
array $context = [],
): void;
}