Arbeitszeit-Compliance — ArbZG-Echtzeit, Überstunden, Gleitzeit, Schichtmodelle
Feinkonzept — Arbeitszeit-Compliance (ArbZG · Überstunden · Gleitzeit · Schicht)
Abschnitt betitelt „Feinkonzept — Arbeitszeit-Compliance (ArbZG · Überstunden · Gleitzeit · Schicht)“Kern-Modul. Dieses Feinkonzept implementiert die Policy-Engine rund um das Stempeln (
kern/01-zeiterfassung). Ohne Live-Bewertung der Stempel-Ereignisse gegen ArbZG-Regelwerk, Überstunden-Konten, Gleitzeit-Modelle und Schicht-Vorgaben ist Werkszeit keine BAG-konforme Lösung, sondern nur eine Stoppuhr. Struktur nach Pflichtvorlage../TEMPLATE.md, alle 18 Sektionen.
1. Header & Metadaten
Abschnitt betitelt „1. Header & Metadaten“feature_id: kern/02-arbeitszeit-compliancetitle: Arbeitszeit-Compliance — ArbZG-Echtzeit, Überstunden, Gleitzeit, Schichtmodellefunktionsumfang_ref: §3.2roadmap_horizont: MVP # Kern-Regeln MVP, erweiterte Schichtmodelle V1plattformen: mobile: vollständig # Anzeige Saldo + Warnungen web: vollständig # Konfiguration Regeln, Auswertung desktop: ab V1.5 bei Bedarfowner_rolle: Admin # Konfiguration; konsumiert wird von Mitarbeiter/Manager/HRmodul_gate_flag: module.kern.arbeitszeit_compliancecompliance_flags: gobd: true # Warnungen + Konten werden append-only protokolliert arbzg: true # Kern-Gesetz vob: false dsgvo: true bfsg: true betrvg: true # Anomalie-Erkennung ist Leistungs-/Verhaltenskontrolle stvg: false weitere: [TV Bau (Rahmentarif), §87(1)2 BetrVG (Verteilung Arbeitszeit), MiLoG]referenzkunde: status: TBD name: "zu klären mit Sales — Kandidaten-Profil siehe §17" quelle: Sales-Call "BAG-Deadline-Angst"estimate_eng_tage: 48abhängigkeiten: - kern/01-zeiterfassung # liefert time_entries-Stream - kern/03-abwesenheiten # Urlaub/Krank reduzieren Überstunden-Saldo - kern/08-dienstplanung # Schicht-Soll = Referenz für Abweichung2. Kontext & Problem
Abschnitt betitelt „2. Kontext & Problem“Marktrealität. Das ArbZG ist seit 1994 in Kraft, wurde aber durch das BAG-Urteil 13.09.2022 (1 ABR 22/21) und den Referentenentwurf zur ArbZG-Novelle (2025) wieder zu einem aktiv geprüften Gesetz. Typische Handwerks-Probleme:
- §3 Höchstarbeitszeit (8 h / bis 10 h mit Ausgleich binnen 6 Monaten): In der Praxis gerne überschritten, Nachweis des Ausgleichs fehlt.
- §4 Pausen (30 min ab 6 h, 45 min ab 9 h): Oft „Frühstück am Fahrzeug“ ohne formale Erfassung.
- §5 Ruhezeit (11 h): Bei Notdienst SHK oder Winterdienst der größte Dauerbruch — Kunde ruft 22:00, Team ist 06:00 wieder auf der Baustelle.
- §7 Abweichungen (TV-geregelte Ausnahmen): Der Rahmentarif Bau lässt 10-h-Tage zu, aber nur bei Ausgleich und nur für bestimmte Gewerke.
- MiLoG + TV Bau Mindestlohn: Ab 1.4.2026 gelten in der Bauwirtschaft West 14,35 €/h / Ost 14,35 €/h Lohngruppe 1, Lohngruppe 2 West 15,80 €. Unterschreitung = Haftung Subunternehmer-Vergabe.
- Gleitzeit-Konten und Überstunden-Konten werden oft auf Papier geführt, gerne ins Minus, kein Audit-Trail bei Kappung („der Chef hat gesagt, die verfallen zum Jahresende“).
Schmerzpunkt der Alt-App. LESSONS-LEARNED §5 und §7: Die ArbZG-Grenzfälle wurden nie getestet (Nachtarbeit über 00:00, §7-Ausnahmen, Ruhezeit-Unterbrechungen). Es gab eine pzeAze.js-Service-Datei (LESSONS-LEARNED §11) mit Geschäftsregeln, aber keine Property-basierten Tests, keine klare Trennung zwischen „Warnung“ (protokollieren, weiterlaufen lassen) und „Blocker“ (kein Save ohne Begründung), und die Konfiguration hing hart in JS-Enums.
Erwarteter Outcome.
- Echtzeit-Warnungen beim Stempeln (< 300 ms Rundtrip), nicht erst im Monatsabschluss.
- Konten-Transparenz: Mitarbeiter sehen eigenen Überstunden- und Gleitzeit-Saldo tagesaktuell.
- Manager-Dashboard „ArbZG-Ampel“ pro Team, filterbar nach Regel (§3/§4/§5/§7).
- Konfigurierbare Overrides pro Tenant: TV-Bau-Ausnahmen, Schichtmodell-Auslegung (Früh/Spät/Nacht/Wechsel), ohne Code-Änderung.
- Property-Test-Abdeckung für alle ArbZG-Grenzfälle (Minute-genau, 24×365 Matrix).
3. Personas & Rollen
Abschnitt betitelt „3. Personas & Rollen“| Rolle | Aktion | Scope | Plattform |
|---|---|---|---|
| Mitarbeiter | Eigene Salden einsehen (ÜS, Gleitzeit, Ruhezeit-Kette) | own |
📱🌐 |
| Mitarbeiter | Warnungen beim Stempeln lesen, ggf. Begründung eingeben | own |
📱🌐 |
| Manager | ArbZG-Ampel im Team, Verletzungs-Tickets abarbeiten | team |
📱🌐 |
| Manager | Überstunden-Kappung mit Begründung (falls Modell erlaubt) | team |
🌐 |
| HR | Konten-Korrekturen manuell, Audit-pflichtig | all |
🌐 |
| Admin | Überstunden-/Gleitzeit-Modelle, Schichtmodelle, TV-Ausnahmen konfigurieren | all |
🌐 |
| Betriebsrat | Read-Only auf Ampel + BR-Freischaltungs-Workflows | all |
🌐 |
| Buchhaltung | Salden zum Stichtag einfrieren (Monatsabschluss-Ref) | all |
🌐 |
Persona-Skizzen.
- Hannes Krüger (musterbetrieb-maler) — sieht beim Stempel-Screen „Woche 32:15 / 40:00“. Will beim Überschreiten 10 h klare Info, aber nicht zwangsabgemeldet werden, wenn der Bauherr noch vor Ort ist.
- Sabine Maier — konfiguriert keine Regeln (das macht HR), aber nutzt täglich die ArbZG-Ampel und bekommt Tickets bei Ruhezeit-Brüchen.
- Thomas Schmidt (shk-gebruder-schmidt) — Bauleiter 18 Monteure, SHK-Notdienst-Schichten → viele §5-Grenzfälle. Braucht klare §7-Ausnahme-Konfiguration (TV Bau).
- Frau Müller (Buchhaltung) — braucht zum 01. jedes Monats eine konsistente Salden-Kopie für DATEV; jedes nachträgliche Ändern auf gesperrtem Monat muss explizit sein.
4. User-Stories
Abschnitt betitelt „4. User-Stories“US-01 [MVP] Als Monteur möchte ich beim Stempel-Stop in Echtzeit sehen, ob ich die 10-Stunden-Grenze nach §3 ArbZG erreicht habe, um es bewusst zu entscheiden.
US-02 [MVP] Als Mitarbeiter möchte ich täglich meinen aktuellen Überstunden-Saldo sehen, damit ich planen kann, ob ich Freitag früher gehe.
US-03 [MVP] Als Manager möchte ich eine Team-Ampel haben, die ArbZG-Risiken aggregiert, damit ich gezielt die 2–3 Mitarbeiter mit §3/§5-Konflikten ansprechen kann.
US-04 [MVP] Als Admin möchte ich das Gleitzeit-Modell pro Tenant konfigurieren (Kernzeit 10:00–15:00, Rahmen 06:00–20:00, Kappung bei ±30 h).
US-05 [V1] Als Admin möchte ich Schichtmodelle (Früh 05:30–13:30, Spät 13:30–21:30, Nacht 21:30–05:30) anlegen und Wechselschicht-Regeln definieren.
US-06 [V1] Als Admin möchte ich §7-ArbZG-TV-Ausnahmen hinterlegen (TV Bau 10h-Regel mit Ausgleich binnen 6 Monaten), damit Monteure ohne Rotwarnung arbeiten dürfen.
US-07 [MVP] Als HR möchte ich eine Konten-Korrektur durchführen (z.B. +8h wegen Fortbildungstag), mit Pflicht-Begründung und Audit.
US-08 [V1] Als Betriebsrat möchte ich einen Read-Only-Dashboard-Zugang und einen schriftlichen Freischaltungs-Workflow für Anomalie-Erkennung haben.
US-09 [MVP] Als Buchhaltung möchte ich Salden zum 30. eines Monats einfrieren, sodass DATEV-Export deterministisch ist.5. Funktionale Anforderungen
Abschnitt betitelt „5. Funktionale Anforderungen“5.1 Mobile App (📱)
Abschnitt betitelt „5.1 Mobile App (📱)“- F-M-01 — Saldo-Kachel auf Home/Stempel-Screen: Saldo Tag, Woche, Monat, ÜS-Konto, Gleitzeit-Konto. Mono-Schrift, Tabular-Numeric.
- F-M-02 — Inline-ArbZG-Warnung beim Stempel-Ereignis: gelbe Box mit §-Verweis und konkretem Zeitpunkt („10-h-Grenze in 3:18 h“).
- F-M-03 — Ruhezeit-Projektion beim Einstempeln: Wenn letzter Stop < 11h her, Warnung mit Differenz; Begründungsfeld (Pflicht) + Freigabe-Schalter.
- F-M-04 — Ampel-Status (🟢/🟡/🔴) pro Tag in der Monatsliste, auf Tippen öffnet Detail-Sheet mit verletzter Regel.
- F-M-05 — Kontenverlauf als Chart (fl_chart): Überstunden-Saldo über 12 Wochen, mit Kappungs-Marker.
5.2 Web-App (🌐)
Abschnitt betitelt „5.2 Web-App (🌐)“- F-W-01 — ArbZG-Ampel-Dashboard: Team-Übersicht mit Zeilen pro Mitarbeiter, Spalten für
§3,§4,§5,§7-Bruch, Filter nach Zeitraum. - F-W-02 — Detail-Ansicht pro Verletzung: chronologischer Audit der Stempelereignisse, die zur Verletzung geführt haben, inkl. Ruhezeit-Berechnung und §-konformer Formulierung des Sachverhalts.
- F-W-03 — Konto-Editor für HR: Korrektur-Zeile mit Δ, Pflicht-Begründung, Audit-Log-Eintrag.
- F-W-04 — Monatsabschluss-Freeze: zum Stichtag werden Salden in
balance_snapshotseingefroren (hash-chained). - F-W-05 — Export ArbZG-Report als PDF (pro MA / pro Team / pro Monat), signiert.
5.3 Cross-Plattform (🔄)
Abschnitt betitelt „5.3 Cross-Plattform (🔄)“- F-X-01 — Live-Re-Check: Jede neue
time_entrytriggert ArbZG-Evaluator serverseitig (Hono) + spiegelt Flags in Client-UI via SSE. - F-X-02 — Feiertagskalender-Integration (Bundesland) — Feiertags-Arbeit triggert Zuschlags-Flag (kein Lohn-Feature hier, nur Markierung für DATEV-Export).
- F-X-03 — Teilschicht-Logik: Schichtübergreifende Buchung (22:00 → 06:00) wird kalendertag-übergreifend korrekt zugeordnet (Split auf beide Tage mit anteiligen Stunden).
5.4 Admin-Konfiguration
Abschnitt betitelt „5.4 Admin-Konfiguration“- F-A-01 — Überstunden-Modell: Wöchentliche Basis (z.B. 40h), Kappung (z.B. max 30h ÜS-Konto), Verfall (Stichtag / rollierend), Ausgleich in Freizeit vs. Auszahlung.
- F-A-02 — Gleitzeit-Modell: Kernzeit, Rahmen, Kappung ±, Übertragbarkeit Monat.
- F-A-03 — Schichtmodelle: Früh/Spät/Nacht-Zeitfenster, Wechselschicht-Regeln (max. 7 Nachtschichten in Folge, min. Ausgleichstage).
- F-A-04 — §7-TV-Ausnahmen: Liste Tarifverträge (TV Bau, TV Metall, TV Einzelhandel), konkrete Abweichung (§3 auf 12h bei Ausgleich binnen 6 Monaten).
- F-A-05 — MiLoG-Mindestlohn-Referenz: Aktueller Satz automatisch gepflegt (CI-Job von Basis-Satz 2026, TV Bau-Tabelle separat); Admin kann Tenant-Override setzen.
- F-A-06 — BetrVG-Freischaltung Anomalie-Erkennung: UI-Workflow mit BR-Beschluss-PDF-Upload, Audit, Default aus.
5.5 Roadmap-Schichtung
Abschnitt betitelt „5.5 Roadmap-Schichtung“| Anforderung-ID | MVP | V1 | V1.5 | V2 |
|---|---|---|---|---|
| F-M-01 Saldo-Kachel | ✅ | |||
| F-M-02 Inline-Warnung | ✅ | |||
| F-M-03 Ruhezeit-Projektion | ✅ | |||
| F-M-04 Ampel-Tagesliste | ✅ | |||
| F-M-05 Kontoverlauf-Chart | ✅ | |||
| F-W-01 Ampel-Dashboard | ✅ | |||
| F-W-02 Verletzungs-Detail | ✅ | |||
| F-W-03 Konto-Editor | ✅ | |||
| F-W-04 Salden-Freeze | ✅ | |||
| F-W-05 PDF-Report | ✅ | |||
| F-A-01 ÜS-Modell | ✅ | |||
| F-A-02 Gleitzeit-Modell | ✅ | |||
| F-A-03 Schichtmodelle | ✅ | |||
| F-A-04 §7-TV | ✅ | |||
| F-A-06 Anomalie-BR-Workflow | ✅ |
6. Mockups & Flows
Abschnitt betitelt „6. Mockups & Flows“HTML-Hero-Mockup: 02-arbeitszeit-compliance.html — Mobile (Hannes sieht Saldo + ArbZG-Warnung + Ruhezeit-Dialog) + Web (Sabine, ArbZG-Ampel-Dashboard, Verletzungs-Detail).
6.1 Saldo-Kachel Mobile
Abschnitt betitelt „6.1 Saldo-Kachel Mobile“┌────────────────────────────────┐│ ← Konten 📊 │├────────────────────────────────┤│ Mo 19.04.2026 ││ ││ Heute 6:40 h von 8:00 ││ Woche 32:15 h von 40:00 ││ ││ Überstunden-Konto +14:30 h ││ [Historie ▸] ││ ││ Gleitzeit-Saldo +4:15 h ││ Kernzeit 10:00–15:00 ││ [Historie ▸] ││ ││ ArbZG-Status diese Woche ││ 🟢 §3 OK 🟢 §4 OK ││ 🟡 §5 1 Verletzung (15.04.) ││ ││ Letzter Freeze: ││ 31.03.2026 · Frau Müller │└────────────────────────────────┘6.2 Ruhezeit-Projektion (Mobile)
Abschnitt betitelt „6.2 Ruhezeit-Projektion (Mobile)“┌────────────────────────────────┐│ ⚠ §5 ArbZG — Ruhezeit kurz │├────────────────────────────────┤│ Letzte Stempelung ││ Gestern 22:15 Uhr ││ ││ Aktueller Start ││ Heute 06:30 Uhr ││ ││ Ruhezeit: 8:15 h ││ Soll laut §5 ArbZG: 11:00 h ││ Unterschied: −2:45 h ││ ││ Begründung 🔴 (Pflicht) ││ ┌──────────────────────────┐ ││ │ SHK-Notdienst, Wasser- │ ││ │ rohrbruch Bgm. Müller- │ ││ │ Schule, §7 ArbZG/TV Bau. │ ││ └──────────────────────────┘ ││ ││ ℹ Manager wird informiert ││ Eintrag als §5-Warnung ││ gespeichert ││ ││ [ Abbrechen ] [ Trotzdem ein ]│└────────────────────────────────┘6.3 ArbZG-Ampel-Dashboard Web
Abschnitt betitelt „6.3 ArbZG-Ampel-Dashboard Web“┌────────────────────────────────────────────────────────────────────────────────┐│ Werkszeit · musterbetrieb-maler Sabine M. · Manager [Profil ▾] │├──────────┬─────────────────────────────────────────────────────────────────────┤│ ⏱ Zeit │ ArbZG-Ampel · KW 16 · Mo–Fr 13.–19.04.2026 [⤓ PDF] ││ ⚡ ArbZG ▸├─────────────────────────────────────────────────────────────────────┤│ 📅 Plan │ 🔴 1 akut 🟡 3 Warnungen 🟢 14 OK ││ 📋 Doku ├─────────────────────────────────────────────────────────────────────┤│ 🗓 Urlaub │ Mitarbeiter §3 Höchst §4 Pause §5 Ruhe §7 TV Überst Aktion││ 🏗 Projek│ Hannes Krüger 🟡 9:42h 🟢 🟢 — +14:30 [→] ││ 📄 Rechn.│ Mehmet Yılmaz 🟢 🟡 5 min 🟢 — +8:15 [→] ││ 🛡 Audit │ Frank Demir — (krank) ││ ⚙ Einst. │ Sabine Maier 🟢 🟢 🟢 — −2:00 [→] ││ ────────│ Thomas S.(NRW) 🔴 11:15 🟢 🔴 8:15 §7✔ +22:00 [!] ││ SM │ Andreas Wirth 🟢 🟢 🟢 — +0:45 [→] ││ Manager │ Jonas Brehm 🟢 🟢 🟢 — +1:30 [→] ││ │ ││ │ [Zeitraum: KW 16 ▾] [Team: Alle ▾] [Nur Verletzungen ☑] │└──────────┴─────────────────────────────────────────────────────────────────────┘6.4 Verletzungs-Detail Web
Abschnitt betitelt „6.4 Verletzungs-Detail Web“┌────────────────────────────────────────────────────────────────────────────────┐│ ← ArbZG-Verletzung · Thomas Schmidt · 15.04.2026 │├────────────────────────────────────────────────────────────────────────────────┤│ 🔴 §5 ArbZG — Ruhezeit verletzt (8:15 h statt 11:00 h) ││ ││ Ursache: ││ • 14.04.2026 22:15 Stop Hauptstr. 42, Köln (Notdienst Heizung) ││ • 15.04.2026 06:30 Start Schulstr. 12, Köln ││ → Ruhezeit 8:15 h, Unterschreitung 2:45 h ││ ││ Ausnahme-Check: ││ • §7 Abs. 2 ArbZG · TV Bau Rahmentarif §3 Abs. 1 Buchst. c (Notdienste) ││ • Begründung Mitarbeiter: „Wasserrohrbruch Bgm. Müller-Schule" ││ • Ausgleich eingeplant: 17.04.2026 (freier Tag) ││ ││ Audit-Chain: ││ • 14.04. 22:16 erstellt ││ • 15.04. 06:31 §5-Flag gesetzt (Hash abcd…) ││ • 15.04. 06:31 Begründung ergänzt (Hash efgh…) ││ • 15.04. 07:00 Manager Bauleitung informiert (Ticket #TW-2026-0432) ││ ││ Status: [ Als Ausnahme anerkannt ] [ Korrigieren ] [ Eskalieren HR ] │└────────────────────────────────────────────────────────────────────────────────┘6.5 Admin-Konfiguration Überstunden-Modell
Abschnitt betitelt „6.5 Admin-Konfiguration Überstunden-Modell“┌────────────────────────────────────────────────────────────────────────────────┐│ Einstellungen / Überstunden-Modell │├────────────────────────────────────────────────────────────────────────────────┤│ Modell-Name [Standard musterbetrieb-maler ] ││ ││ Wöchentliche Soll-Arbeitszeit [40:00] h ││ Kappung ÜS-Konto [±30:00] h ││ Verfall ( ) zum Jahresende ││ (•) rollierend 12 Monate ││ ( ) kein Verfall ││ Ausgleich [✓] in Freizeit ││ [✓] Auszahlung mit Zuschlag 25% ││ ││ Wochenfeiertage-Regel [✓] Feiertag auf Werktag = Zuschlag 50% ││ [ ] Feiertag auf Sonntag ignorieren ││ ││ Abwesenheiten reduzieren [✓] Urlaub auf Kontingent (nicht ÜS) ││ [✓] Krank auf Entgeltfortzahlung (nicht ÜS) ││ ││ Aktivierung ab [01.05.2026 ▼] ││ ││ [ Abbrechen ] [ Speichern + BR-Notifikation ] │└────────────────────────────────────────────────────────────────────────────────┘6.6 Konto-Editor HR
Abschnitt betitelt „6.6 Konto-Editor HR“┌────────────────────────────────────────────────────────────────────────────────┐│ ← Konto-Korrektur · Hannes Krüger │├────────────────────────────────────────────────────────────────────────────────┤│ Konto-Typ: [ Überstunden ▾ ] Saldo heute: +14:30 h ││ ││ Korrektur Δ: [ +8:00 ] h ││ Neuer Saldo: +22:30 h ││ ││ Wirksam ab: [ 19.04.2026 ] ││ ││ Begründung 🔴 (Pflicht, min. 20 Zeichen, GoBD) ││ ┌──────────────────────────────────────────────────────────────────────────┐ ││ │ Fortbildung "Luftdichtheit Holzbau" 16.–17.04., 8h außerhalb Zeiterfas- │ ││ │ sung aufgrund Kurs-Software der Handwerkskammer. │ ││ └──────────────────────────────────────────────────────────────────────────┘ ││ ││ ℹ Audit-Log: balance.correction · Aktor: Frau Müller · Hash wird verkettet. ││ ││ [ Abbrechen ] [ Korrektur speichern ] │└────────────────────────────────────────────────────────────────────────────────┘7. Datenmodell-Skizze
Abschnitt betitelt „7. Datenmodell-Skizze“export const arbzgFlagsTable = pgTable('arbzg_flags', { id: uuid('id').primaryKey(), tenantId: uuid('tenant_id').notNull(), userId: uuid('user_id').notNull(), timeEntryId: uuid('time_entry_id').notNull().references(() => timeEntriesTable.id), rule: arbzgRuleEnum('rule').notNull(), // haechstarbeitszeit | pause | ruhezeit | tv_ausnahme | milog_unter severity: severityEnum('severity').notNull(), // info | warn | violation value: jsonb('value').$type<ArbzgFlagValue>().notNull(), // {requested: 11h, actual: 8.25h, diff: -2.75h} reasonText: varchar('reason_text', { length: 500 }), // Begründung Mitarbeiter / HR acknowledgedBy: uuid('acknowledged_by'), // Manager der anerkannt / abgelehnt hat resolution: resolutionEnum('resolution'), // pending | accepted_exception | ticket | escalated createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(), hashPrev: bytea('hash_prev'), hashSelf: bytea('hash_self'),}, (t) => ({ tenantUserCreatedIdx: index('arbzg_tenant_user_idx').on(t.tenantId, t.userId, t.createdAt.desc()), ruleIdx: index('arbzg_rule_idx').on(t.tenantId, t.rule),}));
export const balanceAccountsTable = pgTable('balance_accounts', { id: uuid('id').primaryKey().defaultRandom(), tenantId: uuid('tenant_id').notNull(), userId: uuid('user_id').notNull(), accountKind: accountKindEnum('account_kind').notNull(), // ueberstunden | gleitzeit modelId: uuid('model_id').notNull().references(() => balanceModelsTable.id),});
export const balanceLedgerTable = pgTable('balance_ledger', { id: uuid('id').primaryKey(), // UUID v7 tenantId: uuid('tenant_id').notNull(), accountId: uuid('account_id').notNull().references(() => balanceAccountsTable.id), sourceKind: ledgerSourceEnum('source_kind').notNull(), // time_entry | manual_correction | monthly_close | cap | payout sourceId: uuid('source_id'), deltaSeconds: integer('delta_seconds').notNull(), reasonText: varchar('reason_text', { length: 500 }), actorUserId: uuid('actor_user_id').notNull(), effectiveAt: timestamp('effective_at', { withTimezone: true }).notNull(), hashPrev: bytea('hash_prev'), hashSelf: bytea('hash_self'),});
export const balanceSnapshotsTable = pgTable('balance_snapshots', { id: uuid('id').primaryKey(), tenantId: uuid('tenant_id').notNull(), accountId: uuid('account_id').notNull(), snapshotAt: timestamp('snapshot_at', { withTimezone: true }).notNull(), balanceSeconds: integer('balance_seconds').notNull(), hashPrev: bytea('hash_prev'), hashSelf: bytea('hash_self'),});
// Konfigurationexport const balanceModelsTable = pgTable('balance_models', { /* ... */ }); // ÜS / Gleitzeitexport const shiftModelsTable = pgTable('shift_models', { /* ... */ }); // Früh/Spät/Nachtexport const tvExceptionsTable = pgTable('tv_exceptions', { /* ... */ }); // §7 TV-AusnahmenRLS-Policies.
ALTER TABLE arbzg_flags ENABLE ROW LEVEL SECURITY;CREATE POLICY arbzg_tenant ON arbzg_flags USING (tenant_id = current_setting('app.tenant_id')::uuid);CREATE POLICY arbzg_own ON arbzg_flags FOR SELECT USING (user_id = current_setting('app.user_id')::uuid OR current_setting('app.scope') IN ('team','all'));
ALTER TABLE balance_ledger ENABLE ROW LEVEL SECURITY;CREATE POLICY ledger_append_only ON balance_ledger FOR UPDATE USING (FALSE) WITH CHECK (FALSE);CREATE POLICY ledger_insert_scope ON balance_ledger FOR INSERT WITH CHECK ( tenant_id = current_setting('app.tenant_id')::uuid AND current_setting('app.role') IN ('system','hr','admin','buchhaltung') );ER-Bezug. time_entries (aus kern/01), users, absences (aus kern/03), shifts (aus kern/08), holidays.
8. API-Endpunkte
Abschnitt betitelt „8. API-Endpunkte“Alle unter /v1/kern/arbzg/…, hinter module.kern.arbeitszeit_compliance.
| Methode | Pfad | Auth-Scope | Rate-Limit | Idempotenz | Beschreibung |
|---|---|---|---|---|---|
| POST | /v1/kern/arbzg/evaluate |
arbzg:evaluate |
Privileged | Key Pflicht | Serverseitig nach time_entry auslösen (intern) |
| GET | /v1/kern/arbzg/flags?userId=&from=&to= |
arbzg:read:<scope> |
Standard | — | Liste Flags |
| POST | /v1/kern/arbzg/flags/{id}/acknowledge |
arbzg:ack:team |
Standard | Key Pflicht | Manager-Anerkennung einer Ausnahme |
| GET | /v1/kern/arbzg/balances?userId= |
arbzg:read:<scope> |
Standard | — | ÜS + Gleitzeit aktuell |
| POST | /v1/kern/arbzg/balances/corrections |
arbzg:correct:all |
Privileged | Key Pflicht | HR-Korrektur (delta_seconds + Begründung) |
| POST | /v1/kern/arbzg/balances/snapshots |
arbzg:close |
Privileged | Key Pflicht | Monats-Freeze aller Accounts eines Tenants |
| GET | /v1/kern/arbzg/models |
arbzg:config:read |
Standard | — | Modelle lesen |
| PATCH | /v1/kern/arbzg/models/{id} |
arbzg:config:write |
Privileged | Key Pflicht | Modell-Update (mit Audit + ggf. BR-Flag) |
| GET | /v1/kern/arbzg/stream |
arbzg:read:<scope> |
Live (SSE) | — | Push neuer Flags/Ampelzustände |
paths: /v1/kern/arbzg/balances/corrections: post: operationId: createBalanceCorrection x-werkszeit-scope: arbzg:correct:all requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/BalanceCorrectionInput' } responses: '201': { content: { application/json: { schema: { $ref: '#/components/schemas/BalanceLedgerEntry' } } } } '422': { description: 'Begründung < 20 Zeichen oder Kappung überschritten' }Webhook-Events:
arbzg.flag.createdarbzg.flag.acknowledgedbalance.correction.createdbalance.snapshot.created
9. Offline-Profil
Abschnitt betitelt „9. Offline-Profil“| Profil | Begründung | Mechanik |
|---|---|---|
| Best-effort-offline | Anzeige Saldo: letzter Server-Stand wird gecacht; Evaluierung Server-seitig | Drift-Read-Cache + optimistischer ArbZG-Preview client-seitig; verbindliche Flags setzt der Server nach Sync. |
| Online-only | Konto-Korrektur / Konfiguration | UI blockt Button bei connectivity == none mit Toast „erfordert Online“. |
Konflikt-Strategie. Warnung-Engine ist idempotent pro time_entry_id × rule. Mehrfach-Evaluierung erzeugt keine Duplikate; Server hat unique key (tenant_id, time_entry_id, rule).
Foto-/Datei-Sync. Anerkennungs-Dokument (z.B. BR-Beschluss PDF bei F-A-06) via S3-Presigned (Objekt-Lock 10 J).
10. Compliance-Mapping
Abschnitt betitelt „10. Compliance-Mapping“10.1 GoBD
Abschnitt betitelt „10.1 GoBD“arbzg_flags,balance_ledger,balance_snapshotssind append-only mit Hash-Chain pro(tenant_id, user_id).balance_ledgerist das einzige Zugang/Abgang-Journal; jede Korrektur ist eine neue Zeile mit Delta, Begründung und Aktor-Referenz.UPDATEist RLS-seitig blockiert (WITH CHECK (FALSE)).- Snapshots beim Monatsabschluss werden in S3 mit Object Lock Compliance 10 J signiert abgelegt (ed25519).
- Verfahrensdokumentations-Baustein „Überstunden-/Gleitzeit-Konto“ verweist auf Tabellenstruktur + Hash-Verfahren.
10.2 ArbZG (Kern-Gesetz dieses Feinkonzepts)
Abschnitt betitelt „10.2 ArbZG (Kern-Gesetz dieses Feinkonzepts)“- §3 Höchstarbeitszeit — Default-Policy:
day_hours <= 8regulär,day_hours <= 10 && ausgleich_within_6m = trueals TV-Ausnahme. Flag-Severityviolationbei > 10 h ohne Ausnahme,warnbei 10 h mit Ausnahme. - §4 Pausen —
pause_required(duration_h)→ 0/30/45 min. Differenz zwischen Soll und Ist → Flagpause. - §5 Ruhezeit — Zwischen letztem Stop und neuem Start eines Users muss
delta >= 11h(oder10hbei §5 Abs. 2 + TV-Ausnahme). Ausnahme: Pflegeberufe/Gastgewerbe nicht relevant für Handwerk; Notdienst pertv_exceptions-Referenz. - §7 Abweichungen — Admin konfiguriert per
tv_exceptions: Rechtsgrundlage (TV-Name, §-Verweis), neuer Grenzwert, Ausgleichsfenster, Geltungsbereich (Team / alle). Jede Ausnahmen-Erkennung schreibt Rechtsgrundlage-Zitat ins Flag. - §16 Aushangpflicht — Das Tool ersetzt den Aushang nicht, stellt aber eine PDF-Variante des aktuellen ArbZG-Modells generierbar bereit.
10.3 VOB/B
Abschnitt betitelt „10.3 VOB/B“— nicht zutreffend, weil §-Thematik Arbeitsrecht, nicht Werkvertragsrecht.
10.4 DSGVO
Abschnitt betitelt „10.4 DSGVO“- Art. 5. Keine Rohdaten-Spiegelung;
value-JSON speichert nur relevante Teil-Deltas, nicht kompletten Tagesverlauf. - Art. 6. Vertragserfüllung (b) + gesetzliche Pflicht (c — ArbZG).
- Art. 17. Bei MA-Austritt:
reason_text-Felder mit Namensnennungen nach 10 J maskiert, Hashes bleiben. - Art. 20. JSON-Export enthält Flags + Ledger-Zeilen des betroffenen Users, keine Kollegen-Daten.
- Art. 30. VVZ-Eintrag „Arbeitszeit-Compliance-Evaluierung“: Zweck = Gesetzes-Compliance, Empfänger = Manager/HR-Team intern, Löschfrist = 10 J.
- DSFA Pflicht. Ja (systematische Bewertung Leistungsverhalten) — verweist auf die DSFA von
kern/01-zeiterfassung, Delta-Abschnitt für Policy-Engine + Anomalie-Erkennung.
10.5 BFSG / WCAG 2.2 AA
Abschnitt betitelt „10.5 BFSG / WCAG 2.2 AA“- Ampel-Farben (🟢/🟡/🔴) sind nicht der einzige Informations-Träger — jede Zelle trägt Text-Label (
OK · 9:42 h,Ruhezeit 8:15 h). - Screenreader: Dashboard als
<table>mit<caption>, sortierbare Header habenaria-sort. - Kontrast warn-Background
#FBF1DAauf Text#5A3706= 8.2:1. - Keyboard:
J/Knächste/vorige Verletzung,Aanerkennen,Eeskalieren.
10.6 BetrVG §87(1)6
Abschnitt betitelt „10.6 BetrVG §87(1)6“- Ampel-Dashboard selbst ist nicht zustimmungspflichtig (dient dem Gesetzes-Vollzug und reduziert Daten auf Kategorien).
- Anomalie-Erkennung (F-A-06, V1.5): Mustererkennung auf „atypischen“ Mitarbeitern ist Verhaltens-/Leistungskontrolle → BR-Workflow.
- Stempel-Blockade bei §3 >10h wird nicht implementiert (würde in BetrVG §87(1)2 „Beginn/Ende Arbeitszeit“ eingreifen). Wir warnen und protokollieren, aber stoppen niemanden.
10.7 Weitere Spezial-Compliance
Abschnitt betitelt „10.7 Weitere Spezial-Compliance“- MiLoG — Pro Buchung wird MiLoG-Referenz gespeichert (Lohnsatz zum Stichtag). Unterschreitung pro Buchung → Flag
milog_unter. Für Sub-Vergabe wichtig (siehehandwerk-Feinkonzepte). - TV Bau Rahmentarif — §3 Ausnahmen (Notdienst, Winterbeschäftigung) als Preset
tv_exceptions-Seed.
11. Edge-Cases
Abschnitt betitelt „11. Edge-Cases“| # | Szenario | Erwartetes Verhalten |
|---|---|---|
| EC-01 | Zeitzonenwechsel: MA arbeitet Montag in DE, Dienstag in CH, Mittwoch in DE. | UTC-Speicherung. Arbeitszeit-Summen in tenant.timezone (Europe/Berlin). Flag-Berechnung nutzt UTC-Deltas, Anzeige zeigt Wanduhr-Zeit. |
| EC-02 | Tagesgrenze 00:00 — Schicht 22:00–06:00 (Notdienst SHK). | time_entry.kind=start 22:00 auf Tag T, Stop 06:00 auf Tag T+1. §3 bewertet Kette, nicht Kalendertag (8 h im Stück). §5-Check auf nächsten Start ≥ 17:00 des Folgetages. |
| EC-03 | Multi-Tenant: MA Hannes ist Tenant A + B. | Flags pro (tenant, user)-Paar. Konten nicht verrechnet zwischen Tenants. RLS trennt hart. |
| EC-04 | Sync-Konflikt bei späterem Eingang offline erfasster Zeiten, die im Nachhinein §3 auslösen. | Re-Evaluierung ist idempotent (unique(tenant, time_entry_id, rule)). Spät eintreffende Flags werden mit severity markiert und erzeugen Tickets rückwirkend — Monatsabschluss wird nicht rückwirkend verändert (Freeze). |
| EC-05 | Großmenge: Tenant fordert ArbZG-Report 3 Jahre × 80 MA. | Async-Job, PDF-Paket, S3-Download-Link. Query nutzt balance_snapshots + arbzg_flags mit Index (tenant, user, created desc). |
| EC-06 | Abgelaufenes Zertifikat ist nicht ArbZG-relevant, aber Schichtplan sperrt (siehe kern/08). |
Hier kein Einfluss. |
| EC-07 | Plan-Limit: Starter-Plan nutzt nur §3/§4/§5 (Standard). Schichtmodelle nur Business/Pro. | API liefert 403 auf PATCH /models mit code=plan_limit_shiftmodel, UI zeigt Upgrade-Hinweis. |
| EC-08 | Rollen-Demotion: HR verliert Rolle mitten in Bulk-Korrektur. | Request-Level-Scope-Check; laufende Transaktion wird committed bis zum Batch-Ende, weitere Batches 401. Audit zeigt partiellen Abbruch. |
| EC-09 | §7-TV-Ausnahme rückwirkend aktiviert (Admin-Flag erst nach Verletzung gesetzt). | Re-Evaluator läuft (Nightly), wandelt violation → accepted_exception mit Audit-Log. Alte Tickets bleiben einsehbar mit „überschrieben durch Ausnahme“. |
| EC-10 | Sommerzeit 29.03.2026: Arbeitsstunde geht verloren / doppelt. | UTC-Delta-Berechnung korrekt, keine Doppel/Fehlstunde. Anzeige kennzeichnet Wechsel-Tag mit Tooltip. Property-Test C-05 prüft. |
| EC-11 | Manipulierter Client-Timestamp beim Stempeln. | Verwendung Server-occurredAt im Flag-Check (siehe kern/01 EC-11). Flag basiert auf validierter Zeit, nicht auf Client-Behauptung. |
| EC-12 | Auslaufen TV-Ausnahme (Stichtag 30.06.2026). | Config hat valid_until — Evaluator nutzt Ausnahme nur im Geltungszeitraum. Grenzfall genau um 00:00 → occurred_at >= valid_until schließt Ausnahme aus. |
12. Akzeptanzkriterien (Gherkin)
Abschnitt betitelt „12. Akzeptanzkriterien (Gherkin)“Funktionalität: Arbeitszeit-Compliance — ArbZG-Echtzeit, Konten, Schicht
Hintergrund: Angenommen ein Tenant "musterbetrieb-maler" mit aktivem Modul-Gate "module.kern.arbeitszeit_compliance" Und ein Mitarbeiter "Hannes Krüger" mit Rolle "Mitarbeiter" und Scope "own" Und ein Manager "Sabine Maier" mit Rolle "Manager" und Scope "team" Und eine Standard-Konfiguration 40h/Woche, ÜS-Kappung ±30h, Gleitzeit ±20h
Szenario: Happy Path — Saldo sichtbar nach Stempel-Tag Wenn Hannes am 19.04.2026 von 07:02 bis 16:42 mit 32 min Pause arbeitet Dann erscheint in der Saldo-Kachel "Heute 8:08 h" (Arbeitszeit ohne Pause) Und das Überstunden-Konto wird um +0:08 h korrigiert Und ein Audit-Log-Eintrag "balance.ledger.created" existiert
Szenario: Grenzfall — §3 ArbZG Höchstarbeitszeit (BAG-Urteil 1 ABR 22/21 berücksichtigt) Angenommen Hannes hat am 19.04.2026 um 17:20 bereits 10:15 h gearbeitet Wenn das System eine neue Stempelung empfängt Dann entsteht ein arbzg_flag mit rule="haechstarbeitszeit" severity="violation" Und der §3-Ausgleich-Check wird aktiv: Hannes muss innerhalb 6 Monaten einen Ausgleichstag nehmen Und die Buchung bleibt gespeichert (kein Stempel-Block) Und Sabine sieht im Dashboard eine rote Ampel für Hannes
Szenario: Grenzfall — §5 ArbZG Ruhezeit mit Tagesgrenze 00:00 Angenommen Thomas Schmidt hat am 14.04.2026 um 22:15 ausgestempelt Wenn er am 15.04.2026 um 06:30 einstempelt Dann wird eine Ruhezeit von 8:15 h berechnet Und ein arbzg_flag mit rule="ruhezeit" severity="violation" entsteht Und Thomas muss eine Begründung eingeben, bevor der Stempel-Start bestätigt wird Wenn er als Begründung "Notdienst Wasserrohrbruch" angibt Und für den Tenant ist TV-Bau §3 Abs. 1 Buchst. c als Ausnahme konfiguriert Dann wird das Flag mit resolution="accepted_exception" geführt Und das Ticket enthält Rechtsgrundlage-Zitat
Szenario: Grenzfall — Multi-Tenant-Isolation Angenommen ein zweiter Tenant "shk-gebruder-schmidt" Wenn Sabine Maier (Tenant A) per ID ein arbzg_flag aus Tenant B abruft Dann antwortet die API mit "404" Und kein Audit-Log-Eintrag entsteht in Tenant B
Szenario: Grenzfall — Monats-Freeze blockiert rückwirkende Korrektur Angenommen Frau Müller hat März 2026 am 05.04.2026 per balance_snapshot eingefroren Wenn jemand eine balance_correction mit effective_at "28.03.2026" versucht Dann antwortet die API mit "423 Locked" und Code "frozen_period" Und die UI bietet "Einmal-Öffnung anfordern" mit Begründungs-Pflichtfeld Und beim Öffnen entsteht Audit-Log-Eintrag "balance.freeze.reopened"
Szenario: Grenzfall — §7-TV-Ausnahme rückwirkend konfiguriert Angenommen Thomas hat am 14.04.2026 10:45 h gearbeitet, Flag "haechstarbeitszeit" severity="violation" Wenn Admin am 16.04.2026 eine TV-Bau-Ausnahme mit valid_from=01.04.2026 aktiviert Dann läuft der nightly Re-Evaluator Und das Flag wechselt zu resolution="accepted_exception" mit Hinweis "§7 ArbZG i.V.m. TV Bau" Und ein neuer ledger-Eintrag "flag.resolution_changed" wird geschrieben Aber der ursprüngliche violation-Eintrag bleibt lesbar (GoBD §145 AO)13. Test-Cases
Abschnitt betitelt „13. Test-Cases“13.1 Unit-Tests
Abschnitt betitelt „13.1 Unit-Tests“- U-01 —
ArbzgEvaluator.haechst(entries)— property-basiert über zufällige 24h-Ketten (glados/fast-check), 1000 Iterationen. - U-02 —
ArbzgEvaluator.ruhezeit(prevStop, newStart, tvExceptions)— Matrix 11h/10h × Ausnahme ja/nein. - U-03 —
BalanceLedger.applySum(entries)ist assoziativ (A + B + C == A + (B + C)). - U-04 —
HashChain.verify(ledger)detektiert Mutationen. - U-05 — Sommerzeit-Umstellung:
diffHours(22:00 CET, 06:00 CEST)= 7h (29.03.), = 9h (25.10.).
13.2 Widget-/Component-Tests
Abschnitt betitelt „13.2 Widget-/Component-Tests“- W-01 — Saldo-Kachel Darstellung negativer Werte (−2:00 h) mit roter Farbe und Screenreader-Label.
- W-02 — ArbZG-Warnung Golden iOS/Android × Light/Dark.
- W-03 — Ampel-Dashboard mit 50+ Zeilen: Tab-Navigation landet nie in Endlos-Loop.
13.3 Integrations-Tests
Abschnitt betitelt „13.3 Integrations-Tests“- I-01 — Multi-Tenant-Isolation Flags + Ledger.
- I-02 — Idempotenz Evaluator: doppelt triggern → 1 Flag.
- I-03 — Monats-Freeze: Nach Snapshot blockt Insert auf
balance_ledgermiteffective_at < snapshot_at. - I-04 — RLS: Mitarbeiter sieht nur eigene Flags/Ledger.
- I-05 — HR-Korrektur unter 20 Zeichen Begründung → 422.
13.4 E2E-Tests
Abschnitt betitelt „13.4 E2E-Tests“- E-01 — Happy-Path Saldo + Warnung auf Mobile + Web.
- E-02 — Ruhezeit-Begründung-Dialog, inkl. Abbruch-Pfad.
- E-03 — Manager erkennt §5 an, Status wechselt, Audit-Eintrag sichtbar.
- E-04 — Visual Regression Dashboard.
- E-05 — Accessibility axe-core grün.
13.5 Compliance-Tests
Abschnitt betitelt „13.5 Compliance-Tests“- C-01 — Hash-Chain Integrität über
balance_ledger(Manipulation erkennbar). - C-05 — ArbZG-Property-based über §3/§4/§5/§7-Kombinationsraum (zufällige Schichtketten + TV-Ausnahmen).
- C-06 — REB-ähnliche Referenz-Ketten:
arbzg_fixtures/mit 50 handgepflegten Schicht-Szenarien (BAG-Urteile, Amtliche Beispiele); Evaluator muss exakte Flag-Liste liefern. - C-07 — Sommerzeit-Property (29.03. + 25.10.2026).
13.6 Flakiness-Schutz
Abschnitt betitelt „13.6 Flakiness-Schutz“E-01/E-03 20×-Lauf grün; Property-Tests seed-stabil.
14. Nicht-Ziele
Abschnitt betitelt „14. Nicht-Ziele“| Nicht-Ziel | Begründung |
|---|---|
| Stempel-Blockade bei §3-Überschreitung | Eingriff BetrVG §87(1)2 + Reputationsrisiko. Wir warnen + dokumentieren. |
| Auto-Ausgleich ÜS-Konto via Kalendereintrag | Kalender-Integration = Werkszeit Office (V3). Hier nur Kontengang, kein Kalender-Push. |
| Gehaltsberechnung / Lohn-Auszahlung | DATEV-Lohnlauf ist Buchhalter-Domäne. Werkszeit liefert Vorauflage, nicht Payroll. |
| Historische Alt-Daten-Import in Konten | Separater Migrationsassistent (V1). Im MVP CSV-Seed, wenn Kunde braucht. |
| Weltweite Tarif-Ausnahmen (Metall, Chemie …) | TV-Bau-Preset reicht für Handwerk. Weitere TVs bei Referenzkunde-Fall. |
| Aktives Geofencing zur Ruhezeit-Erkennung | BetrVG-Freischaltung disproportional. Wir rechnen mit Stempelzeiten — reicht. |
| SMS-Eskalation an HR bei Verletzung | BSI-Bedenken + Eskalationspfad über E-Mail + Push. |
| Automatische §-Zitate-Anwaltsberatung | Keine Rechtsberatung. Wir zeigen §-Referenz + Text, Haftungsausschluss. |
15. Risiken & offene Annahmen
Abschnitt betitelt „15. Risiken & offene Annahmen“| Risiko / Annahme | Impact | Wahrscheinlichkeit | Gegenmaßnahme |
|---|---|---|---|
| ArbZG-Novelle tritt mit anderen Grenzwerten in Kraft | hoch | mittel | Evaluator-Parameter tenant-unabhängig seitens Werkszeit konfigurierbar; Policy-Update via Admin-Migration + BR-Info. |
| TV-Bau-Auslegung bei Notdienst — Anwalt-Review nötig | hoch | hoch | §7-Ausnahmen-Preset wird juristisch validiert, Disclaimer im UI „keine Rechtsberatung“. |
| Performance Live-Evaluator bei 80-MA-Tenant × 2.000 Entries/Woche | mittel | mittel | Evaluator als BullMQ-Worker pro time_entry (async); UI sieht Flags via SSE; p95 < 2 s. |
| Sommerzeit / Zeitzonen-Bugs | hoch | niedrig | Property-Tests decken beide Umstellungen; UTC-Storage-Invariante; CI-Gate. |
| Konten-Drift zwischen Client-Cache und Server | mittel | mittel | Server ist Autorität, Client zeigt Zeitstempel „Stand 13:42“. Refresh bei App-Foreground. |
| Float-Rundung Saldo-Berechnung | mittel | hoch | Int-Sekunden statt Float-Stunden; alle Deltas als integer('delta_seconds'). |
| Audit-Log-Wachstum bei Tenant mit vielen Warnungen | niedrig | mittel | Partitionierung nach Monat; Glacier-Archivierung > 2 Jahre mit Object-Lock-Übernahme. |
| Referenzkunde-Verfügbarkeit — wer testet §7-TV-Ausnahmen? | hoch | mittel | SHK-Betrieb mit Notdienst als Pflicht-Design-Partner; Fallback über Berufsverband-Kooperation. |
16. Abhängigkeiten
Abschnitt betitelt „16. Abhängigkeiten“- Vorbedingung:
kern/01-zeiterfassungliefert den Stream;kern/09-authentifizierungliefert Session-/Rollen-Context; Feiertags-Tabelle & Bundesländer-Lookup bereit. - Schnittstelle zu:
kern/01— konsumierttime_entries, schreibtarbzg_flagszurück.kern/03-abwesenheiten— Urlaubs- und Krankheitszeiten reduzieren nicht das ÜS-Konto, erhöhen aber die Ist-Erfüllung (kein §3-Flag an Kranktagen).kern/08-dienstplanung— Soll-Schicht liefert Referenz für Abweichungs-Berechnung (Ist − Soll = Gleitzeit-Delta).kern/10-datev-integration— Exportiertbalance_snapshotsals Lohn-Vorlage (Zuschläge, Ausgleich).
- Wird konsumiert von:
kern/07-reporting,handwerk/03-stundennachweis(ArbZG-Flags erscheinen als Anmerkung).
17. Referenzkunde-Slot
Abschnitt betitelt „17. Referenzkunde-Slot“Status: TBD.
Kandidaten-Profile:
- SHK-Betrieb 50–100 MA mit Notdienst (häufige §5-Verletzungen, TV-Bau-Ausnahmen erforderlich) — Archetyp für §7-Konfiguration.
- Malerbetrieb 15–30 MA mit Gleitzeit und wenig Schicht → deckt Standard-Fall ab.
- Facility-Services 80+ MA mit 3-Schicht-Rotation → deckt V1 Schichtmodelle.
Validierungs-Fragen:
- Welche ArbZG-Verletzungen sehen Sie im Monat? Wie sind Sie heute aufgefallen (BR / Betriebsprüfung / eigener Audit)?
- Welches TV-Bau-Regime (West/Ost) nutzen Sie? Haben Sie eine Betriebsvereinbarung zur Ruhezeit?
- Führen Sie Überstunden-/Gleitzeit-Konten heute auf Papier, Excel oder Tool? Welche Kappungs-Regel haben Sie dokumentiert?
- Ist Ihr BR für Auslesen von Arbeitszeiten an konkrete Zustimmung gebunden?
- Würden Sie 30 Tage im Beta testen und einen Wochenbericht „was wurde erkannt, was fehlt“ liefern?
18. Senior-Berater-Empfehlung
Abschnitt betitelt „18. Senior-Berater-Empfehlung“Build-Sequenz.
- Datenmodell + RLS + Hash-Chain (
arbzg_flags,balance_ledger,balance_snapshots) + Multi-Tenant-Test. - Evaluator als pure function in TS (Node 22) + Property-Tests mit fast-check — deterministisch, ohne DB.
- BullMQ-Worker für async Evaluation pro
time_entry.created-Event. - SSE-Stream + Client-State (Riverpod) + Mobile-UI für Saldo & Warnung.
- Web-Dashboard + Verletzungs-Detail.
- Admin-Konfiguration + BR-Workflow (F-A-06 erst V1.5, aber UI-Gerüst ab V1 vorbereiten).
- Compliance-Tests C-05/C-06/C-07 + externe Review mit Fachanwalt Arbeitsrecht.
Risiko-Reihenfolge.
- Hash-Chain + Property-Tests sind nicht verhandelbar. Dashboard-Politur und Chart-Ästhetik sind Streich-Kandidaten.
- Schichtmodelle und §7-Presets können in V1 verschoben werden, Echtzeit-§3/§4/§5 muss MVP.
Stop-the-Bus-Triggers.
- Property-Test-Bruch bei §3/§5 (auch an einem Seed).
- Sommerzeit-Test schlägt fehl.
- Salden-Differenz Client vs. Server > 1 min bei identischem Datum.
- Anwaltliche Einschätzung weicht von Evaluator-Default ab (muss konfigurierbar abbildbar sein, sonst ADR).
Was uns 2027 dankbar macht:
Ein sekundengenaues, hash-chained Ledger pro Mitarbeiter + ein konfigurierbarer Evaluator ohne hartcodierte §-Werte macht jede künftige ArbZG-Novelle und jeden TV-Wechsel zu einer Konfig-Änderung, nicht zum Code-Release. Die Alt-App hatte Geschäftsregeln in pzeAze.js verdrahtet — das war ein Tech-Debt-Produzent. Hier bauen wir ab Tag 1 eine Policy-Engine, die wir in drei Jahren auch für Werkszeit Office wiederverwenden können.
Feinkonzept-Stand: 2026-04-19 · Werkszeit Konzeptions-Team · Greenfield Phase 1 · Version v0.1
Für Entwickler — API-Endpoints11
| Methode | Pfad | Auth | Zweck |
|---|---|---|---|
| GET | /v1/kern/arbzg/balances | bearerAuth | Überstunden-/Gleitzeit-Konten auflisten |
| POST | /v1/kern/arbzg/balances/corrections | bearerAuth | HR-Korrektur auf einem Balance-Konto |
| POST | /v1/kern/arbzg/balances/snapshots | bearerAuth | Monats-Freeze aller Konten eines Tenants |
| POST | /v1/kern/arbzg/evaluate | bearerAuth | ArbZG-Auswertung eines Time-Entry triggern (intern) |
| GET | /v1/kern/arbzg/flags | bearerAuth | ArbZG-Flags auflisten |
| GET | /v1/kern/arbzg/flags/{id} | bearerAuth | Einzelnes ArbZG-Flag |
| POST | /v1/kern/arbzg/flags/{id}/acknowledge | bearerAuth | Manager-Anerkennung einer Ausnahme |
| GET | /v1/kern/arbzg/models | bearerAuth | ArbZG-Modelle auflisten |
| POST | /v1/kern/arbzg/models | bearerAuth | ArbZG-Modell anlegen |
| PATCH | /v1/kern/arbzg/models/{id} | bearerAuth | ArbZG-Modell aktualisieren |
| GET | /v1/kern/arbzg/stream | bearerAuth | SSE-Stream für neue Flags / Ampel-Übergänge |