Mehrarbeits-Genehmigungen (WorkTimeOvertimeApproval)
HR-Leitung erreicht die pending Approvals über:
- Notification-Popup (severity=violation für ungenehmigte Mehrarbeit)
- Mitarbeiter-Detail → Compliance-History-Page (
/employees/:id/compliance-history) - Time-Overview-Report mit eigener §3-ArbZG-Card
Der Anwender-Workflow ist im Tutorial Mehrarbeit genehmigen beschrieben.
Zweck
WorkTimeOvertimeApproval modelliert die Genehmigungs-Entscheidung für Tage, an denen ein Mitarbeiter die deutsche Tageshöchstgrenze nach §3 ArbZG (i. d. R. 10 Stunden) überschritten hat. Pro Tag ein Eintrag, automatisch von der Compliance-Engine erzeugt, manuell von HR-Leitung genehmigt oder abgelehnt.
Aktiv nur, wenn das Tenant-Setting enforceMaxWorkingHours auf true gesetzt ist.
Konzept: §3 ArbZG-Cap Workflow für HR-Leitung: Mehrarbeit genehmigen
Voraussetzungen
Berechtigungen (CASL)
Frontend-Page-Guard:
| Action | Subject |
|---|---|
view | FE_WorkTimeOvertimeApproval |
view | WorkTimeOvertimeApproval |
API-Datenzugriff:
| Action | Subject | Wirkung |
|---|---|---|
view | WorkTimeOvertimeApproval | Liste / Detail lesen |
create | WorkTimeOvertimeApproval | Engine erzeugt Eintrag (System-Rolle) |
update | WorkTimeOvertimeApproval | Status / Entscheidung schreiben |
do | ApproveWorkTimeOvertimeApproval | Genehmigen — POST /:id/approve |
do | RejectWorkTimeOvertimeApproval | Ablehnen — POST /:id/reject |
Datenmodell
| Feld | Typ | Bedeutung |
|---|---|---|
id | UUID | Primary Key |
sequenceId | Number | fortlaufend pro Mandant |
employeeId | UUID | Mitarbeiter |
date | DateOnly | Betroffener Tag |
workedMinutes | Integer | Brutto-Arbeitsminuten an dem Tag (vor Cap) |
maxAllowedMinutes | Integer | Gesetzliche Tageshöchstgrenze (i.d.R. 600 = 10h, aus laborLaw[country].maxDailyWorkMinutesExtended) |
overflowMinutes | Integer | workedMinutes - maxAllowedMinutes |
status | enum | pending (Default) | approved | rejected |
decidedByEmployeeId | UUID nullable | wer hat entschieden (HR-Leitung) |
decidedAt | DateTime nullable | wann entschieden |
decisionReason | String nullable | Begründung (Pflicht bei Reject) |
sourceCheckId | UUID nullable | Verweis auf EmployeeComplianceCheck (maxDailyHoursExceeded) |
createdAt, updatedAt, deletedAt | DateTime | Standard + Soft-Delete |
API-Endpoints
| Methode | Endpoint | Zweck |
|---|---|---|
GET | /api/work-time-overtime-approvals | Liste aller Approvals |
GET | /api/work-time-overtime-approvals/:id | Detail eines Approvals |
POST | /api/work-time-overtime-approvals/:id/approve | Genehmigen, optional mit Begründung |
POST | /api/work-time-overtime-approvals/:id/reject | Ablehnen, Begründung Pflicht |
POST | /api/work-time-overtime-approvals/backfill | Manueller Backfill für historische Tage (siehe unten) |
Filter typisch: ?filter[status]=pending, ?filter[employeeId]=..., ?filter[date][between]=....
Backfill für historische Tage (Welle 113)
Wenn ein Tag in der Vergangenheit nachträglich einen §3-Überlauf bekommt — z. B. weil Zeit-Buchungen korrigiert oder nachgepflegt wurden — kann der zugehörige Approval-Record manuell erzeugt werden:
POST /api/work-time-overtime-approvals/backfill
{
"employeeId": "<uuid>", // Pflicht
"date": "2026-04-15", // Pflicht (YYYY-MM-DD)
"decision": "approved", // optional, ENUM approved | rejected
"reason": "Notfall-Einsatz" // Pflicht bei decision = rejected
}
Logik des Endpoints:
- Der Service berechnet die Tagesarbeitszeit für
{employeeId, date}aus den vorhandenen Zeit-Trackings. - Ist die reine Arbeitszeit ≤
maxAllowedMinutes, gibt es keinen Überlauf und der Aufruf schlägt fehl (kein leerer Approval-Record). - Andernfalls wird der
WorkTimeOvertimeApproval-Eintrag angelegt oder aktualisiert. Mitdecisionwerdenstatus,decidedByEmployeeIdunddecidedAtdirekt gesetzt; ohnedecisionläuft der Record im Statuspendingin den normalen Workflow.
CASL: create:WorkTimeOvertimeApproval. Der Endpoint löst keine Notification aus — Backfill ist eine Admin-/HR-Korrektur, kein automatischer Trigger.
Verknüpfungen zu anderen Modulen
- EmployeeTimeTracking — Quelle der Stempel-Zeiten, durch Engine ausgewertet
- EmployeeComplianceCheck — Source-Check (Type
maxDailyHoursExceeded) der den Approval triggert - WorkTimeBalance-Service —
resolveCountableMinutesForDay()schreibt das Approval-Ergebnis ins Saldo - TimeOverviewReport — eigene §3-ArbZG-Card im PDF-Export
Versionshinweise
- 2026-05 (Welle 97): Initiale Doku basiert auf BE-Tag v1.64.0 + FE-Tag v1.71.0. Modell
workTimeOvertimeApproval.model.ts, ServiceworkTimeOvertimeApproval.service.ts(353 Zeilen), Integration inworkTimeBalance.service.ts(1268 Zeilen). - 2026-05-12 (Welle 113): Neuer Endpoint
POST /api/work-time-overtime-approvals/backfillfür manuell nachgetragene historische Tage. Backend-Saldo verwendet jetztactualMinutesals reine Arbeitszeit nach §3-Cap undbruttoIstMinutesals separate Brutto-Anwesenheit.