Rapport QR-010 : Anomalies du tableau de bord + Lot de clôtures automatiques +¶
@assignee: @m-kouassi
Module de périmètre de gestion : qr-attendance Tranche : QR-T3-002 + QR-T3-004 + US-QR-010 (autres AC) Contexte de la marque : [LES DEUX] Papillon HR Suite + ALTARYS ENTERPRISE HR Suite Priorité : 10 Dépend de : QR-009 (tableau de bord de base) Peut être développé en parallèle avec : Aucun (prolonge QR-009) Ordre de fusion : Après QR-009 Complexité estimée : M PRD User Stories : US-QR-002 (AC-002), US-QR-010 (AC-003, AC-004)
Objectif¶
Étendre le tableau de bord des présences quotidiennes avec trois fonctionnalités : - (1) une tâche batch de fermeture automatique qui crée des événements de pointage de sortie synthétiques pour les employés qui oublient de pointer leur sortie, - (2) la détection d'anomalies sur les appareils partagés qui signale lorsque plusieurs employés utilisent le même appareil, - et (3) un filtrage par périmètre de gestion afin que les managers ne voient que leurs subordonnés directs. Ces fonctionnalités complètent la préparation opérationnelle du tableau de bord pour les workflows RH quotidiens.
Portée du backend¶
Entités et enregistrements¶
Aucune nouvelle table. Extension du tableau de bord et ajout de tâches batch.
Migrations Flyway¶
Aucune.
Couche de référentiel¶
Aucun nouveau repository. Extension des requêtes existantes.
Couche de service¶
AutoCloseService + AutoCloseScheduledJob :
- Tâche quotidienne @Scheduled à une heure configurable (par défaut 23 h 59 à partir de AttendanceModuleConfig.autoCloseTime)
- Parcourt les tenants actifs dont le module QRCONTR est activé
- Pour chaque employé ayant une pointe d'arrivée ouverte (IN sans OUT) dont l'heure de fin prévue est dépassée :
- Créer une sortie synthétique à l'heure de fin prévue, source=SYSTEM, autoCloseReason="MISSED_CLOCK_OUT"
- Définir DailyAttendance.isAutoClosed=true, AUCUNE heure supplémentaire créditée
- Indicateur : « Pointage incomplet (fermeture automatique) »
- Si l'employé n'a pas d'horaire : NE PAS fermer automatiquement, signaler « Pointage incomplet — pas d'horaire configuré », régularisation manuelle requise
SharedDeviceDetector :
- Vérification : si 2 employés différents ou plus ont des événements de pointage avec le même deviceIdHash le même jour -> générer une anomalie
- Ajouter au JSONB DailyAttendance.anomalyDetails : {"type":"SHARED_DEVICE","employeeIds":["uuid1","uuid2"],"details":"Appareil partagé avec [name]"}
- Définir hasAnomaly=true
- Événements de pointage NON rejetés — indicateur informatif uniquement
Étendre DashboardService :
- Ajouter la liste des anomalies à la réponse du tableau de bord
- Ajouter la liste autoClosedYesterday (consolidée pour la revue matinale des RH)
- Portée du responsable : filtrer les employeeIds par managerId à partir de CachedEmployeeData.currentManagerId
Endpoints API¶
Mêmes endpoints que QR-009, réponses étendues :
| Method | Path | Changes |
|---|---|---|
| GET | /api/v1/qrcontr/attendance/today |
DashboardResponse now includes anomalies and autoClosedYesterday |
| GET | /api/v1/qrcontr/attendance/daily |
Same extensions |
DashboardResponse
comprend désormais :
- anomalies (ListautoClosedYesterday (List
Filtre « Manager » : lorsque le rôle de l'utilisateur authentifié est MANAGER, le filtrage s'applique automatiquement aux seuls subordonnés directs.
Règles de validation¶
- Fermeture automatique uniquement pour les employés ayant un horaire configuré
- La détection des appareils partagés est purement informative — aucun événement n'est rejeté
- La portée du gestionnaire est appliquée côté serveur en fonction du contexte d'authentification
Considérations multi-tenant¶
Le lot de fermeture automatique itère les tenants individuellement. La détection des appareils partagés s'applique au niveau du tenant (un même deviceIdHash chez différents tenants ne constitue pas une anomalie).
Portée du frontend¶
Étend DashboardPage de QR-009.
Composants à ajouter/étendre¶
AnomalyBadge
:
- Badge coloré sur la ligne de l'employé (appuyer pour afficher les détails)
- Types : SHARED_DEVICE (avertissement), AUTO_CLOSED (horloge), NO_SCHEDULE (calendrier)
AnomalyDetailPanel
:
- Déploiement en ligne (animation de hauteur de 200 ms) affichant les détails de l'anomalie
AutoClosedList
:
- Section en haut du tableau de bord affichant les enregistrements fermés automatiquement hier
Étendre EmployeeAttendanceRow
:
- Ajouter la prise en charge des badges d'anomalie, icône différente pour les enregistrements fermés automatiquement
États de l'interface utilisateur¶
| State | Behavior | French Copy |
|---|---|---|
| Anomaly badge | Colored badge on employee row, tappable | "Alerte : appareil partage" / "Pointage incomplet (fermeture automatique)" |
| Manager view | Filtered to team only, no team selector | Header shows "Mon equipe" |
| Auto-closed list | Highlighted section at top | "Fermetures automatiques d'hier" |
Comportement adaptatif¶
- 360px : les badges d'anomalie s'affichent sous forme de petites icônes ; appuyer pour les développer en ligne. La liste à fermeture automatique s'affiche sous forme d'accordéon repliable.
- 768px : badges avec un texte court ; la liste à fermeture automatique est visible par défaut.
- 1024px+ : détails complets de l'anomalie visibles ; la liste à fermeture automatique s'affiche sous forme de tableau.
Interactions¶
- Appui sur le badge d'anomalie : affichage en ligne avec les détails (200 ms)
- Balayage vers la gauche sur la ligne de l'employé (mobile, RH uniquement) : affiche l'action rapide « Régularisation directe » (renvoie vers QR-013)
- Badge du responsable dans l'en-tête pour indiquer la portée de l'équipe
Critères d'acceptation¶
```gherkin AC-001: Missed clock-out auto-close Given I forget to clock out When my scheduled end time passes Then the system auto-closes my record at the scheduled end time, flags it as SYSTEM-generated, and does NOT credit overtime
AC-002: Anomaly visual flagging on dashboard Given an anomaly exists (incomplete record, shared device alert) When I view the dashboard Then the anomaly is visually flagged with a colored badge
AC-003: Manager team-only view Given I am a manager When I view the dashboard Then I see only my team's data (direct reports) ```---
OHADA et règles réglementaires¶
- La fermeture automatique NE génère PAS d'heures supplémentaires (mesure de protection pour l'employeur — évite les heures supplémentaires fantômes dues à des pointages de sortie oubliés)
- Les événements de pointage d'origine sont conservés, les événements synthétiques sont marqués
source=SYSTEM(piste d'audit immuable, ADR-10) - La détection des appareils partagés est purement informative (FR-QR-092) — les événements ne sont pas rejetés
Normes et conventions¶
docs/standards/java-Spring-guidelines.md— modèles@Scheduled, tâche batch avec itération par tenantdocs/standards/api-guidelines.mddocs/standards/react-typescript-guidelines.md
Exigences de test¶
Tests unitaires¶
AutoCloseService: fin programmée dépassée -> événement synthétique créé, pas de programmation -> pas de fermeture automatique + indicateur, pas d'heures supplémentaires créditées lors de la fermeture automatique, déjà fermé -> aucune actionSharedDeviceDetector: même appareil, employés différents -> anomalie créée, même appareil, même employé -> pas d'anomalie, appareils différents -> pas d'anomalie- Filtrage par périmètre de gestion : le responsable ne voit que ses subordonnés directs, les RH voient tout
Tests d'intégration¶
- Exécuter la tâche de fermeture automatique, vérifier que des événements de pointage de sortie synthétiques sont créés avec
source=SYSTEM - Vérifier
isAutoClosed=truesurDailyAttendance - Vérifier que l'anomalie apparaît dans la réponse du tableau de bord
- Vérifier que la requête GET du responsable
/attendance/todayrenvoie uniquement les subordonnés directs - La requête GET des RH
/attendance/todayrenvoie tous les employés - Isolation des locataires : la tâche de fermeture automatique traite les locataires indépendamment
- Vérifier les badges d'anomalie sur le tableau de bord (appareil partagé, fermeture automatique)
- Vérifier que le responsable ne voit que les données de son équipe
- Vérifier que la liste des fermetures automatiques apparaît en haut du tableau de bord le lendemain matin
- Appuyer sur le badge d'anomalie, vérifier l'affichage des détails
Hors du périmètre¶
- Régularisation pour corriger les enregistrements de fermeture automatique (QR-012)
- Détection des absences (déjà dans QR-009)
- Exportation du tableau de bord (QR-017)
Définition de « Terminé »¶
- [ ] Le traitement par lots de fermeture automatique s'exécute correctement et crée des événements synthétiques
- [ ] La détection des appareils partagés génère des entrées d'anomalie
- [ ] Le filtrage par périmètre du responsable fonctionne pour le tableau de bord
- [ ] Les badges d'anomalie s'affichent sur le tableau de bord avec les icônes et les couleurs correctes
- [ ] Tous les critères d'acceptation sont satisfaits manuellement
- [ ] Les tests unitaires et les tests d'intégration sont réussis
- [ ] L'isolation multi-tenant est vérifiée
- [ ] Pas de
anyen TypeScript, pas de types bruts en Java - [ ] Entrées de piste d'audit pour les événements de fermeture automatique
- [ ]
./gradlew testest vert - [ ]
./gradlew spotlessApplyréussit