Cas QR-012 : Approbation de régularisation (Responsable + RH)¶
Module : qr-attendance Tranche : QR-T4-001 (partiel : approuver/refuser/passer outre) Contexte de marque : [LES DEUX] Papillon HR Suite + ALTARYS ENTERPRISE HR Suite Priorité : 12 Dépend de : QR-011 (les demandes de régularisation existent) Peut être développé en parallèle avec : QR-015 Ordre de fusion : Avant QR-013, QR-017 Complexité estimée : M PRD User Stories : US-QR-005
Objectif¶
Mettre en œuvre le workflow d'approbation des demandes de régularisation : les responsables peuvent approuver ou rejeter les demandes de leurs subordonnés directs, les RH peuvent approuver/rejeter toute demande et passer outre les régularisations approuvées par les responsables. Une fois approuvée, l'enregistrement DailyAttendance correspondant est recalculé à l'aide des horaires corrigés tout en conservant les événements d'horloge d'origine à des fins d'audit. Cela achève le cycle de vie de la régularisation commencé dans QR-011.
Portée du backend¶
Entités et enregistrements¶
Aucune nouvelle table. Étend RegularizationRequest de QR-011.
Migrations Flyway¶
Aucune.
Couche de référentiel¶
Pas de nouveaux repositories. Utilise le RegularizationRepository existant.
Couche de service¶
Étend RegularizationService :
approve(id, approverId) :
- Valide : la demande est en attente (PENDING), l'approbateur dispose de l'autorité nécessaire (responsable pour les subordonnés directs, RH pour tous les autres)
- Définit status=APPROVED, approvedBy, approvedAt
- Appelle DailyAttendanceService.recalculateForRegularization(regularization) :
- Utilise les heures d'arrivée et de départ corrigées
- Recalcule : workedMinutes, scheduledMinutes, overtimeMinutes, lateMinutes, earlyDepartureMinutes
- Événements d'horloge d'origine CONSERVÉS — la régularisation est additive
- En cas de correction d'un pointage de sortie manqué et clôturé automatiquement (QR-010) : les heures supplémentaires peuvent désormais être créditées
- Si la semaine du jour concerné dispose d'un WeeklyOvertimeSummary, marquer pour reclassification
- Définit DailyAttendance.regularizationId
- Informe l'employé
reject(id, rejecterId, reason) :
- Définit status=REJECTED
- Informe l'employé en indiquant le motif
override(id, hrId) :
- Réservé aux RH. Remplace une régularisation précédemment approuvée par le responsable.
- Crée une nouvelle RegularizationRequest avec overrideOf pointant vers l'originale
- Rétablit le calcul des événements de pointage d'origine dans DailyAttendance
- Informe le responsable et l'employé
Matrice des autorisations¶
| Role | Approve/Reject | Override | Scope |
|---|---|---|---|
| Manager | Yes | No | Direct reports only (CachedEmployeeData.currentManagerId == authenticatedUserId) |
| HR | Yes | Yes | Any employee |
| ### Endpoints de l'API |
| Method | Path | Request Body | Response | Auth |
|---|---|---|---|---|
| POST | /api/v1/qrcontr/regularizations/{id}/approve |
— | ApiResponse<RegularizationResponse> |
Manager (team), HR |
| POST | /api/v1/qrcontr/regularizations/{id}/reject |
{reason: string} |
ApiResponse<RegularizationResponse> |
Manager (team), HR |
| POST | /api/v1/qrcontr/regularizations/{id}/override |
— | ApiResponse<RegularizationResponse> |
HR (P2) |
| ### Règles de validation |
- Approuver/refuser uniquement les demandes en attente
- Remplacer uniquement les demandes approuvées (réservé aux RH)
- Le responsable ne peut intervenir que pour ses subordonnés directs
- Le verrouillage optimiste via le champ « version » empêche les approbations simultanées (erreur 409 - Conflit)
- Le motif de refus est obligatoire
Considérations relatives à la multi-tenant¶
Toutes les requêtes sont filtrées par tenant_id. Les vérifications d'autorisation utilisent les données des employés au niveau de la location. Les événements de notification incluent le contexte de la location.
Portée du frontend¶
Composants¶
ApprovalPage
(maquette de spécifications de conception 3.8) :
- Liste des demandes en attente (onglet « Régularisations »)
ApprovalCard
:
- Nom de l'employé, type, date, motif, heures corrigées
- Bouton Approuver (vert) + Bouton Rejeter (rouge)
- Nombre de badges dans la navigation
RejectReasonDialog
:
- Fenêtre contextuelle pour la saisie du motif de rejet
OverrideDialog
:
- Confirmation RH : « Cette régularisation a été approuvée par {manager}. Souhaitez-vous l'annuler ? »
États de l'interface utilisateur¶
| State | Behavior | French Copy |
|---|---|---|
| Loading | Skeleton cards | — |
| Empty | Celebration illustration | "Aucune demande en attente" |
| Error | Inline retry | "Impossible de charger les demandes. Reessayez." |
| Offline | Cached requests, approve/reject queued | "Actions sauvegardees — seront synchronisees." |
| Success (approve) | Green flash -> card slides out left (300ms) | "Regularisation approuvee." |
| Success (reject) | Red flash -> card slides out (300ms) | "Regularisation refusee." |
Comportement adaptatif¶
- 360px : cartes d'approbation empilées sur toute la largeur. Balayage vers la droite = approuver (traînée verte), balayage vers la gauche = rejeter (traînée rouge, justifiant requis)
- 768px : grille de cartes d'approbation sur deux colonnes
- 1024px+ : vue en tableau avec approbation groupée (Enterprise), panneau de détails latéral
Interactions¶
- Balayage vers la droite sur la carte (mobile) : approbation rapide (animation de traînée verte)
- Balayage vers la gauche : rejet rapide -> justifiant requis dans une fenêtre contextuelle
- Annulation : notification avec fenêtre d'annulation de 5 secondes après l'action. « Action annulée » lors de l'annulation.
- Le nombre de badges diminue lors de l'approbation/du rejet
Critères d'acceptation¶
```gherkin AC-001: Manager sees only direct reports' requests Given I am a manager When I view pending regularizations Then I see only requests from my direct reports
AC-002: HR sees all pending requests Given I am HR When I view pending regularizations Then I see all pending requests across the company
AC-003: Approval recalculates attendance Given I approve a regularization When the system processes it Then the attendance record for that day is updated in display/calculation (original record preserved for audit)
AC-004: HR override of manager approval Given I am HR When I see a manager-approved regularization that is incorrect Then I can override/reject it ```---
OHADA et règles réglementaires¶
- FR-QR-064 : toutes les actions (approbation, rejet, annulation) sont consignées dans la piste d'audit
- Les événements horodatés d'origine ne sont JAMAIS modifiés — les régularisations s'ajoutent (ADR-10)
- Le verrouillage optimiste via le champ de version empêche les approbations simultanées (erreur 409 - Conflit)
Normes et conventions¶
docs/standards/java-Spring-guidelines.mddocs/standards/api-guidelines.mddocs/standards/react-typescript-guidelines.mddocs/standards/offline-sync-guidelines.md
Exigences en matière de tests¶
Tests unitaires¶
- Vérification des autorisations : un responsable peut approuver un subordonné direct, mais ne peut pas approuver une personne qui ne lui est pas subordonnée ; les RH peuvent approuver n'importe qui
- Recalcul de
DailyAttendanceavec les heures corrigées :workedMinutes,overtimeMinutesetlateMinutesmis à jour - Logique de remplacement : nouvelle requête créée avec
overrideOf, DA d'origine rétablie - Motif de rejet obligatoire
- Verrouillage optimiste : une approbation simultanée renvoie un code 409
Tests d'intégration¶
- POST
/regularizations/{id}/approve-> 200 + DA recalculé - POST
/regularizations/{id}/rejectavec motif -> 200 - POST
/regularizations/{id}/overrideen tant que RH -> 200 - Le responsable approuve un subordonné qui ne lui est pas rattaché -> 403
- Approuver une demande déjà approuvée -> 409 ou 400
- Isolation des tenants : les demandes du tenant A ne peuvent pas être approuvées par les utilisateurs du tenant B
Ce que l'assurance qualité va valider¶
- Flux d'approbation/de rejet sur mobile (gestes de balayage)
- Vérifier que le registre de présence est mis à jour après l'approbation
- Vérifier la boîte de dialogue de remplacement et la réinitialisation de la DA
- Tester l'annulation dans un délai de 5 secondes
- Vérifier que le nombre de badges est mis à jour lors de l'approbation/du rejet
Hors du périmètre¶
- Régularisation par création directe RH (QR-013)
- Approbation par lots (Enterprise V2)
- Mise en œuvre de la livraison des notifications (événement de publication uniquement)
Définition de « terminé »¶
- [ ] Tous les endpoints d'approbation/rejet/contournement implémentés
- [ ] DailyAttendance recalculé lors de l'approbation
- [ ] Page d'approbation avec actions de balayage sur mobile
- [ ] Tous les états de l'interface utilisateur implémentés (chargement, vide, erreur, hors ligne, approbation réussie, rejet réussi)
- [ ] Les micro-textes en français correspondent aux spécifications de conception
- [ ] Tous les critères d'acceptation sont satisfaits manuellement
- [ ] Tests unitaires et tests d'intégration réussis
- [ ] Isolation multi-tenant vérifiée
- [ ] Hors ligne : approbations/rejets mis en file d'attente pour la synchronisation
- [ ] Pas de
anyen TypeScript, pas de types bruts en Java - [ ] Entrées de piste d'audit pour toutes les actions d'approbation
- [ ]
./gradlew testest vert - [ ]
./gradlew spotlessApplyréussit