39cdfd7428
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
66 lines
3.4 KiB
Markdown
66 lines
3.4 KiB
Markdown
# 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
|
|
```sql
|
|
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écessite `framework.trusted_proxies` derrière un reverse proxy, sinon IP du proxy
|
|
- `userAgent` : User-Agent brut de la requête
|
|
- `deviceLabel` : libellé lisible dérivé du User-Agent (`Type · OS · Navigateur`, ex. `Mobile · Android · Chrome`), via `App\Service\UserAgentParser`
|
|
- `deviceId` : identifiant d'appareil persistant envoyé par le front (header `X-Device-Id`, stocké en `localStorage['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-Id` ajouté à chaque requête déclenche un préflight CORS. Il **doit** figurer dans `nelmio_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.
|