docs : note Lundi de Pentecôte traité comme jour ouvré (choix délibéré)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-24 15:48:04 +02:00
parent 5e2c6c219b
commit d201489bcb
2 changed files with 8 additions and 1 deletions
+1 -1
View File
@@ -214,7 +214,7 @@
## Notifications
- Système : entité `Notification` (table `notifications`, `recipient`/`actor`/`message`/`category`/`target`/`isRead`), cloche **admin-only** dans `AppTopNav.vue`, providers `/notifications/{unread,today,history}` + `POST /notifications/mark-all-read`. Création historique : `WorkHourSiteValidationProcessor` (1 notif/admin via `UserRepository::findAllAdmins`).
- **Fin de contrat (J-1 ouvré)** : commande cron quotidienne `app:contract:end-notifications` (crontab prod, ~6h ; option `--date`). Notifie les admins sur le **dernier jour ouvré avant** `endDate` (inclusif) de la **dernière** période d'un employé (changement de contrat enchaîné exclu). Week-ends + fériés sautés (`WorkingDayCalculator`). Fenêtre couverte un jour J = `]J ; prochain_jour_ouvré(J)]`. Message « Fin de {nature} de {Nom} le {date} », catégorie `Contrat`, target `/employees/{id}`, acteur null. Idempotent (`NotificationRepository::existsForRecipientCategoryTargetMessage`). Logique pure testée : `ContractEndNotificationPlanner` + `WorkingDayCalculator`. Front : `AppTopNav.vue` masque le span acteur si `actorName` vide. Doc : `doc/contract-end-notifications.md`.
- **Fin de contrat (J-1 ouvré)** : commande cron quotidienne `app:contract:end-notifications` (crontab prod, ~6h ; option `--date`). Notifie les admins sur le **dernier jour ouvré avant** `endDate` (inclusif) de la **dernière** période d'un employé (changement de contrat enchaîné exclu). Week-ends + fériés sautés (`WorkingDayCalculator`, via `getHolidaysDayByYears` → applique `EXCLUDED_PUBLIC_HOLIDAYS`, donc **Lundi de Pentecôte traité comme jour ouvré**, cohérent avec le reste de l'app). Fenêtre couverte un jour J = `]J ; prochain_jour_ouvré(J)]`. Message « Fin de {nature} de {Nom} le {date} », catégorie `Contrat`, target `/employees/{id}`, acteur null. Idempotent (`NotificationRepository::existsForRecipientCategoryTargetMessage`). Logique pure testée : `ContractEndNotificationPlanner` + `WorkingDayCalculator`. Front : `AppTopNav.vue` masque le span acteur si `actorName` vide. Doc : `doc/contract-end-notifications.md`.
## Backend Conventions
- Prefer explicit DTOs over associative arrays