Aller au contenu

Story QR-013: HR Direct Regularization

Module: qr-attendance Slice: QR-T4-001 (partial: HR direct-create) Brand context: [BOTH] Papillon HR Suite + ALTARYS ENTERPRISE HR Suite Priority: 13 Depends on: QR-012 (approval + recalc logic exists) Can develop concurrently with: QR-015, QR-017 Merge order: After QR-012 Estimated complexity: S PRD User Stories: US-QR-006


Objective

Enable HR personnel to create direct regularizations that bypass the employee request and manager approval workflow. A direct regularization is auto-approved on creation (HR is both creator and approver), immediately triggers DailyAttendance recalculation, and notifies the affected employee. This supports operational scenarios where HR corrects attendance records proactively.


Backend Scope

Entities & Records

No new tables. Extends RegularizationService from QR-012.

Flyway Migrations

None.

Repository Layer

No new repositories. Uses existing RegularizationRequestRepository.

Service Layer

RegularizationService.directCreate(request, hrId): - Creates RegularizationRequest with: - status = APPROVED - isDirectCreate = true - requestedBy = hrId - approvedBy = hrId - approvedAt = now() - Triggers DailyAttendance recalculation (reuses logic from QR-012) - Publishes notification to employee: "Votre pointage a ete corrige par les RH."

API Endpoints

Method Path Request Body Response Auth
POST /api/v1/qrcontr/regularizations/direct CreateRegularizationRequest ApiResponse<RegularizationResponse> HR (P2)

DTOs

Reuses CreateRegularizationRequest and RegularizationResponse from QR-011.

Validation Rules

Same validation as QR-011: - reason is mandatory - At least one time field must be provided (correctedClockIn or correctedClockOut) - date must reference an existing DailyAttendance record - employeeId must be a valid employee in the same tenant

Multi-Tenant Considerations

All regularization queries filter by tenant_id. HR can only create direct regularizations for employees within their tenant.


Frontend Scope

Pages & Routes

No new routes. Form is triggered from existing dashboard views.

Components

DirectRegularizationForm: - Triggered from dashboard swipe-left on employee row (HR only), or from employee day detail - Reuses RegularizationForm component from QR-011 but with "Regularisation directe" header and no PENDING step - Confirmation message: "Regularisation enregistree. L'employe sera notifie de la correction."

UI States

State Behavior French Copy
Loading N/A (form is local)
Empty Pre-filled with employee + date from context
Error Inline validation Same as QR-011
Offline Form works, submit queued "Regularisation sauvegardee — sera envoyee des la reconnexion."
Success Animated checkmark "Regularisation enregistree. L'employe sera notifie de la correction."

Responsive Behavior

  • 360px: Bottom sheet form (single step — no wizard needed since HR knows what to fill)
  • 768px: Bottom sheet
  • 1024px+: Side panel

Interactions

  • Swipe-left on employee row in dashboard → opens DirectRegularizationForm
  • Employee + date pre-filled from context
  • Submit → animated checkmark → form closes
  • Offline: form submits to local queue, syncs when online

Acceptance Criteria

AC-001: HR direct-create auto-approved regularization
Given I am HR
When I create a direct regularization
Then it is auto-approved (no pending step) and recorded with HR as both creator and approver

AC-002: Employee notification on HR correction
Given I create a direct regularization
When it is saved
Then the employee is notified that their record was corrected

OHADA & Regulatory Rules

  • FR-QR-064: Direct regularization logged in audit trail with HR as actor
  • Original clock events are preserved — regularization is an additive record, not a destructive edit

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

  • RegularizationService.directCreate: sets status=APPROVED, isDirectCreate=true, requestedBy=hrId, approvedBy=hrId
  • RegularizationService.directCreate: triggers DailyAttendance recalculation
  • Validation: reason required, at least one time field required

Integration Tests

  • POST /regularizations/direct → 201 with status APPROVED
  • POST /regularizations/direct with non-HR role → 403
  • POST /regularizations/direct → DailyAttendance recalculated correctly
  • Tenant isolation: HR from tenant A cannot regularize employee from tenant B

What QA Will Validate

  • HR creates direct regularization from dashboard swipe action
  • Verify regularization is auto-approved (no pending step)
  • Verify employee receives notification
  • Verify DailyAttendance is recalculated
  • Offline: form works and syncs when reconnected

Out of Scope

  • Employee/manager request workflow (QR-011)
  • Approval workflow (QR-012)
  • Bulk regularization (V2)

Definition of Done

  • [ ] POST /regularizations/direct endpoint implemented
  • [ ] DailyAttendance recalculated on direct create
  • [ ] Frontend form works from dashboard swipe action
  • [ ] 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 write+sync works
  • [ ] Audit trail entries for direct regularization
  • [ ] No TypeScript any, no Java raw types
  • [ ] API responses follow standard envelope format
  • [ ] ./gradlew test is green
  • [ ] ./gradlew spotlessApply passes