Aller au contenu

Story QR-016 : Historique des présences des employés

Module : qr-attendance Tranche : QR-T5-001 (vue employé) + US-QR-003 Contexte de la marque : [LES DEUX] Papillon HR Suite + ALTARYS ENTERPRISE HR Suite Priorité : 16 Dépend de : QR-006 (événements de pointage + DailyAttendance) Peut être développé en parallèle avec : QR-011, QR-014 Ordre de fusion : N'importe quel ordre par rapport aux pairs Complexité estimée : M PRD User Stories : US-QR-003


Objectif

Créer la page d'historique des présences des employés, offrant une vue mensuelle de tous les événements d'horodatage, des enregistrements de présence quotidiens et des statistiques récapitulatives. Les employés peuvent consulter leur propre historique mois par mois, voir les heures détaillées d'arrivée et de départ, les statuts (retard, absent, régularisé) et une ligne récapitulative avec les totaux. La page sert à la fois d'outil de transparence pour les employés et de point d'entrée pour les demandes de régularisation concernant les jours anormaux.


Portée du backend

Entités et enregistrements

Aucune nouvelle table. Utilise les tables existantes Clock et DailyAttendance.

Migrations Flyway

Aucune.

Couche de référentiel

Pas de nouveaux référentiels. Étend les requêtes existantes sur DailyAttendance et Clock.

Couche de service

AttendanceHistoryService : - getEmployeeHistory(tenantId, employeeId, month) : - Récupère tous les enregistrements DailyAttendance de l'employé pour le mois donné - Récupère tous les enregistrements Clock pour chaque jour - Calcule le récapitulatif : totalWorkedHours, totalOvertime, totalLateCount, totalLateMinutes, totalAbsences, totalTeletravailDays - Renvoie une réponse structurée comprenant le récapitulatif et les enregistrements journaliers

Endpoints API

Method Path Request Body Response Auth
GET /api/v1/qrcontr/attendance/me ?month=2026-03&dateFrom=&dateTo= ApiResponse<EmployeeAttendanceHistoryResponse> Employee (P4)
GET /api/v1/qrcontr/employees/{employeeId}/attendance ?month=&dateFrom=&dateTo= ApiResponse<EmployeeAttendanceHistoryResponse> HR, Manager (team), Employee (own)
### DTO

EmployeeAttendanceHistoryResponse : - summary (MonthlySummary) : - totalWorkedHours (BigDecimal) - totalOvertime (BigDecimal) - totalLateCount (int) - totalLateMinutes (int) - totalAbsences (int) - totalTeletravailDays (int) - days (List): - date (LocalDate) - dayOfWeek (String) - clockIn (LocalTime, nullable) - clockOut (LocalTime, nullable) - minutesTravaillées (int) - statut (String) - minutesDeRetard (int) - minutesDeDépartAnticipé (int) - anomalies (List) - aRégularisation (boolean)

Règles de validation

  • Format month : AAAA-MM (valeur par défaut : mois en cours si non fourni)
  • dateFrom/dateTo remplacent month s'ils sont fournis
  • L'employé ne peut accéder qu'à son propre historique via l'endpoint /me
  • Le responsable peut accéder aux membres de son équipe via l'endpoint /{employeeId}
  • Les RH peuvent accéder à n'importe quel employé

Considérations multi-tenant

Toutes les requêtes sont filtrées par tenant_id. L'employé ne voit que ses propres données. Le responsable voit son équipe. Les RH voient tout ce qui se trouve au sein du tenant.


Portée du frontend

Pages et routes

  • /qrcontr/history — Historique de présence de l'employé (onglet « Historique »)

Composants

HistoryPage (maquette fonctionnelle 3.5) : - Sélecteur de mois + fiches récapitulatives + mise en page sous forme de liste quotidienne

MonthPicker : - Sélecteur de mois/année avec flèches gauche/droite - Gesture de balayage sur mobile pour la navigation entre les mois

MonthlySummary : - Grille 2x3 de fiches récapitulatives : - Travail (heures travaillées) - Retards (nombre de retards) - H. Supp. (heures supplémentaires) - Absences (nombre d'absences) - Télétroi (nombre de jours de télétravail) - Assiduité (taux de présence %)

DayHistoryCard : - Date, heures d'arrivée/de départ, heures travaillées, badge de statut - En cas d'absence : bouton d'action « Demander une régularisation » (renvoie vers QR-011) - En cas de retard : badge de statut orange avec la mention « (15 min) » - En cas de régularisation : badge « Régulariser » (vert) - Appuyer pour développer : affiche tous les événements de pointage de la journée (paires ENTRÉE/SORTIE)

États de l'interface utilisateur

State Behavior French Copy
Loading Skeleton summary cards + skeleton day rows
Empty No attendance data for selected month "Aucun pointage pour ce mois."
Error Inline error + retry "Impossible de charger l'historique. Reessayez."
Offline Cached data from last sync "Donnees hors ligne — derniere synchronisation : {datetime}"
Success Summary cards + day list rendered

Comportement adaptatif

  • 360px : fiches récapitulatives empilées (2 par ligne), fiches journalières en pleine largeur
  • 768px : fiches récapitulatives (3 par ligne), fiches journalières avec plus de détails
  • 1024px+ : barre latérale récapitulative + tableau journalier défilable

Interactions

  • Sélecteur de mois : flèches gauche/droite, balayage sur mobile
  • Appui sur la carte journalière : déplier pour afficher tous les événements horaires de la journée (paires ENTRÉE/SORTIE)
  • Bouton d'action « Demander une régularisation » sur les jours d'absence : ouvre la feuille de régularisation (QR-011)
  • Tirer pour actualiser sur mobile

Critères d'acceptation

```gherkin AC-001: View attendance history with filters Given I am logged in When I navigate to my attendance history Then I see a list of my clock events for the current month (default), filterable by date range

AC-002: Offline attendance history Given I am offline When I view my history Then I see cached data from the last sync ```---

OHADA et règles réglementaires

  • L'accès des employés à leurs propres données de présence contribue au respect des obligations de transparence
  • Les registres doivent être conservés pendant 10 ans (TV-QR-003)
  • Les données de présence alimentent le rapprochement des paies

Normes et conventions

  • docs/standards/java-spring-guidelines.md
  • docs/standards/api-guidelines.md
  • docs/standards/react-typescript-guidelines.md
  • docs/standards/offline-sync-guidelines.md

Exigences en matière de tests

Tests unitaires

  • AttendanceHistoryService : calculs récapitulatifs (nombre total d'heures, nombre de retards, absences, etc.)
  • AttendanceHistoryService : mappage des enregistrements journaliers avec les événements d'horloge
  • AttendanceHistoryService : comportement par défaut mensuel, remplacement de la plage de dates

Tests d'intégration

  • GET /attendance/me → renvoie les données de l'employé pour le mois en cours
  • GET /attendance/me?month=2026-02 → renvoie les données pour le mois spécifié
  • GET /employees/{id}/attendance en tant que RH → renvoie les données
  • GET /employees/{id}/attendance en tant qu'utilisateur non autorisé → 403
  • Isolation des tenants : un employé du tenant A ne peut pas voir les données du tenant B

Ce que l'assurance qualité va valider

  • Naviguer sur la page d'historique, vérifier que les fiches récapitulatives affichent les totaux corrects
  • Changer de mois à l'aide du sélecteur, vérifier la mise à jour des données
  • Vérifier que le cache hors ligne s'affiche avec l'horodatage « dernière synchronisation »
  • Vérifier que le CTA de régularisation apparaît sur les jours d'absence et renvoie vers QR-011
  • Développer la fiche journalière pour voir tous les événements de pointage
  • Mise en page responsive à 360px, 768px, 1024px

Hors périmètre

  • Formulaire de régularisation (QR-011, mais le CTA y renvoie)
  • Vue dédiée à l'équipe RH/Manager (utilise le même endpoint avec le paramètre employeeId)
  • Exportation de rapport (QR-017)
  • Vue cumulée depuis le début de l'année (V2)

Définition de « Terminé »

  • [ ] Les endpoints backend renvoient des données d'historique correctes
  • [ ] Les calculs de synthèse sont exacts
  • [ ] La page d'historique s'affiche correctement à 360px, 768px, 1024px
  • [ ] Les 5 états de l'interface utilisateur sont implémentés (chargement, vide, erreur, hors ligne, succès)
  • [ ] Les micro-textes en français correspondent exactement aux spécifications de conception
  • [ ] Tous les critères d'acceptation sont satisfaits manuellement
  • [ ] Les tests unitaires sont écrits et réussis
  • [ ] Les tests d'intégration sont écrits et réussis
  • [ ] L'isolation multi-tenant est vérifiée
  • [ ] Hors ligne : l'historique mis en cache s'affiche avec l'horodatage de synchronisation
  • [ ] Pas de any en TypeScript, pas de types bruts en Java
  • [ ] Les réponses API respectent le format d'enveloppe standard
  • [ ] ./gradlew test est vert
  • [ ] ./gradlew spotlessApply réussit