Aller au contenu

Story QR-016: Employee Attendance History

Module: qr-attendance Slice: QR-T5-001 (employee view) + US-QR-003 Brand context: [BOTH] Papillon HR Suite + ALTARYS ENTERPRISE HR Suite Priority: 16 Depends on: QR-006 (clock events + DailyAttendance) Can develop concurrently with: QR-011, QR-014 Merge order: Any order relative to peers Estimated complexity: M PRD User Stories: US-QR-003


Objective

Build the employee attendance history page, providing a monthly view of all clock events, daily attendance records, and summary statistics. Employees can browse their own history month by month, see detailed clock-in/out times, status badges (late, absent, regularized), and a summary row with totals. The page serves as both a transparency tool for employees and an entry point for regularization requests on anomalous days.


Backend Scope

Entities & Records

No new tables. Uses existing Clock and DailyAttendance.

Flyway Migrations

None.

Repository Layer

No new repositories. Extends existing queries on DailyAttendance and Clock.

Service Layer

AttendanceHistoryService: - getEmployeeHistory(tenantId, employeeId, month): - Retrieves all DailyAttendance records for the employee for the given month - Retrieves all Clock records for each day - Computes summary: totalWorkedHours, totalOvertime, totalLateCount, totalLateMinutes, totalAbsences, totalTeletravailDays - Returns structured response with summary + day records

API Endpoints

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)

DTOs

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) - workedMinutes (int) - status (String) - lateMinutes (int) - earlyDepartureMinutes (int) - anomalies (List) - hasRegularization (boolean)

Validation Rules

  • month format: YYYY-MM (defaults to current month if not provided)
  • dateFrom/dateTo override month if provided
  • Employee can only access own history via /me endpoint
  • Manager can access team members via /{employeeId} endpoint
  • HR can access any employee

Multi-Tenant Considerations

All queries filter by tenant_id. Employee sees only own data. Manager sees team. HR sees all within tenant.


Frontend Scope

Pages & Routes

  • /qrcontr/history — Employee's own attendance history (tab "Historique")

Components

HistoryPage (design spec wireframe 3.5): - Month picker + summary cards + daily list layout

MonthPicker: - Month/year selector with left/right arrows - Swipe gesture on mobile for month navigation

MonthlySummary: - 2x3 grid of summary cards: - Travaille (hours worked) - Retards (late count) - H. Supp. (overtime hours) - Absences (absence count) - Teletravail (remote work count) - Assiduite (attendance rate %)

DayHistoryCard: - Date, clock-in/out times, worked hours, status badge - If absent: inline CTA "Demander une regularisation" (links to QR-011) - If late: amber status badge with "(15 min)" detail - If regularized: "Regularise" badge (green) - Tap to expand: shows all clock events for that day (IN/OUT pairs)

UI States

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

Responsive Behavior

  • 360px: Stacked summary cards (2 per row), day cards full-width
  • 768px: Summary cards 3 per row, day cards with more detail
  • 1024px+: Summary sidebar + scrollable day table

Interactions

  • Month picker: arrows left/right, swipe on mobile
  • Day card tap: expand to show all clock events for that day (IN/OUT pairs)
  • "Demander une regularisation" CTA on absent days: opens regularization bottom sheet (QR-011)
  • Pull-to-refresh on mobile

Acceptance Criteria

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 & Regulatory Rules

  • Employee access to own attendance data supports transparency obligations
  • Records must be available for 10 years (TV-QR-003)
  • Attendance data feeds payroll reconciliation

Standards & Conventions

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

Testing Requirements

Unit Tests

  • AttendanceHistoryService: summary calculations (total hours, late count, absences, etc.)
  • AttendanceHistoryService: day record mapping with clock events
  • AttendanceHistoryService: month default behavior, date range override

Integration Tests

  • GET /attendance/me → returns employee's own data for current month
  • GET /attendance/me?month=2026-02 → returns data for specified month
  • GET /employees/{id}/attendance as HR → returns data
  • GET /employees/{id}/attendance as non-authorized → 403
  • Tenant isolation: employee from tenant A cannot see tenant B data

What QA Will Validate

  • Navigate history page, verify summary cards show correct totals
  • Change months using picker, verify data updates
  • Verify offline cache displays with "derniere synchronisation" timestamp
  • Verify regularization CTA appears on absent days and links to QR-011
  • Expand day card to see all clock events
  • Responsive layout at 360px, 768px, 1024px

Out of Scope

  • Regularization form (QR-011, but CTA links to it)
  • HR/Manager dedicated team view (uses same endpoint with employeeId param)
  • Report export (QR-017)
  • Year-to-date view (V2)

Definition of Done

  • [ ] Backend endpoints return correct history data
  • [ ] Summary calculations are accurate
  • [ ] History page renders correctly at 360px, 768px, 1024px
  • [ ] All 5 UI states implemented (loading, empty, error, offline, success)
  • [ ] French micro-copy matches design spec exactly
  • [ ] All acceptance criteria pass manually
  • [ ] Unit tests written and passing
  • [ ] Integration tests written and passing
  • [ ] Multi-tenant isolation verified
  • [ ] Offline: cached history displayed with sync timestamp
  • [ ] No TypeScript any, no Java raw types
  • [ ] API responses follow standard envelope format
  • [ ] ./gradlew test is green
  • [ ] ./gradlew spotlessApply passes