Zum Hauptinhalt springen

Mehrarbeits-Genehmigungen (WorkTimeOvertimeApproval)

Im aktuellen FE-Master gibt es **keine eigenständige `/work-time-overtime-approvals`-Route**. Der Endpoint-Frontmatter dieser Seite bezieht sich auf die **BE-API-Routenfamilie**.

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

- Tenant-Setting `enforceMaxWorkingHours = true` - Mitarbeiter-Zeiterfassung aktiv - Berechtigung `view:WorkTimeOvertimeApproval` (für Sicht) - Power-Permissions `do:ApproveWorkTimeOvertimeApproval` + `do:RejectWorkTimeOvertimeApproval` (für HR-Leitung)

Berechtigungen (CASL)

Frontend-Page-Guard:

ActionSubject
viewFE_WorkTimeOvertimeApproval
viewWorkTimeOvertimeApproval

API-Datenzugriff:

ActionSubjectWirkung
viewWorkTimeOvertimeApprovalListe / Detail lesen
createWorkTimeOvertimeApprovalEngine erzeugt Eintrag (System-Rolle)
updateWorkTimeOvertimeApprovalStatus / Entscheidung schreiben
doApproveWorkTimeOvertimeApprovalGenehmigen — POST /:id/approve
doRejectWorkTimeOvertimeApprovalAblehnen — POST /:id/reject

Datenmodell

FeldTypBedeutung
idUUIDPrimary Key
sequenceIdNumberfortlaufend pro Mandant
employeeIdUUIDMitarbeiter
dateDateOnlyBetroffener Tag
workedMinutesIntegerBrutto-Arbeitsminuten an dem Tag (vor Cap)
maxAllowedMinutesIntegerGesetzliche Tageshöchstgrenze (i.d.R. 600 = 10h, aus laborLaw[country].maxDailyWorkMinutesExtended)
overflowMinutesIntegerworkedMinutes - maxAllowedMinutes
statusenumpending (Default) | approved | rejected
decidedByEmployeeIdUUID nullablewer hat entschieden (HR-Leitung)
decidedAtDateTime nullablewann entschieden
decisionReasonString nullableBegründung (Pflicht bei Reject)
sourceCheckIdUUID nullableVerweis auf EmployeeComplianceCheck (maxDailyHoursExceeded)
createdAt, updatedAt, deletedAtDateTimeStandard + Soft-Delete

API-Endpoints

MethodeEndpointZweck
GET/api/work-time-overtime-approvalsListe aller Approvals
GET/api/work-time-overtime-approvals/:idDetail eines Approvals
POST/api/work-time-overtime-approvals/:id/approveGenehmigen, optional mit Begründung
POST/api/work-time-overtime-approvals/:id/rejectAblehnen, Begründung Pflicht
POST/api/work-time-overtime-approvals/backfillManueller 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:

  1. Der Service berechnet die Tagesarbeitszeit für {employeeId, date} aus den vorhandenen Zeit-Trackings.
  2. Ist die reine Arbeitszeit ≤ maxAllowedMinutes, gibt es keinen Überlauf und der Aufruf schlägt fehl (kein leerer Approval-Record).
  3. Andernfalls wird der WorkTimeOvertimeApproval-Eintrag angelegt oder aktualisiert. Mit decision werden status, decidedByEmployeeId und decidedAt direkt gesetzt; ohne decision läuft der Record im Status pending in 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-ServiceresolveCountableMinutesForDay() 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, Service workTimeOvertimeApproval.service.ts (353 Zeilen), Integration in workTimeBalance.service.ts (1268 Zeilen).
  • 2026-05-12 (Welle 113): Neuer Endpoint POST /api/work-time-overtime-approvals/backfill für manuell nachgetragene historische Tage. Backend-Saldo verwendet jetzt actualMinutes als reine Arbeitszeit nach §3-Cap und bruttoIstMinutes als separate Brutto-Anwesenheit.