- CSRF-Schutz auf allen mutierenden Endpunkten:
#[NoCSRFRequired]wurde auf POST/PUT/DELETE-Methoden inAbsenceController,TimeEntryController,TimeTrackingController,ComplianceController,SubstituteController,SettingsController,MonthClosureController,GdprControllerundAdminControllerentfernt. Das Frontend sendetrequesttokenbereits konsistent überArbeitszeitCheckUtils.ajax; mutierende Routen lehnen Cross-Site-Anfragen damit per Default ab. Reine GET-Endpunkte bleiben bewusst#[NoCSRFRequired](CSRF ist für Read-Only-GETs im Nextcloud-Framework nicht relevant). - Keine ungefilterten Exception-Texte mehr in JSON-Antworten:
AbsenceController::getSafeErrorMessagewurde gehärtet – Exception-Nachrichten werden nur dann weitergereicht, wenn sie aus expliziten Business-Rule-\Exception-Klassen stammen; Texte mit technischen Indikatoren (SQL-Fragmente, Pfade, Stacktraces, übergroße Payloads) werden durch eine generische lokalisierte Fehlermeldung ersetzt. Der gehärtete Helper wird inAbsenceController::store/updateverwendet. DirektegetMessage()-Leaks inAdminController::getTeams,SettingsController::index_apiund in den Page-Render-Fehlerpfaden desPageControllerwurden durch sanitisierte, übersetzte Texte ersetzt. - Korrekter HTTP-Status bei Auth-Fehlern:
SettingsController::updateliefert bei unauthentifizierten Aufrufen jetztHTTP 401 Unauthorized(vorherHTTP 400 Bad Request), damit API-Clients und Loadbalancer das richtige Verhalten erkennen.
- Organisations-weiter Monats-Report-Download:
reports.jsreicht die im Preview ermittelten User-IDs an denreport.team-Endpunkt weiter und zeigt bei leerem Organisations-Preview die klare Meldung „Im gewählten Zeitraum hat keine Person der Organisation Arbeitszeit erfasst – es gibt nichts herunterzuladen." statt des irreführenden Hinweises auf einen erforderlichen Preview. - Sanitisierte Dashboard-Fehleranzeige:
dashboard.js/dashboard.csszeigen statt roher Widget-Exceptions eine lokalisierte Live-Region-Meldung „Einige Dashboard-Daten konnten nicht geladen werden.". - „Resume after break" vereinheitlicht: Clock-In-Texte und l10n verwenden konsistent „Resume after break" anstelle des Platzhalters
clock_in_resume.
- Landmark
<main>auf allen Seiten: 17 Page-Templates exponieren jetzt jeweils genau ein<main id="app-content" role="main" aria-label="...">-Landmark für Hilfstechnologien (dashboard,index,timeline,calendar,settings,personal-settings,reports,compliance-dashboard,compliance-reports,compliance-violations,working-time-models,admin-dashboard,admin-teams,admin-users,admin-holidays,manager-dashboard,manager-time-entries,manager-absences,manager-month-closures). - Skip-Link /
<main>-Konsistenz:time-entries,absences,admin-settings,admin-notifications,substitution-requestsundaudit-loghattenid="app-content"auf einem reinen<div>, währendrole="main"auf dem Kind-Wrapper saß – der Skip-Link „Zum Hauptinhalt springen" landete dadurch auf einem Nicht-Landmark. Alle sechs Templates verwenden jetzt direkt<main id="app-content" role="main">. Das überflüssigerole="banner"auf dem<header>innerhalb der Main-Region vonaudit-logwurde entfernt. - Zugängliche Namen auf allen Datentabellen: Die Feiertagsliste und die beiden Benachrichtigungs-Matrix-Tabellen erhalten
aria-label/aria-labelledbyplus eine Screenreader-<caption>; sie hatten zuvor keinen zugänglichen Namen. - Live-Fehlermeldung im Dashboard: Der Dashboard-Fehlerbereich liegt in einer
aria-live-Region; teilweise Widget-Fehler werden angekündigt, ohne den Fokus zu stören. - Manager-Dashboard-Kennzahlen jetzt vorlesbar: Die Statistik-Werte (Teammitglieder / Heute aktiv / Stunden heute / Offene Anträge) hatten
aria-hidden="true"auf den Wert-Spans – Screenreader-Nutzer:innen verloren damit jede einzelne Zahl. Jede Karte exponiert jetzt einen vollständig vorlesbaren Namen (z. B. „5 Teammitglieder heute aktiv") über einenrole="group"-Wrapper; das visuelle Layout bleibt identisch. - Konflikt zwischen
role="alert"undaria-live="polite"aufgelöst: Das überschreibendearia-live="polite"wurde inabsences.php(Formularfehler),admin-settings.php(globaler Fehlerbanner) und drei Inline-Fehlern im Time-Entry-Formular entfernt.role="alert"impliziert bereits assertive Ankündigungen;politehatte kritisches Validierungsfeedback für Hilfstechnologien verzögert. - Heading-Hierarchie normalisiert: Jedes Hauptseiten-Template hat jetzt genau ein
<h1>(dashboard, time-entries, absences, calendar, timeline, reports, settings, personal-settings, compliance-dashboard, compliance-reports, compliance-violations, working-time-models, admin-dashboard, admin-users, admin-holidays, admin-settings, admin-notifications, manager-dashboard). Die meisten Seiten begannen vorher bei<h2>. Untergeordnete Section-Überschriften in time-entries und absences wurden aufh2/h3angehoben, sodass keine Ebene mehr übersprungen wird. Eine Stilregel für.section-header h1wurde ergänzt, damit die bestehendeh2-Optik erhalten bleibt. - Breadcrumb im Manager-Dashboard: Standard-Breadcrumb „Dashboard › Manager Dashboard" ergänzt – konsistent mit allen anderen Hauptseiten und besser orientiert für Tastatur- und Screenreader-Nutzer:innen.
- Kalender-Ladezustand wird angekündigt: Der „Kalender wird geladen…"-Platzhalter nutzt jetzt
role="status"mitaria-live="polite"; Lade- und Fertig-Übergänge werden angekündigt, der dekorative Spinner istaria-hidden. - Fokus-Indikatoren wiederhergestellt:
outline: noneauf den Timeline-Filter-Checkboxen und den Admin-Userpicker-Items hatte die Tastatur-Fokussichtbarkeit unterdrückt. Beide haben jetzt:focus-visible-Outlines in der Primärfarbe; Hover-Stile bleiben erhalten. - Touch-Ziele auf Mobile:
.btn--smwar auf Mobilgeräten 36 × 36 px – unterhalb der WCAG-2.5.5-Empfehlung von 44 × 44 px. Die Mobile-Media-Query erzwingt jetzt 44 × 44 px für kleine Buttons; Desktop-Größen bleiben unverändert. - Empty-State-Zeile im Legacy-
index.php-Time-Entries-View: Fehlende Empty-State-Zeile bei leerer Liste wiederhergestellt (Parität mit den anderen Tabellen-Views im selben Template). - Reports-Zugang: Fallback-Navigation: Inline-
onclick-Redirect in der „Kein Zugriff"-Empty-State vonreports.phpdurch einen echten<a>-Link ersetzt – funktioniert auch ohne JavaScript und folgt Standard-Link-Semantik.
- Veraltetes Personal-Settings-Panel im Nextcloud-Settings-Bereich: Das alte
personal-settings.php-Panel im Nextcloud-User-Settings-Bereich enthielt hartcodierte Felder für Urlaubstage / tägliche Arbeitszeit und Erinnerungs-Checkboxen, die nie an ein Backend angebunden waren. Ersetzt durch ein klares Info-Panel, das die Nutzer:innen zur In-App-Personal-Settings-Seite (dort werden Einstellungen real überSettingsController::updatepersistiert) leitet, plus einem kurzen DSGVO-Hinweis. Im Legacy-index.php-Settings-Branch (toter Code, aber noch im Code) wurde der hartcodierte Versionsstring1.0.1durchIAppManager::getAppVersion('arbeitszeitcheck')ersetzt.
- AccessibilityTest gehärtet: Die Assertion „muss
<button>enthalten" (die Seiten ohne tastaturerreichbare Steuerelemente erlaubte und reine Link-Panels fälschlich beanstandete) wurde durch zwei strengere Prüfungen ersetzt: (1)<div onclick=…>-Anti-Pattern explizit verbieten und (2) mindestens ein<button>oder<a href>pro auditiertem Template erzwingen. Gesamte Suite: 455 Tests, 1 652 Assertions, alle grün.
- Audit-Checkliste für kritische Workflows:
tests/WORKFLOW_AUDIT_CHECKLIST.mdergänzt als kompakte Release-Checkliste für Zeiterfassung, Korrekturen manueller Einträge, Abwesenheiten/Genehmigungen, Monatsfinalisierung, Reporting/Compliance/Export und öffentliche Fehleroberflächen.
- Mutationssicherheit in der Zeiterfassung: Clock-/Pausen-Mutationen nutzen nun nutzerspezifische Locks und Transaktionen; Statusabfragen bleiben read-only, während automatische Pausen-Fallbacks und Tagesmaximum-Finalisierung über explizite Mutationspfade/Hintergrundjobs laufen.
- API-Eingaben und Fehlerbehandlung gehärtet: Report-, Export-, Compliance-, Manager- und Time-Tracking-Endpunkte verwenden strengere Datums-/Zeitvalidierung, sichere Validierungsantworten und generische öffentliche Fehlermeldungen bei unerwarteten Fehlern.
- Monatsabschluss konsequenter durchgesetzt: Abwesenheits-Update/Delete/Cancel/Shorten/Freigabe-/Vertretungsflows prüfen die Änderbarkeit des Monats erneut, bevor Workflow-Mutationen geschrieben werden.
- Fingerprinting am Health-Endpunkt: Die öffentliche Health-Antwort enthält keine App- oder Nextcloud-Versionsfelder mehr.
- Forensik bei Abwesenheitsfreigaben:
approved_by_user_idwird nun direkt am Abwesenheitsdatensatz gespeichert (Freigabe/Ablehnung/Auto-Freigabe), inkl. Migration und API-Ausgabe.
- Integrität der Urlaubsanspruch-Snapshots: Deterministisches Key-Upsert auf
(user_id, period_key, as_of_date)ergänzt und per Migrations-Unique-Index auf Datenbankebene abgesichert. - Nebenläufigkeitskontrolle in kritischen Workflows: Create/Update/Approve/Reject/Substitute-Flows sind nun mit nutzerspezifischen Mutations-Locks plus transaktionalen Rechecks/Row-Locks abgesichert, um Race-Conditions bei Überschneidungen und Überfreigaben zu verhindern.
- Release-Absicherung: Workflow-bezogene Unit- und Integrationstests wurden auf die gehärteten Mutationspfade angepasst und erfolgreich ausgeführt.
- Legacy-Snapshot-Reparaturpfad: Upsert behandelt historische fehlerhafte Zeilen sowie parallele Unique-Key-Konflikte robust via deterministischem Retry-Update.
- Race-Condition bei Resturlaub-Updates:
VacationYearBalanceMapper::upsertlöst gleichzeitige Unique-Key-Konflikte jetzt per Re-Read/Update-Fallback.
- Release-Paket aktualisiert: App-Metadaten auf
1.2.5angehoben und den signierten Release-Artefaktsatz für App-Store- und GitHub-Veröffentlichung neu erzeugt.
- Release-Stand veröffentlichbar gemacht: App-Metadaten auf
1.2.4angehoben und ein neuer signierter Release-Artefaktsatz (Archiv, Checksummen, App-Store-Signatur) für App-Store-/GitHub-Veröffentlichung erstellt.
- Release-Paket aktualisiert: Neues signiertes App-Store-/GitHub-Release-Archiv für den aktuellen Code-Stand mit Docker-basiertem Signatur-Workflow erstellt.
- Lokalisierte Dezimaleingaben in den Admin-Einstellungen: Tagesstunden-Felder akzeptieren jetzt zuverlässig Kommawerte wie
7,74und behalten zwei Nachkommastellen korrekt bei. - Parsing bei Legacy-Hours-Payloads: Time-Entry-Endpunkte verarbeiten optionale Stundenwerte nun konsistent mit Komma und Punkt, sodass in rückwärtskompatiblen Requests keine stillen Abschneidungen mehr auftreten.
- Präzisionshinweise in Eingabefeldern:
step-Werte und Hilfetexte wurden auf Zwei-Nachkommastellen-Szenarien (z. B. 38,7-Stunden-Woche) abgestimmt.
- Wiederzugriff auf pausierte Einträge: Pausierte Einträge sind im Bearbeiten-/Löschen-Workflow wieder erreichbar und werden beim Speichern mit Endzeit konsistent als
completedfinalisiert. - Fortsetzen statt Duplikat bei gleichem Tag:
Clock Insetzt einen pausierten Tages-Eintrag fort, statt einen neuen automatischen Eintrag zu erzeugen; die Pausenlücke wird korrekt als Break-Historie archiviert. - Historische Restfälle bei
paused: Neue MigrationVersion1020Date20260421000000repariert verbleibende verwaistepaused-Datensätze (auch Fälle außerhalb der früheren Einmal-Migration).
- Auto-Fallback mit Nachvollziehbarkeit: Zeiteinträge speichern jetzt
ended_reasonundpolicy_applied(z. B.manual_clock_outoderauto_break_fallback) für klare Audit-/Export-Nachweise. - Einmalige Nutzerinfo nach Auto-Ausstempeln: Beim nächsten Statusabruf wird eine neutrale, konkrete Meldung mit Uhrzeit und Regel eingeblendet.
- Urlaubsanspruch-Policy-Engine: Neue berechnungslogikbasierte Anspruchsermittlung mit Modi
manual_fixed,model_based_simple,tariff_rule_basedundmanual_exceptioninkl. Simulations-Endpunkt für Admins. - Tarifregel-Datenmodell und APIs: Versionierte Tarif-Regelwerke/Module sowie Admin-Endpunkte zum Erstellen, Aktualisieren, Aktivieren, Stilllegen und Zuweisen von Urlaubs-Policies.
- Snapshots der Anspruchsberechnung: Persistente Snapshots (
at_entitlement_snapshots) mit Berechnungstrace/Policy-Fingerprint für Nachvollziehbarkeit und Diagnose. - Neue Admin-Seite „Benachrichtigungen“: Eigene Oberfläche für HR-Empfänger und Ereignis-Matrix inkl. dedizierter Notifications-API.
- Fallback-Logik differenziert nach Einsatzart: Für Schichtarbeit gilt standardmäßig eine strikte Fallback-Regel; für Nicht-Schichtmodelle eine flexible Regel mit tagsüber konfigurierbarem Ruhefenster (z. B. Familien-/Mittagsunterbrechung ohne Auto-Ausstempeln).
- Export-Transparenz: CSV/JSON-Zeilen enthalten jetzt
ended_reasonundpolicy_applied, damit automatische Beendigungen in Reports eindeutig erkennbar sind. - Urlaubsallokation integriert: Jahresallokation nutzt nun die neue
VacationEntitlementEngineund liefert Quelle/Regelwerk/Trace in der Ergebnisstruktur zurück. - Migrations-Kompatibilität: Bestehende Urlaubswerte aus Nutzer-Modellzuweisungen werden in Policy-Zuordnungen überführt (
Version1018Date20260420123000), damit Bestandsinstallationen konsistent weiterlaufen. - Admin-Einstellungsfluss für Abwesenheiten: Carryover-/Rollover-, Vertretungs- und E-Mail-Schalter sind zentral über die neue Notifications-Seite/API steuerbar.
- Schema Arbeitszeitmodelle:
at_modelsenthält jetztwork_days_per_week(Version1019Date20260420150000) als Grundlage für Formeln.
- Aufräumen bei Nutzerlöschung: Beim Entfernen eines Nutzers werden jetzt auch Urlaubs-Policy-Zuordnungen und Entitlement-Snapshots gelöscht (keine verwaisten Policy-/Berechnungsdaten).
- Zeitzonen-Konsistenz (Europe/Berlin): Server-/PHP-Zeitzone für ArbeitszeitCheck auf Deutschland ausgerichtet; neue Migration
Version1015Date20260415120000konvertiert bestehende UTC-DATETIME-Werte in App-Tabellen nachEurope/Berlinund setztapp_timezoneexplizit. - Ausstempeln-Semantik korrigiert:
clockOut()finalisiert Einträge nun zuverlässig mitend_timeundstatus=completed(stattpausedohne Endzeit). Dadurch sind Exporte/Reports wieder vollständig und konsistent. - Historische Pausiert-Einträge repariert: Migration schließt verwaiste Einträge mit
status=pausedundend_time IS NULLautomatisch überend_time = updated_atund Statuswechsel aufcompleted. - Mehrfach-Pausen ohne Datenverlust: Beim Start einer weiteren Pause wird die zuvor abgeschlossene Pause zuerst in
breaks(JSON) archiviert; Break-Dauern bleiben vollständig für ArbZG-Prüfungen erhalten. - Break-Status-Berechnung korrigiert:
getBreakStatus()zählt aktive Sitzungszeit nicht mehr doppelt; Warnstufen und Restpausen-Hinweise sind wieder korrekt. - Export-Spalten korrigiert:
duration_hoursliefert jetzt Brutto-Dauer (Wall-Clock),working_hoursNetto-Arbeitszeit (abzgl. Pausen). Vorher waren beide Spalten identisch.
- Export-Transparenz: CSV/JSON-Exporte enthalten jetzt explizite Zeitzonen-Metadaten (
timezone,exported_at), damit nachgelagerte Systeme die Uhrzeiten eindeutig interpretieren. - UI-Klarheit: Dashboard zeigt sichtbaren Zeitzonen-Hinweis (
Europe/Berlin (MEZ/MESZ)), Export-Hinweis auf der Zeiteintragsseite nennt die verwendete Zeitzone. - Bediensicherheit: Vor
Clock Outerscheint eine Bestätigungsabfrage mit klarer Abgrenzung zwischen „Pause starten“ und „Ausstempeln“. - Admin-Transparenz: In den Admin-Einstellungen wird die konfigurierte Zeitzone sichtbar angezeigt.
- Genehmigungs-Deadlock (App-Teams): Abwesenheiten und Zeiteintrags-Korrekturen behandeln „hat Kolleg:innen“ nicht mehr wie „hat eine:n Vorgesetzte:n“. Auto-Genehmigung, wenn kein zuweisbarer Genehmiger existiert, folgt
TeamResolverService::hasAssignableManagerForEmployee()(explizite Team-Manager bei App-Teams; Legacy-Gruppenmodus weiterhin Kollegen-Proxy). Verhindert Anträge, die dauerhaft auf Managerfreigabe warten, obwohl niemand freigeben darf. - Zeiteintrags-Korrekturen: Gleiche Zuweisbarkeitsregel wie bei Abwesenheiten (zuvor nur Kollegen-IDs).
- Admin-Users API auf
/index.php-Instanzen: Refresh/Edit/History/Update nutzen nun zuverlässig aufgelöste App-URLs; fehlerhafte Requests wiesearch=[object PointerEvent]treten nicht mehr auf. - Admin-Teams und Settings auf Rewrite-losen Setups: Zentrale URL-Auflösung enthält jetzt einen robusten
/index.php-Fallback, wennOC.generateUrl()im Seitenkontext fehlt oder unvollständig ist.
- Repair-Schritt
ReleaseStuckPendingAbsences: setzt nach Migration verbliebenepending-Abwesenheiten unter derselben Bedingung automatisch auf genehmigt (idempotent). - Frontend-URL-Sicherheitsleitplanken: Die gemeinsame AJAX-Schicht blockiert externe Cross-Origin-Calls standardmäßig (explizit
allowExternal: truenötig); Unit-Tests decken URL-Normalisierung und External-Handling ab. - Lint-Leitplanken: ESLint-Regeln verhindern neue rohe
fetch('/apps/arbeitszeitcheck/...')-Aufrufe und implizite externefetch(...)-Nutzung außerhalb der vorgesehenen Abstraktionen.
- UX: Abwesenheiten zeigen einen Hinweis, wenn App-Teams aktiv sind und kein Genehmiger zugeordnet ist; in der Detailansicht erscheint bei veralteten hängenden Anträgen ein Warnhinweis (bis Repair/Admin die Teamkonfiguration korrigiert).
- Frontend-Architektur:
ArbeitszeitCheckUtilsstellt nun zentralgetRequestToken(),resolveUrl()undisExternalUrl()bereit; genutzt u. a. inadmin-users,reports,settingsundvalidation. - Mobile UX Konsistenz (WCAG 2.1 AA): iPhone-Safe-Area-konforme Abstände, bessere Touch-Targets, klarere Abschnittsstruktur und visuelle Hierarchie für Nutzerseiten (
dashboard,time-entries,absences) sowie Managerseiten (manager-dashboard,manager-time-entries, Mitarbeiter-Abwesenheiten).
- Nutzerhandbücher (EN/DE),
tests/WORKFLOW_ROLE_MATRIX.mdund Entwicklerdokumentation zur Semantik „zuweisbarer Manager“ und zum Repair-Schritt ergänzt. - README und Entwicklerdokumentation um zentrale Frontend-URL-Policy, striktes External-Call-Verhalten und Mobile/iOS-Layout-Hinweise ergänzt.
- Monatsabschluss: Karenz und Auto-Finalisierung: Admin-Einstellung
month_closure_grace_days_after_eom(0–90, Standard 0). Nach Monatsende haben Mitarbeitende so viele Kalendertage zur manuellen Finalisierung; ist der Monat danach noch offen, finalisiert ein täglicher Hintergrundauftrag automatisch (gleicher Snapshot wie manuell). Ausstehende Zeiteintragsfreigaben und offene Abwesenheits-Workflows blockieren die Auto-Finalisierung. Wiederöffnen bleibt Administrator:innen vorbehalten. - App-Admin-Whitelist: Neue Admin-Einstellung
app_admin_user_ids, um die Administration von ArbeitszeitCheck auf eine ausgewählte Teilmenge der Nextcloud-Admins zu begrenzen. Leere Auswahl bleibt rückwärtskompatibel (alle Nextcloud-Admins dürfen die App verwalten). - Docker-Testziel für Security-Role-Gating: Verdrahtung von
scripts/test-security-role-gating-docker.shübermake test-security-role-gating-dockerundcomposer test:security-role-gating:dockerfür schnelle Autorisierungs-Regressionstests im Container-Setup.
- Monatsabschluss UX/API: Klarere Karten-UI, sichtbares Erfolgs-/Fehlerfeedback (WCAG), serverseitiges
canFinalizemit lokalisierten Sperrgründen; manuelle Finalisierung lehnt zukünftige Kalendermonate ab; Abwesenheits-Workflow (pending,substitute_pending,substitute_declined) zusätzlich zu ausstehenden Zeiteintragskorrekturen; API 401 bei fehlender Anmeldung wo passend; Admin: eigener Abschnitt „Monatsabschluss“; Karenzfeld bleibt editierbar mit Hinweis, dass der Wert gespeichert wird und bei aktivierter Funktion gilt; Wiederöffnen mit durchsuchbarer Mitarbeitenden-Auswahl und klarerer Rollenbeschreibung; Validierungsfehler mit höherem Kontrast über Themes hinweg. Auto-Finalize protokolliert Einzelfehler. - Release-/Signatur-Workflow für Integritätsprüfung gehärtet:
make release-signedsigniert jetzt den entpackten Release-Archivinhalt (nicht den lokalen Entwicklungs-Checkout), prüft verbotene Entwicklungs-Pfade und packt das signierte Archiv für Deployment/App-Store neu. - Admin-Autorisierung zentral erzwungen: Zugriffe auf
AdminController-Routen werden jetzt per Middleware auf App-Admin-Rechte geprüft; nicht berechtigte angemeldete Nutzer erhalten eine konsistente 403-Seite.
- Deployment-Hinweise ergänzt: Die Release-Dokumentation fordert nun explizit das Deployment aus dem signierten Tarball und beschreibt das typische Fehlerbild (
.git/*/node_modules/*) bei versehentlicher Signierung eines Dev-Trees. - Deployment-Helferskript:
release/deploy-from-release.shhinzugefügt für Deployment aus signierten Release-Archiven mit Sicherheitsprüfungen (verbotene Pfade, erforderlichesignature.json, optionales Disable/Enable undocc integrity:check-app). - Admin-Betrieb: Nutzer-/Entwicklerdokumentation ergänzt um Einrichtung der App-Admin-Whitelist, Rückfallverhalten bei leerer Auswahl und Verifikation des Role-Gatings im Docker-Testlauf.
- Revisionssichere Monatsfinalisierung (optional): Admin-Schalter
month_closure_enabled(Standard aus). Mitarbeitende können einen vollen Kalendermonat finalisieren; die App speichert kanonischen JSON-Snapshot, SHA-256-Hashkette, Anhänge-Revisionen, Audit-Ereignisse und ein schlankes PDF. Finalisierte Monate sind über normale App-APIs nicht mehr änderbar; Administrator:innen können einen Monat mit Pflichtbegründung wieder öffnen (Audit). Monatsberichte für finalisierte Monate lesen den gespeicherten Snapshot. Datenbank:at_month_closure,at_month_closure_revision(MigrationVersion1014Date20260409120000).
- Nutzerhandbücher (DE/EN), Entwicklerdokumentation und Compliance-Hinweise zu Monatsabschluss, Aufbewahrung und Grenzen (Nachweis in der App, keine QES) ergänzt.
- Manager-Ansicht „Mitarbeiter-Abwesenheiten“: Neue In-App-Seite und API für Manager/Admins zur Einsicht von Abwesenheiten mit sicherer Bereichsfilterung, Pagination und lokalisierten Statusbezeichnungen.
- Kopierfunktion für Arbeitszeitmodelle: Neue Kopieraktion mit Modal-UX, eindeutiger Namensvorschlag-Logik und Schutz gegen Doppelklicks.
- Manager-Navigation / Sidebar: Struktur in klarere Manager-/Admin-Untermenüs überführt; Berichte in den Manager-Kontext verschoben; Compliance-Link zur besseren Übersicht umgruppiert.
- UX Mitarbeiter-Zeiteinträge (Manager): Standard-Datumswerte sowie Datums-/Übersetzungsdarstellung im Filterfluss verbessert.
- Kalender-Verhalten (Rollback-Bereinigung): Angefangene Funktionalität für direkte Kalendereinträge sowie zugehörige Admin-Optionen/Status/Test-Endpunkte wurde entfernt. Das unterstützte Verhalten bleibt unverändert: keine Synchronisation mit der Nextcloud-Kalender-App; optionale
.ics-Anhänge werden weiterhin per E-Mail in den konfigurierten Abwesenheits-Workflows versendet.
- Arbeitszeitmodell-Modaldialoge: Interaktionsprobleme im Kopier-Modal, Darstellung des Quellmodells sowie Lokalisierung/Formatierung im Lösch-Dialog korrigiert.
- Abwesenheits-iCal-Härtung: Strengere Status-/Datumsprüfungen, Empfänger-Deduplizierung und datenschutzärmere Beschreibungen für Vertretung/Manager ergänzt.
- Nutzerhandbücher und Changelogs an das finale Kalenderverhalten (optionale
.ics-Mail, keine direkte Kalender-App-Synchronisation) sowie die aktuelle Manager/Admin-UX-Struktur angepasst.
- Urlaubsübertrag / Rollover:
VacationRolloverService, Hintergrundauftrag,occ arbeitszeitcheck:vacation-rollover, MigrationVersion1013Date20260407120000mitat_vacation_rollover_log; Unit-Tests.
- Frontend-L10n: Gemeinsame Partials
templates/common/main-ui-l10n.phpundteams-l10n.php, damit Übersetzungen früh verfügbar sind; zugehörige Template- und JS-Anpassungen.
- Manager-Dashboard — ausstehende Abwesenheiten: Die API liefert
summary.typeLabel(serverseitig übersetzter Abwesenheitstyp); die Oberfläche nutzt das bevorzugt, damit Karten lokalisierte Bezeichnungen zeigen (z. B. Urlaub) statt Rohcodes wievacation.
docs/Developer-Documentation.en.md: API-Hinweis zutypeLabelbei Pending Approvals; Nutzerhandbücher EN/DE: Hinweis zu lokalisierten Abwesenheitstypen bei ausstehenden Genehmigungen.
- Nextcloud-Kalender-App (CalDAV): Synchronisation von Abwesenheiten in die Kalender-App ist entfernt; Migration
Version1012Date20260406120000entfernt die Tabelleat_absence_calendar. Bereits angelegte Kalender in der Kalender-App bleiben bestehen, bis Nutzer sie dort löschen.
- Feiertage / Kalenderlogik: In der Klasse
HolidayServicegebündelt.
- AdminController: Doppelte
use-Anweisung fürHolidayServiceführte zu einem PHP-Fatal (u. a. beim Laden durch PHPUnit).
- Nutzerhandbücher EN/DE (
docs/User-Manual.*), README- und Entwicklerdokumentation aktualisiert; Hilfsskriptdocker/run-app-phpunit.shfür PHPUnit im Container.
- Resturlaub / Urlaubsübertrag: Pro Nutzer und Kalenderjahr Eröffnungsbestand
carryover_daysinat_vacation_year_balance; globale Admin-Einstellung für Ablauf des Vorjahresurlaubs (Monat/Tag, Standard 31.03.).VacationAllocationServicewendet FIFO auf genehmigten Urlaub an (nachstart_date, dannid) und teilt Arbeitstage vor/nach Ablauf, sodass Resturlaub zuerst verbraucht wird, solange er gültig ist. - Validierung & Freigaben: Urlaubsanträge werden bei Manager-Freigabe (und bei Auto-Approve) erneut geprüft, damit parallele Anträge nach Genehmigung das Kontingent nicht überziehen.
- API & UI:
AbsenceController::statsliefert Anspruch, Übertrag, Summen und ablaufbezogene Felder; Dashboard und Abwesenheiten zeigen eine klare Urlaubsübersicht; Admin-Einstellungen enthalten Ablauffelder. - DSGVO:
UserDeletedListenerlöscht Urlaubs-Jahresbestände bei Kontolöschung. - Migration / Massenpflege:
occ arbeitszeitcheck:import-vacation-balanceimportiert CSVuser_id,year,carryover_daysmit--dry-run.
- Unit-Tests für
VacationAllocationService; erweiterte Tests fürAbsenceServiceund zugehörige Controller.
- Entwicklung: CLI
occ arbeitszeitcheck:generate-test-datafür deterministische Demo-Daten (Zeiteinträge, Abwesenheiten, optional Verstöße, Demo-App-Team) zum Testen von UI, Berichten und Workflows. - Exporte:
TimeEntryExportTransformerbündelt Feldzuordnung und CSV-Aufbereitung für Zeiteintrags-Exporte;ExportControllerdelegiert daran für eine einheitliche, testbare Pipeline.
- Berichte-UI: Berichtstyp-Karten werden bei teambezogenem Scope nicht mehr fälschlich deaktiviert.
- Berichte (Tests): CSV-Download-Test nutzt
DataDownloadResponse::render()für den Dateiinhalt. - Team-Berichte: Nutzer-IDs werden vor Berechtigungsprüfung und Aggregation dedupliziert (keine Doppelzählung bei Mehrfach-Teams).
- Abwesenheits-Badges: Besser lesbare, theme-sichere Kontraste für Urlaub / Krank / Homeoffice / Sonstiges.
- Kompatibilität (Dev): Lokale Entwicklungsumgebungen an Nextcloud 33.x ausgerichtet (z. B. offizielles
nextcloud-Docker-Image). - Berichte-Layout: Zu aggressive Vollbreiten-Regel für das Parameterformular zurückgenommen (verbessert Scroll/Layout).
- Berichte-UI: Anpassungen an Templates, JavaScript und Styles auf der Berichtsseite; Admin-Einstellungen mit zugehörigem Hook.
- Reporting: Anpassungen in
ReportControllerundReportingServicepassend zum Export-Refactoring.
- Unit-Tests für
TimeEntryExportTransformer; erweiterteReportController-Tests;ExportController-Tests an neue Verdrahtung angepasst.
- Routing/Kompatibilität:
indexApi()-Kompatibilitätsaliases für Legacy-Endpunkte ergänzt, um 500-Fehler in den Nextcloud-Logs zu verhindern. - PHP-Fatals: Konstruktor-Signaturprobleme in
AbsenceServiceundComplianceServicebehoben (konnte die App beim Laden von Services oder beim Speichern von Einstellungen zum Absturz bringen). - Reports-Sicherheit: Vorschau-Endpunkte gehärtet (
start <= endValidierung + maximale Zeitraumbegrenzung) um DoS-Risiken durch untrusted Parameter zu reduzieren. - Admin-“Gesamte Organisation”: Admin-Organisation-Scope korrekt verarbeitet (
userId=""= alle aktivierten Nutzer) inklusive passender Zugriffsprüfung, damit Preview/Download konsistent bleiben. - Reports-Rendering: Preview-Darstellung für Abwesenheiten und Compliance verbessert, sodass sie zur tatsächlichen Ergebnisstruktur passt.
- Reports-UI-Semantik: Team-Scope auf Team-Overview-/Export-Semantik eingeschränkt (verhindert irreführende Preview/Downloads).
- Organisation-Download Hinweis: UI-Hinweis ergänzt, dass Organisation-Download erst vollständig unterstützt ist, sobald dedizierte Organization-Export-Endpunkte verfügbar sind.
- ArbZG-Compliance: Pausenprüfung korrigiert (9h/45min-Zweig erreichbar; Prüfung ≥9h vor ≥6h)
- Manager-Logik:
employeeHasManager()nutzt nungetManagerIdsForEmployee()stattgetColleagueIds() - Berichte:
getTeamHoursSummary()berücksichtigt Periodenparameter (Woche/Monat) - Admin-Benutzer:
hasTimeEntriesTodaypro Benutzer statt systemweit - UserSettingsMapper: Falsy-Null/Leerstring-Behandlung in getIntegerSetting, getFloatSetting, getStringSetting
- Routing: exportUsers-Route vor getUser verschoben (Shadowing behoben)
- Version1009-Migration: MySQL-Backticks durch portablen QueryBuilder ersetzt; OCP\DB\Types
- Doppelte Notifier-Registrierung: Aus Application.php boot() entfernt
- API-Sicherheit: Generische Fehlermeldungen statt roher Exceptions (SubstituteController, GdprController)
- PDF-Export: HTTP 422 mit klarer Meldung statt stillem CSV-Fallback
- LIKE-Injection: WorkingTimeModelMapper::searchByName() verwendet escapeLikeParameter()
- XSS: Modal-Titel in components.js escaped; compliance-violations.js innerHTML escaped
- Admin-Einstellungen: CSRF-requesttoken ergänzt
- AbsenceService DI: Konstruktorargument-Reihenfolge (IDBConnection) korrigiert
- Admin-Feiertage und -Einstellungen: englische Quellstrings für l10n
- UserDeletedListener: TeamMemberMapper und TeamManagerMapper per Injection
- XSS: Team-Namen in admin-teams.js bereinigt
- CSS: Shadow-Light-Variable, scopierte Resets, Dark-Mode color-mix, semantische Farben, Navigationshöhe/z-index
- Uhr-Buttons: Doppel-Submit-Guard (deaktiviert während API-Aufrufen)
- initTimeline(): Max-Retry (20) gegen Endlosschleife
- Barrierefreiheit: aria-label auf Header-Buttons, Label für Admin-Suche, aria-modal im Willkommens-Dialog, englische l10n-Keys in Navigation
- Dokumentation: Interne Docs entfernt; docs/README ergänzt; Repo-URLs korrigiert
- Manager-Dashboard: l10n von PHP an JS übergeben für Übersetzungen
- Constants.php; benutzerfreundliche Fehlermeldungen
- Zeiteintrags-Export: Optional (per Admin-Einstellung) können Einträge, die über Mitternacht laufen, im CSV/JSON-Export rein darstellungsbezogen in zwei Kalendertage segmentiert werden (vor/nach 00:00). Die zugrundeliegende Arbeitszeit- und ArbZG-Compliance-Berechnung bleibt unverändert auf Basis des originalen, unsplitteten Zeiteintrags.
- Version1010-Migration: Zusammengesetzte Indizes auf at_entries, at_violations, at_holidays, at_absences
- Langfristiges Refactoring: Ersetzung aller
\OC::$server-Verwendungen durch OCP-APIs und Konstruktor-Injection - CSPService: ContentSecurityPolicyNonceManager per Konstruktor injiziert
- Controller: manuelles cspNonce entfernt (configureCSP übernimmt dies); IURLGenerator und IConfig injiziert, wo nötig
- PageController: IURLGenerator und IConfig injiziert; übergibt urlGenerator an Templates
- HealthController: IDBConnection für Datenbank-Check injiziert
- ProjectCheckIntegrationService: LoggerInterface statt OC::$server->getLogger() injiziert
- Templates:
\OC::$serverdurch\OCP\Server::get()(öffentliche OCP-API) ersetzt - GitHub-Actions-Release-Workflow hinzugefügt (
.github/workflows/release.yml) - PageControllerTest mit vollständigen Konstruktor-Mocks aktualisiert
- Doppelte Routen-Namen in der Abwesenheits-API behoben (absence#store, absence#show, absence#update, absence#delete)
- Klassen-Namen der Settings in info.xml korrigiert, um den vollständigen OCA-Namespace zu verwenden
declare(strict_types=1)zu routes.php hinzugefügt
- Nicht vorhandene Screenshot-Referenzen aus info.xml entfernt, bis echte Screenshots verfügbar sind
- ProjectCheck-Integration für Projektzeiterfassung
- Zusätzliche Migrationen für Schema-Updates
- Weitere Verfeinerungen des Datenbankschemas
- Arbeitszeitmodelle
- Zuweisung von Arbeitszeitmodellen zu Nutzern
- Abwesenheitsverwaltung
- Audit-Logging
- Benutzer-Einstellungen
- Tracking von Compliance-Verstößen
- Erste Veröffentlichung
- Arbeitszeiterfassung gemäß deutschem Arbeitszeitgesetz (ArbZG)
- Kommen-/Gehen- und Pausen-Erfassung
- Verwaltung von Zeiteinträgen (Erstellen, Bearbeiten, Löschen, manuelle Einträge)
- Grundlegende Compliance-Prüfungen (max. 8h/Tag, Pausenanforderungen)
- DSGVO-konforme Datenverarbeitung
- Deutsche und englische Übersetzungen
- WCAG-2.1-AAA-Accessibility-Compliance