Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
3.4 KiB
Journal des actions (Audit Log)
Objectif
Tracer les actions utilisateurs pour diagnostiquer rapidement les problèmes de calcul signalés. Quand un utilisateur signale une incohérence dans ses heures, RTT ou congés, le journal permet de voir exactement ce qui a été modifié, par qui, et quand.
Accès
- Rôle requis :
ROLE_SUPER_ADMIN(rôle caché, non visible dans l'interface de gestion des utilisateurs) - Ajout du rôle : directement en base de données
UPDATE users SET roles = '["ROLE_ADMIN","ROLE_SUPER_ADMIN"]' WHERE username = 'xxx'; - Page :
/audit-logs(lien "Journal" dans la sidebar, visible uniquement avec le rôle)
Actions tracées
| Processor | Entité | Actions |
|---|---|---|
AbsenceWriteProcessor |
Absence | create, delete |
WorkHourBulkUpsertProcessor |
WorkHour | create, update, delete |
WorkHourSiteValidationProcessor |
WorkHour | site_validate |
WorkHourBulkValidationProcessor |
WorkHour | validate |
WorkHourBulkSiteValidationProcessor |
WorkHour | site_validate |
EmployeeWriteProcessor |
Employee | create, update (changement contrat) |
ContractSuspensionWriteProcessor |
ContractSuspension | create, update |
EmployeeRttPaymentProcessor |
EmployeeRttPayment | update |
EmployeeFractionedDaysProcessor |
EmployeeLeaveBalance | update |
Données stockées
Chaque entrée contient :
- employee : l'employé concerné (FK, nullable)
- username : l'utilisateur qui a effectué l'action
- action : type d'action (create, update, delete, validate, site_validate)
- entityType : type d'entité (work_hour, absence, employee, etc.)
- description : description lisible en français
- changes : diff JSON
{old: {...}, new: {...}}avec les anciennes/nouvelles valeurs - affectedDate : date de travail ou début d'absence (pour filtrage par période)
- createdAt : horodatage de l'action
ipAddress: IP source de la requête (Request::getClientIp()) — nécessiteframework.trusted_proxiesderrière un reverse proxy, sinon IP du proxyuserAgent: User-Agent brut de la requêtedeviceLabel: libellé lisible dérivé du User-Agent (Type · OS · Navigateur, ex.Mobile · Android · Chrome), viaApp\Service\UserAgentParserdeviceId: identifiant d'appareil persistant envoyé par le front (headerX-Device-Id, stocké enlocalStorage['sirh-device-id']). Distingue les appareils derrière un compte partagé (ex. « Usine »), pas les personnes.
Capture : automatique et centralisée dans AuditLogger::log() (via RequestStack) — aucun processor à modifier. En contexte CLI/cron (pas de requête), ces 4 champs restent null.
⚠️ CORS : le front et l'API sont sur des origines distinctes ; le header
X-Device-Idajouté à chaque requête déclenche un préflight CORS. Il doit figurer dansnelmio_cors.allow_headers(config/packages/nelmio_cors.yaml), sinon le navigateur bloque toutes les requêtes API.
Filtres disponibles
- Par employé
- Par plage de dates (date affectée)
- Par type d'entité
Pagination
Les résultats sont paginés par 50 entrées. L'API retourne {items, total, page, perPage} et accepte un query param page.
Convention
Tout nouveau processor traitant des entités impactant les calculs (heures, absences, contrats, RTT)
doit intégrer le service AuditLogger et logger les actions create/update/delete.