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 (Listdate (LocalDate)
- dayOfWeek (String)
- clockIn (LocalTime, nullable)
- clockOut (LocalTime, nullable)
- workedMinutes (int)
- status (String)
- lateMinutes (int)
- earlyDepartureMinutes (int)
- anomalies (ListhasRegularization (boolean)
Validation Rules¶
monthformat: YYYY-MM (defaults to current month if not provided)dateFrom/dateTooverridemonthif provided- Employee can only access own history via
/meendpoint - 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.mddocs/standards/api-guidelines.mddocs/standards/react-typescript-guidelines.mddocs/standards/offline-sync-guidelines.md
Testing Requirements¶
Unit Tests¶
AttendanceHistoryService: summary calculations (total hours, late count, absences, etc.)AttendanceHistoryService: day record mapping with clock eventsAttendanceHistoryService: 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}/attendanceas HR → returns data - GET
/employees/{id}/attendanceas 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 testis green - [ ]
./gradlew spotlessApplypasses