diff --git a/AGENTS.md b/AGENTS.md
index b277fe9..02f1a16 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -1,6 +1,6 @@
# AGENTS.md
-État des lieux opérationnel du projet SIRH (backend + frontend), à utiliser comme base sur les prochaines interventions.
+État des lieux opérationnel du projet SIRH (backend + frontend), mis à jour après les évolutions sur heures/absences/validations.
## 1) Stack et structure
@@ -25,81 +25,107 @@ Arborescence clé:
### Contrats
- Entité: `Contract`
-- Champs principaux: `name`, `trackingMode`, `weeklyHours`, `isActive`
+- Champs principaux: `name`, `trackingMode`, `weeklyHours`, `isActive`, `type`
- `trackingMode`:
- - `TIME`: suivi par heures
- - `PRESENCE`: suivi présence demi-journées/journées
+ - `TIME`: suivi en heures
+ - `PRESENCE`: suivi en demi-journées/journées
- Enums backend:
- `App\Enum\TrackingMode`
- - `App\Enum\ContractType` (`FORFAIT`, `35H`, `39H`, `INTERIM`, `CUSTOM`)
-- `Contract::getType()` est exposé en API (`contract:read`, `employee:read`)
+ - `App\Enum\ContractType` (`FORFAIT`, `THIRTY_FIVE_HOURS`, `THIRTY_NINE_HOURS`, `INTERIM`, `CUSTOM`)
+- Historique de contrat par employé:
+ - table `employee_contract_periods`
+ - résolu par `App\Service\Contracts\EmployeeContractResolver`
### Heures / absences
-- Les absences sont découpées en enregistrements journaliers (pas de période unique stockée).
-- Une ligne d’heures validée est verrouillée côté métier.
-- Règles de crédit absence (`countAsWorkedHours=true`) gérées dans `WorkedHoursCreditPolicy`:
- - contrats présence: crédit en unités de présence
- - contrats temps: crédit en minutes selon règles contrat (35h, 39h, 4h, fallback)
+- Les absences sont stockées en **lignes journalières** (découpage automatique dans `AbsenceWriteProcessor`).
+- Les absences `countAsWorkedHours=true` créditent:
+ - minutes (contrats TIME)
+ - unités de présence (contrats PRESENCE)
+- Les absences AM/PM effacent les plages horaires concernées.
-## 4) Écrans principaux
+## 4) Validations (important)
-### Page Heures (`frontend/pages/hours.vue`)
-- Vue Jour + Vue Semaine (semaine réservée admin)
-- Toolbar dédiée: `frontend/components/hours/HoursToolbar.vue`
-- Vue jour: `frontend/components/hours/HoursDayView.vue`
-- Vue semaine: `frontend/components/hours/HoursWeekView.vue`
-- Logique page: `frontend/composables/useHoursPage.ts`
+### Validation RH (admin)
+- Champ: `work_hours.is_valid`
+- Endpoint API Platform standard: `PATCH /api/work_hours/{id}`
+- Gérée côté front par `updateWorkHourValidation`.
-### Points UX déjà en place
-- Toolbar semaine: raccourcis semaine précédente / actuelle / suivante
-- Légende absences affichée dans la toolbar (admin + vue semaine)
-- Cellules semaine avec absence: couleur du type d’absence (plus rouge fixe)
-- Pour user non-admin: restrictions d’édition selon validations/absences
+### Validation site (chef de site)
+- Champ: `work_hours.is_site_valid`
+- Endpoint dédié: `PATCH /api/work_hours/{id}/site-validation`
+- Processor: `src/State/WorkHourSiteValidationProcessor.php`
+- Autorisé uniquement aux utilisateurs "Sites" (ni `ROLE_ADMIN`, ni `ROLE_SELF`) dans leur scope site.
-## 5) API / calculs hebdo
+### Règles de verrouillage
+- `is_valid=true`: ligne verrouillée pour tout le monde (admin inclus pour saisie heures/absence; peut toujours décocher validation RH).
+- `is_site_valid=true`:
+ - non-admin: ligne verrouillée (heures + absences)
+ - admin: ligne éditable
+- Toute modification de ligne (heures/présence/absence) remet:
+ - `is_site_valid=false`
+ - `is_valid=false`
+
+## 5) Page Heures (front)
+
+- Page: `frontend/pages/hours.vue`
+- Composable principal: `frontend/composables/useHoursPage.ts`
+- Composants:
+ - `frontend/components/hours/HoursToolbar.vue`
+ - `frontend/components/hours/HoursDayView.vue`
+ - `frontend/components/hours/HoursWeekView.vue`
+
+### Comportement par profil (vue jour)
+- Admin:
+ - colonne RH avec checkbox
+ - badge `Site validé` affiché près du site
+- Chef de site:
+ - colonne `Validation site` avec checkbox
+ - colonne RH en lecture (`Validé`/`-`)
+- Employé:
+ - colonne `Validation site` en lecture
+ - colonne RH en lecture
+
+## 6) Résumé hebdo / calculs
- Provider: `src/State/WorkHourWeeklySummaryProvider.php`
- DTOs:
- `src/Dto/WorkHours/WeeklySummaryRow.php`
- `src/Dto/WorkHours/WeeklyDaySummary.php`
-- Le résumé hebdo renvoie notamment:
- - `trackingMode`
- - `contractName`
- - `contractType`
- - détails journaliers (jour/nuit/total, présence, absence label/couleur)
+- Inclut: contrat résolu par jour, absences, crédits, jour/nuit/total, majorations, récup.
-### Heures supp
-- Règles métier:
- - contrats <= 35h: tranche 25% de 35h à 43h, puis 50% au-delà
- - contrats >= 39h: tranche 25% de 39h à 43h, puis 50% au-delà
- - contrats `INTERIM`: pas de bonus 25/50 ni récup
+Règles majorations:
+- Contrats <= 35h: +25% de 35h à 43h, +50% au-delà
+- Contrats >= 39h: +25% de 39h à 43h, +50% au-delà
+- `INTERIM`: pas de 25% / 50% / récup
-## 6) Conventions techniques
+## 7) Migrations sensibles
-- Favoriser DTO explicites plutôt que tableaux associatifs bruts.
-- Utiliser les interfaces repository dans providers/processors testés.
-- Centraliser les règles métier dans services/providers backend plutôt que dupliquer côté front.
-- Front: éviter les calculs métier lourds; consommer les champs API déjà calculés.
+- `migrations/Version20260226183000.php`
+ - ajoute `work_hours.is_site_valid BOOLEAN NOT NULL DEFAULT FALSE`
+ - non destructive (pas de perte de données)
-## 7) Tests et qualité
+## 8) Points de vigilance prod
-- Les TU backend passent actuellement via `make test`.
-- Le build frontend passe via `npm run build`.
-- À chaque évolution métier:
- - mettre à jour les tests provider/processor/service impactés
- - maintenir la cohérence des DTO TypeScript (`frontend/services/dto/*`)
+- Toujours exécuter migration avant déploiement code backend/front lié.
+- Après déploiement backend, si route manquante côté runtime:
+ - `php bin/console cache:clear && php bin/console cache:warmup`
+- Vérifier présence route:
+ - `/api/work_hours/{id}/site-validation` (PATCH)
-## 8) Fichiers sensibles (à lire avant modif)
+## 9) Conventions techniques
+- Favoriser DTO explicites plutôt que tableaux associatifs.
+- Garder règles métier dans backend (providers/processors/services), front orienté affichage/interaction.
+- Maintenir alignement backend DTO PHP / frontend DTO TS (`frontend/services/dto/*`).
+- Mettre à jour TU si signature constructor/service change.
+
+## 10) Fichiers à lire avant modification
+
+- `src/State/WorkHourBulkUpsertProcessor.php`
+- `src/State/AbsenceWriteProcessor.php`
+- `src/State/WorkHourSiteValidationProcessor.php`
- `src/State/WorkHourWeeklySummaryProvider.php`
- `src/Service/WorkHours/WorkedHoursCreditPolicy.php`
-- `src/State/AbsenceWriteProcessor.php`
-- `src/State/WorkHourBulkUpsertProcessor.php`
- `frontend/composables/useHoursPage.ts`
+- `frontend/components/hours/HoursDayView.vue`
- `frontend/components/hours/HoursWeekView.vue`
-
-## 9) Décisions de conception actuelles
-
-- Les absences sont stockées par jour (facilite verrouillage/édition fine).
-- Les règles de calcul (crédits, majorations, récup) sont portées côté backend.
-- Le front reste centré sur l’affichage/interaction et réutilise les données enrichies de l’API.
diff --git a/frontend/components/AbsencePrintDrawer.vue b/frontend/components/AbsencePrintDrawer.vue
index c4729dd..0685439 100644
--- a/frontend/components/AbsencePrintDrawer.vue
+++ b/frontend/components/AbsencePrintDrawer.vue
@@ -54,6 +54,48 @@
+
+
+ Type de contrat *
+
+
+
+
+
+
+
+
+ Sélectionne au moins un type de contrat.
+
+
+
+
+
+ Temps de travail *
+
+
+
+
+
+
+
+
+ Sélectionne au moins un temps de travail.
+
+
+
-
-
+
+ :style="getRowAbsenceStyle(employee.id)"
+ >
{{ getRowAbsenceLabel(employee.id) || '—' }}
-
+