feat: agent-12 – Zwei-Stufen-Genehmigung für Abwesenheiten

Optionale zweistufige Freigabe (Feature-Parität mit Urlaubsverwaltung,
Second-Stage-Authority), ohne SSO:

- Firmen-Opt-in companies.two_stage_approval_enabled + two_stage_min_days
  (nur Anträge ab X Arbeitstagen brauchen Stufe 2; 0 = alle).
- Ablauf PENDING → FIRST_APPROVED → APPROVED: erste Stufe durch Manager-Rollen,
  finale Stufe nur HR/Admin und zwingend eine ANDERE Person als Stufe 1.
- Urlaubs-/FZA-Abzug, CalDAV-Sync und Vertreter-Mail erst bei finaler Genehmigung.
  Ablehnen in beiden Stufen möglich; Eigentümer darf FIRST_APPROVED noch stornieren.
- pending_days, Kalender und Reminder-Digest berücksichtigen FIRST_APPROVED.
- Neuer Status-Wert + absences.first_approved_by; System-Kommentar bei Stufe 1.

Frontend: CompanySettingsPage (Toggle + Schwellwert), AbsencesPage
("Endgültig genehmigen"/Ablehnen für HR/Admin ≠ Erstgenehmiger, Status-Badge).

Migration 0038. 190/190 Tests grün. Deployed 137 + 164.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-23 13:17:32 +02:00
co-authored by Claude Opus 4.8
parent 2f110df619
commit eab41ede69
12 changed files with 198 additions and 7 deletions
+2
View File
@@ -18,6 +18,7 @@ export const STATUS_LABELS: Record<string, string> = {
rejected: 'Abgelehnt',
cancelled: 'Storniert',
cancellation_requested: 'Storno beantragt',
first_approved: 'Wartet auf Endgenehmigung',
}
export const STATUS_COLORS: Record<string, string> = {
@@ -26,6 +27,7 @@ export const STATUS_COLORS: Record<string, string> = {
rejected: 'bg-red-100 text-red-700',
cancelled: 'bg-gray-100 text-gray-500',
cancellation_requested: 'bg-orange-100 text-orange-700',
first_approved: 'bg-sky-100 text-sky-700',
}
export const MANAGER_ROLES = ['COMPANY_ADMIN', 'SUPER_ADMIN', 'HR', 'MANAGER']