%% Werkjournal — Spezifikation und Umsetzungsplan, Stand 2026-09-09 %% Grundlage: Entscheidungen im Gespräch und beigefügte Werkbaum-Anleitung. %% Implementierung beauftragt: ein Knoten nach dem anderen, danach Statuspflege und Commit/Push; bei Rückfragen anhalten. [~] #werkjournal: Werkjournal — private Arbeitszeit- und Gewohnheitserfassung - [x] #scope: Ziel, Umfang und verbindliche Entscheidungen - [x] #release-version-policy: Entschieden: vor jedem Push Micro-Version erhöhen; größere Versionssprünge abstimmen - [x] #data-preservation: Entschieden: Seit erfolgreicher Ersteinrichtung alle Bestandsdaten bei Migrationen erhalten - [x] #product: Entschieden: Werkjournal auf werkjournal.javagil.de - [x] #architecture: Entschieden: Kotlin mit Vaadin Flow und Spring Boot als modularer Monolith - [x] #excluded: Entschieden: Bewusst außerhalb der ersten Version - [x] #login-navigation-polish: Gastzugang, Today-Markenlink, Werkator-artigen Footer und Journal-PWA-Icon umsetzen - [x] #guest-mode: Entschieden: vollständige Fachfunktionen vorerst mit persistentem Gastkonto - [~] #identity: Konten, Zugriffsschutz und Anmeldung - [x] #auth-choice: Entschieden: Google und OIDC streichen; Konten über Einladungslinks - [x] #return-login: Entschieden: E-Mail-Einmalcode mit alternativem Anmeldelink, geräteübergreifend nutzbar - [x] #mail-delivery: Entschieden: lokales Sendmail mit werkjournal@javagil.de, keine Antwortbearbeitung - [x] #local-mail-check: Lokale Mail-Einlieferung auf dem Deploymenthost prüfen - [x] #invites: Entschieden: Einmalige, widerrufbare Einladungen mit sieben Tagen Gültigkeit - [x] #bootstrap: Entschieden: Erster Administrator und bewusste Wiederherstellung - [x] #privacy: Entschieden: Private Daten und begrenzte Administratorrechte - [x] #sessions: Entschieden: 30 Tage Inaktivität, Sperrung und Abmeldung - [x] #account-delete: Entschieden: Selbstlöschung nach frischer Identitätsbestätigung - [x] #design-shell-today: Freigegebenes Journal-Design mit Logo, Navigation und responsiver Today-Seite umsetzen - [x] #design-other-pages: Freigegebene Seitenentwürfe mit dezent integrierten Aktionen umsetzen - [x] #catalog-redesign: Kunden und Projekte als Listen mit Dialogen und Löschaktionen verwalten - [x] #today-polish: Today mit Tages-/Wochen-/Kalendermonatssummen, Erfassungsbutton, englischen Beispielnamen und einheitlichen Habit-Hinweisen - [x] #work: Arbeitszeiterfassung - [x] #work-entry: Entschieden: Datum, Kunde, Projekt, ganze Stunden und optionaler Freitext - [x] #catalog: Entschieden: Eigene Kunden und kundenspezifische Projekte - [x] #work-views: Entschieden: Tagesansicht und monatliche Summen pro Kunde - [x] #concurrency: Entschieden: Veraltete Änderungen als Konflikt melden - [x] #habits: Habit-Zähler und freie Tage - [x] #project-terminology: Entschieden: Arbeitszeiten werden Kunden und Projekten zugeordnet - [x] #habit-config-decision: Entschieden: null bis beliebig viele benannte Habits je Nutzer, jeweils täglich zählbar - [x] #habit-count: Entschieden: Tägliche ganze Zählerstände je Habit mit Plus und Minus - [x] #habit-limit: Entschieden: Persönliches Wochenlimit Montag bis Sonntag mit Verlauf - [x] #habit-calendar: Entschieden: Monatskalender mit täglichen Werten und Wochensummen - [x] #day-off: Entschieden: Einzelne freie Tage unterdrücken ausschließlich Erinnerungen - [x] #work-quick-actions: Today-Einträge gezielt öffnen, Stunden direkt ändern und Dialogaktionen unterscheiden (S) - [~] #experience: Oberfläche, PWA und Geräteverhalten - [x] #dashboard: Entschieden: Heute-Dashboard und einzeln deaktivierbare Tracker - [x] #locale: Entschieden: Deutsch und Englisch, Browserdefault und persönliche Auswahl - [x] #design: Entschieden: Vaadin-nahe Gestaltung mit Petrol und gerätebezogenem Darkmode - [x] #pwa: Entschieden: Installierbare allgemeine PWA, Android geprüft - [x] #drafts: Entschieden: Gerätebezogene Entwürfe über Wartung hinweg erhalten - [x] #maintenance-ui: Entschieden: Wartung verständlich anzeigen, auch bei gestopptem Backend - [~] #reminders: Arbeitserinnerungen per Web Push - [x] #push-optin: Entschieden: Push je Gerät ausdrücklich aktivieren - [x] #schedule: Entschieden: Montag bis Freitag um 20 Uhr, Nachholen bis 22 Uhr - [x] #push-target: Entschieden: Benachrichtigung öffnet datiertes Erfassungsformular - [x] #export: Entschieden: Ein JSON-Export für einen Monat oder ein Jahr - [~] #storage: Persistenz und Migrationen - [x] #h2: Entschieden: H2 im File-Modus ohne PostgreSQL-Kompatibilitätsmodus - [x] #liquibase: Entschieden: Liquibase mit SQL-Changelogs ausschließlich für H2 - [x] #access-choice: JdbcTemplate, Spring Data JDBC und jOOQ praktisch vergleichen - [~] #model: Vorgeschlagenes minimales Datenmodell - [~] #operations: Build, Deployment und Wiederherstellung - [x] #environment: Entschieden: Werkator, Werkdock, Debian und systemd User Service - [x] #secrets: Entschieden: Geschützte Serverkonfiguration außerhalb der Releases - [x] #pipeline: Entschieden: Hauptbranch automatisch nach erfolgreichen Prüfungen deployen - [x] #deploy: Entschieden: Wartung, konsistente Sicherung, Migration, Startprüfung - [x] #rollback: Entschieden: Letzten lauffähigen Stand trotz mehrfacher Fehlschläge erhalten - [x] #backups: Entschieden: Hostsharing-Backups plus unmittelbare Deployment-Sicherung - [~] #delivery: Umsetzungsplan mit überprüfbaren Lieferstufen - [x] #phase0: 0 — Grundlagen und vorhandene Werkzeuge prüfen - [x] #inventory: Werkator/Werkdock und Hostkonfiguration prüfen (S) - [x] #versions: Kompatible freie Toolchain fixieren (S) - [x] #acceptance: Spezifikation in englische ausführbare Beispiele übertragen (S) - [~] #phase1: 1 — Technischen JVM-Prototyp als Machbarkeitsprüfung erstellen :#inventory,#versions - [x] #runtime-spike: Flow und Spring Boot in Werkdock bauen und mit eigenem JDK starten (S) - [x] #db-spike: H2, Liquibase SQL und Persistenz praktisch prüfen (S) - [x] #first-deploy: Vorziehen: geprüften JVM-Prototyp öffentlich deployen (S) :#runtime-spike - [~] #auth-spike: Einladungszugang und E-Mail-Wiederanmeldung praktisch abnehmen (S) :#return-login - [~] #pwa-spike: Android-PWA, Web Push und Browserentwurf prüfen (S) - [~] #prototype-exit: Machbarkeit und Persistenzentscheidung dokumentieren (S) :#runtime-spike,#db-spike,#auth-spike,#pwa-spike - [x] #phase2: 2 — Anwendungsfundament und Gastbetrieb liefern; Anmeldung folgt :#runtime-spike,#db-spike,#acceptance - [x] #foundation: Repository, Schema und Dienste aufbauen (S) - [x] #login-troubleshooting: Fehlenden Erstversand und veraltete Loginformulare untersuchen (S) - [x] #auth-build: Einladungszugang ohne OIDC, Bootstrap und Kontozugriff implementieren (S) :#return-login - [x] #remove-oidc: Google-/OIDC-Code, Konfiguration, Abhängigkeiten und Tests entfernen (S) :#return-login - [x] #shell-build: Responsive zweisprachige PWA-Hülle implementieren (S) - [x] #phase3: 3 — Arbeitszeiterfassung vollständig liefern :#foundation,#shell-build - [x] #catalog-build: Kunden- und Projektpflege mit Comboboxen umsetzen (S) - [x] #guest-preview: Vorziehen: erste Gastoberfläche öffentlich bereitstellen (S) :#catalog-build - [x] #work-build: Arbeitseinträge und sichere Änderungen umsetzen (S) - [x] #reports-build: Tagesübersicht und Monatskundensummen liefern (S) - [x] #phase4: 4 — Habits, freie Tage und JSON-Export liefern :#phase3 - [x] #habit-config: Vorziehen: konfigurierbare Habits ohne fest eingebauten Zähler (S) - [x] #habits-build: Habit-Tage und Limitverlauf implementieren (S) - [x] #off-build: Freie Tage und Tracker-Deaktivierung verbinden (S) - [x] #export-build: Versionierten JSON-Export implementieren (S) - [x] #mobile-refinement: Mobile Oberfläche verfeinern und bestätigtes Löschen von Habits und Kunden samt Projekten und Buchungen ermöglichen - [~] #phase5: 5 — Erinnerungen und vollständigen Kontolebenszyklus liefern :#phase4 - [~] #push-build: Push-Anmeldung und fällige Erinnerungen implementieren (S) - [x] #push-login-return: Datiertes Arbeitsformular nach erneuter Anmeldung öffnen (S) - [x] #push-zone: Letzte Gerätezeitzone bei App-Nutzung aktuell halten (S) - [x] #push-live: Vorbereiteten Push-Versand nach erfolgreichem Deployment aktivieren (S) - [x] #push-opt-in: Gerätebezogenen Erinnerungsschalter in Einstellungen integrieren (S) - [x] #push-worker: Push-Empfang und datierten Formularlink im PWA-Service-Worker implementieren (S) - [x] #push-key-setup: Push-Schlüssel über remote geschützt und wiederholbar auf dem Server bereitstellen (S) - [x] #push-runtime: Geschützte Push-Konfiguration und periodische Zeitsteuerung anschließen (S) - [x] #push-transport: Verschlüsselten Web-Push-Transport mit VAPID und Zeitlimit implementieren (S) - [x] #push-dispatch: Versandkoordination mit Wartungssperre und erneuter Fälligkeitsprüfung implementieren (S) - [x] #push-queue: Dauerhafte Tageswarteschlange, Versandreservierung und Wiederholung implementieren (S) - [x] #push-eligibility: Fälligkeit anhand Gerät, Arbeitseinträgen und freien Tagen prüfen (S) - [x] #push-device-http: Push-Geräteeinstellungen an die angemeldete Sitzung anbinden (S) - [x] #push-device-store: Gerätegebundene Abonnements mit Konflikt- und Schlüsselprüfung speichern (S) - [x] #delete-build: Kontolöschung und Adminwiederherstellung implementieren (S) - [x] #delete-proof: Zweckgebundene Einmalnachweise und frische Löschfreigabe implementieren (S) - [x] #delete-transaction: Vollständige eigentümergebundene Kontolöschung transaktional implementieren (S) - [x] #delete-ui: E-Mail-Bestätigung und abschließende Kontolöschung in Oberfläche integrieren (S) - [x] #admin-recovery: Einmalige Administratorwiederherstellung über remote freischalten (S) - [x] #delete-mail: Eigene zweckgebundene Bestätigungs-E-Mail für Kontolöschung vorbereiten (S) - [~] #phase6: 6 — Betrieb und Pipeline freigabefähig machen :#phase5 - [x] #ci-build: Werkator-Pipeline und JVM-Artefakt liefern (S) - [x] #login-deploy-check: Deploymentprüfung für aktivierte Anmeldung korrigieren und Betrieb wiederherstellen (S) - [x] #deploy-build: Wartung und fehlertolerantes Deployment implementieren (S) - [~] #restore-test: Fehlerfolgen und Hostsharing-Wiederherstellung erproben (S) - [~] #runbook: Betriebsanleitung fertigstellen (S) - [x] #runbook-consolidation: Betriebsabläufe, Wiederherstellung und Trixie-Wechsel zusammenführen (S) - [~] #phase7: 7 — Abnahme und erste Produktivfreigabe :#phase6 - [~] #browser-accept: Desktop- und Android-Abnahme durchführen (S) - [~] #android-device-acceptance: Installation, E-Mail-Login und Hintergrund-Push am echten Android-Gerät prüfen (S) - [x] #firefox-acceptance: Browser-Szenarien mit Firefox ausführen und in CI absichern (S) - [ ] #release-accept: Freigabekriterien und offene Punkte abschließen (S) - [~] #test-spec: Englische Gherkin-Abnahmespezifikation - [x] #identity-tests: Identity and private ownership - [x] #browser-logout-all: Gerätewiderruf und Entwurfslöschung bei erreichbaren/offline Clients prüfen (S) - [x] #identity-service-gherkin: Konten-Szenarien mit realen Diensten, Gerätefilter und kontrolliertem Mailversand ausführen (S) - [x] #work-tests: Work entries and catalog - [x] #browser-work-conflict: Konflikt zwischen getrennt angemeldeten Geräten im Browser prüfen (S) - [x] #browser-customer-create: Kundenanlage erst nach ausdrücklicher Aktion im Arbeitsformular prüfen (S) - [x] #browser-work-delete: Abbrechen und bestätigtes Löschen einer Arbeitsbuchung im Browser prüfen (S) - [x] #work-service-gherkin: Cucumber-Ausführung der fachlichen Arbeitszeit-Szenarien an reale Dienste und H2 anbinden (S) - [x] #habit-tests: Habit counts, limits and days off - [x] #browser-disable-work: Arbeitstracker ausblenden, Erinnerungen unterdrücken und Exportdaten erhalten (S) - [x] #browser-work-dayoff: Arbeitsbuchung und Summen an freiem Tag im Browser prüfen (S) - [x] #browser-habit-month: Vollständige Habit-Wochen an Monatsgrenzen im Browser prüfen (S) - [x] #browser-habit-limits: Habit-Zählen ohne Limit und oberhalb des Wochenmaximums im Browser prüfen (S) - [x] #habit-service-gherkin: Fachliche Habit-Szenarien mit realen Diensten und Flow-Komponenten ausführen (S) - [~] #push-tests: Device-specific reminders - [x] #push-service-gherkin: Erinnerungs-Szenarien an Scheduler, Warteschlange und Testtransport anbinden (S) - [x] #ux-tests: PWA, drafts, language and export - [x] #browser-deployment-draft: Entwurf über Backend-Stopp und öffentlichen Wartungszugang prüfen (S) - [x] #browser-offline: Offline-Hinweis beim erneuten Öffnen ohne gespeicherte Mutationen prüfen (S) - [x] #browser-private-export: Private Monats-/Jahres-JSON-Dateien einschließlich Grenzen und Geheimnisausschluss prüfen (S) - [x] #browser-draft-owner: Private Entwürfe beim Kontowechsel im Browser prüfen (S) - [x] #browser-tab-conflict: Getrennte Entwürfe und ausdrückliche Konfliktübernahme zweier Tabs prüfen (S) - [x] #browser-closed-draft: Arbeitsentwurf nach geschlossenem Tab im Browser wiederherstellen (S) - [x] #browser-preferences: Sprachwahl und gerätespezifisches Theme im Browser prüfen (S) - [x] #browser-gherkin-runtime: Browser-Gherkin-Lauf samt Werkdock-Abhängigkeiten und erstem Sprachszenario einrichten (S) - [~] #ops-tests: Production JAR smoke checks and safe releases - [x] #production-smoke-gherkin: Produktions-JAR-Abnahme nach vollständigen JVM-Tests ausführen (S) - [x] #remote-tool: Entschieden: tools/remote als zentrale Bash-Schnittstelle für den Serverbetrieb - [x] #remote-commands: Gemeinsame Bedienoberfläche für Deployment, Dienst und Sicherung (S) - [x] #remote-basics: Unit-Setup, Versions-/Bereitschaftsabfrage und SSH-Kurzbefehl ergänzen (S) - [x] #remote-restore: Bestätigte Wiederherstellung mit gesichertem Vorzustand und Unterbrechungsbehandlung implementieren (S) - [x] #remote-backup: Konsistente manuelle Sicherung von Datenbank und Programmstand bereitstellen (S) - [x] #remote-upload: Geprüfte Release-Kandidaten ohne Aktivierung hochladen (S) - [x] #remote-service: Dienststatus, Start/Stop/Neustart, Aktivierung und Logs sicher anbinden (S) - [x] #remote-ci: Dasselbe Deployment-Werkzeug in CI und manueller Bedienung (S) - [x] #werkator-detail: Werkator-Integration nach beigefügter Dokumentation - [~] #open: Offene Prüfungen und kleine noch unbestätigte Details - [x] #sources: Quellen und Herkunft --- #scope Vollständige Statusprüfung und Begründungen: docs/implementation/status-audit.md. Sammelknoten zeigen den eigenen belegten Arbeitsstand; offene Teilabnahmen bleiben sichtbar. Statusprüfung 2026-09-09: verbindlicher Umfang und Entscheidungen dokumentiert; die noch laufende Umsetzung wird separat ausgewiesen. Dieses Dokument ist die vollständige vereinbarte Produktspezifikation und ein ausführbarer Arbeitsplan, keine bereits implementierte Anwendung. Implementierungsknoten bilden den aktuellen Arbeitsstand ab; Risikoknoten markieren technische Ungewissheit. Mit „Entschieden:“ bezeichnete Knoten sind abgeschlossene Festlegungen, keine Behauptung fertiger Implementierung. Deren Umsetzung und Abnahme wird separat unter delivery verfolgt. Noch offene Detailentscheidungen bleiben offen. Größen an Arbeitspaketen sind relative Aufwandsschätzungen, keine Stunden oder Zusagen. Ungeschätzte Spezifikationsknoten sind nicht als zusätzliche Implementierungsaufwände zu summieren. Verbindlich sind die ausdrücklich getroffenen Nutzerentscheidungen. Als Umsetzungsvorschlag oder offene Prüfung bezeichnete Details sind keine nachträglich behaupteten Entscheidungen. Technische Auswahlentscheidungen, die ausdrücklich an den Prototyp delegiert wurden, werden dort begründet dokumentiert. [x] bedeutet immer erledigt beziehungsweise umgesetzt, bezogen auf die Aussage des Knotens: Eine Entscheidung ist mit ihrer verbindlichen Festlegung erledigt; eine Implementierung erst mit ihrer Umsetzung und Prüfung. Eine beschlossene Implementierung bleibt bis zum Arbeitsbeginn [ ] und während der Arbeit [~]. Ihr Status darf nicht durch Umbenennen in eine Entscheidung vorgezogen werden. Werkbaum-Abhängigkeiten beschreiben Voraussetzungen des Fertigstellungsstatus. Die nummerierten Lieferstufen beschreiben zusätzlich die empfohlene Arbeitsreihenfolge. Die Implementierung wurde am 2026-09-08 beauftragt und gestartet. Jeden Umsetzungsknoten beim Start auf [~] setzen und committen/pushen; nach nachgewiesenem Abschluss auf [x] setzen und erneut committen/pushen. Bei erforderlichen Rückfragen anhalten. #product Private tägliche Erfassung für bis zu zehn Konten, normalerweise ein bis drei gleichzeitig aktive Nutzer. Jeder sieht ausschließlich eigene Tracking-Daten. Desktopbrowser und installierbare Smartphone-PWA greifen auf dieselbe Anwendung zu. Öffentliche Adresse: https://werkjournal.javagil.de. Name und Toolpräfix sind entschieden. Ein gemeinsames Repository enthält Anwendung, Migrationen, Build und Betriebskonfiguration. Repository-URL und Copyright-Jahr/-Inhaber für die MIT-Datei sind bei Einrichtung konkret einzutragen, nicht zu erfinden. MIT-Lizenz; ausschließlich kostenlose Open-Source-Komponenten und entsprechende Testwerkzeuge. Abhängigkeiten und transitive Lizenzen prüfen. Keine kostenpflichtigen Vaadin-Komponenten voraussetzen. #architecture Verbindlicher Stack: Kotlin für Flow-UI und Backend, Spring Boot, Gradle Kotlin DSL, JVM-Auslieferung mit eigenem JDK; Installation über tools/remote backend install-jdk wie bei Werkbaum. Kleine JavaScript-/TypeScript-Ergänzungen für Browserfunktionen sind zulässig. Kein Wechsel zu einer eigenständigen TypeScript-SPA vorgesehen. Vorgeschlagene Struktur: Fachbereiche identity, work, habits, notifications und operations; innerhalb der Bereiche Fachlogik, Anwendungsdienste, Persistenz und UI trennen. Ein Prozess und ein Deployment-Artefakt; keine Microservices. Flow-UI ruft Anwendungsdienste auf. Keine öffentliche CRUD-API; erforderliche Login-, PWA- und interne Browserendpunkte sind davon nicht ausgeschlossen. Serverzustand der Flow-UI ist kurzlebig. 30 Tage Anmeldung bedeuten nicht, dass UI-Instanzen 30 Tage im RAM gehalten werden. Dauerhafte Anmeldung, Flow-Sitzung, lokale Entwürfe und Push-Abonnement als getrennte Lebenszyklen implementieren. Vaadin Flow unterstützt PWA und Web Push. Interaktive Offline-Erfassung ist ausdrücklich ausgeschlossen; eine Offline-Seite genügt. Vaadin Server Push für offene UIs ist nicht gleich Web Push für Hintergrundbenachrichtigungen. Referenzen: https://vaadin.com/docs/latest/flow/configuration/pwa und https://vaadin.com/docs/latest/flow/configuration/webpush sowie https://vaadin.com/docs/latest/flow/production/native . Konkrete stabile, zusammen kompatible Versionsstände bei Implementierungsbeginn fixieren; keine Vorabversionen ohne begründete Entscheidung. #excluded Keine Timer, Start-/Endzeiterfassung, Bruchteile von Arbeitsstunden, Abrechnung, Rechnungen oder Stundensätze. Keine gemeinsam genutzten Trails oder Sichtbarkeit fremder Tracking-Daten für App-Administratoren. Keine öffentliche Registrierung, keine weiteren Loginanbieter zunächst. Kein generischer Habit-Baukasten, keine Offline-Buchungen oder Offline-Synchronisierung. Kein CSV, JSON-Import, öffentliche API, Revisionshistorie, automatische Feiertagskalender oder Urlaubsbereiche. Keine dauerhafte Staging-Instanz. Keine iPhone-/Safari-Testzusage. Keine automatischen Deployment-Benachrichtigungen außerhalb Pipeline-Status und Logs. Spätere Ergänzungen dürfen möglich bleiben: andere Gewohnheiten, dauerhafte Kunden-/Projektlöschung, PostgreSQL, eigener Keycloak-Realm, weitere Plattformtests. Kein Aufwand für deren vollständige Implementierung in V1. #auth-choice Entscheidung vom 2026-09-09 ersetzt die frühere Providerwahl: Google-Anmeldung und OIDC entfallen vollständig aus dem Zielumfang. Ein gültiger einmaliger Einladungslink ermöglicht die Kontoanlage ohne externen Identitätsanbieter. Wiederanmeldung entschieden: E-Mail mit Einmalcode und alternativem Anmeldelink; der Code kann auf einem anderen Gerät eingegeben werden. Details unter return-login. Die bestehende OIDC-Implementierung ist historischer Zwischenstand und muss unter remove-oidc entfernt werden. Öffentliche E-Mail-Anmeldung ist seit 2026-09-09 aktiviert; der gemeinsame Gastbereich bleibt über den Gastbutton erreichbar. #invites Administratoren erzeugen Links zum manuellen Teilen; Ein Mailversand für spätere Logins ist noch nicht entschieden. Der erste Empfänger, der den Link erfolgreich einlöst, erhält ein Konto ohne Provider-Anmeldung. Keine Bindung an eine bestimmte E-Mail-Adresse. Sieben Tage ab Erstellung; verbrauchte, widerrufene und abgelaufene Links ablehnen. Einlösung atomar ausführen, sodass konkurrierende Empfänger nicht beide Konten erhalten. Kryptografisch zufällige Tokens verwenden, nur deren Hash dauerhaft speichern und sie nicht loggen. Umsetzungsvorschlag: bestehende Konten beim Öffnen eines Einladungslinks nicht neu anlegen und den Link nicht verbrauchen. #bootstrap Ein einmaliger Code aus geschützter Serverkonfiguration und die noch festzulegende lokale Kontoeinrichtung richtet den ersten Administrator ein. Danach ist die Ersteinrichtung gesperrt; parallele Einlösung darf keinen zweiten Bootstrap zulassen. Auch der letzte Administrator darf sein Konto löschen. Die Wiederherstellung von Verwaltungszugang erfordert einen neuen Code und eine ausdrückliche Freischaltung durch den Betreiber am Server. Niemals allein wegen fehlender Administratoren einen alten Bootstrap-Code automatisch reaktivieren. Offenes Umsetzungsdetail für die Betriebsanleitung: sicheren Befehl/Ablauf festlegen, der eine Wiederherstellung einmalig aktiviert und den Code nach Verbrauch entwertet. #privacy Administratoren verwalten Einladungen und Konten, sehen oder bearbeiten über die App aber keine fremden Tracking-Daten. Serverbetreiber besitzen technisch Zugriff auf Datenbank und Backups; eine Verschlüsselung gegen den Betreiber ist nicht vereinbart. Jeder fachliche Lese-, Schreib- und Exportzugriff wird im Anwendungsdienst auf den angemeldeten Eigentümer beschränkt. Clientseitig übergebene IDs verleihen keine Berechtigung. Auch Kunden, Projekte, Limits, freie Tage, Entwürfe und Push-Abonnements gehören einem Nutzer. Umsetzungsvorschlag: minimale Kontoverwaltung mit Identifikation, Status und Deaktivieren/Reaktivieren. Allgemeine Rollenverwaltung und Beförderung weiterer Administratoren sind nicht vereinbart. #sessions Anmeldung überlebt Browserneustarts und läuft nach 30 Tagen ohne Nutzeraktivität aus. Umsetzungsvorschlag: widerrufbare, persistente Geräte-Anmeldungen mit sicheren HttpOnly-Cookies; stille Heartbeats und Push-Versand verlängern die Frist nicht. Die konkrete Spring-Security-Integration im Prototyp klären. Deaktivieren eines Kontos sperrt bestehende Sitzungen sofort für weitere geschützte Zugriffe; Daten bleiben erhalten. Keine neuen Push-Nachrichten für deaktivierte Konten. Bereits angezeigte Daten können nicht nachträglich aus dem Gedächtnis eines Clients entfernt werden. Reaktivierung stellt Datenzugang wieder her; Vorschlag: erneute Anmeldung verlangen. Keine Geräteliste. Push-Einstellungen erfolgen jeweils auf dem aktuellen Gerät. Überall abmelden widerruft alle Anmeldungen und deaktiviert alle Push-Abonnements. Vorschlag für gewöhnliches Abmelden: aktuelle Anmeldung und aktuelles Push-Abonnement deaktivieren. Lokale Entwürfe bei Abmeldung löschen. Nicht erreichbare Geräte löschen beim nächsten Kontakt beziehungsweise beim Erkennen der widerrufenen Anmeldung. Kein Zugriff eines anderen Kontos auf fremde lokale Entwürfe. #account-delete Vor Kontolöschung die Identität frisch bestätigen und ausdrücklich zustimmen. Ein still weiterverwendeter lokaler Login genügt nicht. Entschieden: eigene Bestätigungs-E-Mail zur Kontolöschung mit Einmalcode und alternativem Link. Beide gelten nur für diesen Löschvorgang; danach ist eine weitere ausdrückliche Löschbestätigung erforderlich. Ein Linkaufruf allein löscht nichts. Google/OIDC ist ausgeschlossen. Konto, Kunden, Projekte, Arbeit, Habit-Zähler, freie Tage, Limitverlauf, Einstellungen, Einladungs-/Identitätsverknüpfungen soweit zugehörig, Anmeldungen und Push-Abonnements vollständig entfernen beziehungsweise notwendige fremde Admin-Referenzen auflösen. Lokale Entwürfe wie bei Abmeldung löschen. Verbrauchte Einladungen dürfen dadurch nicht wieder gültig werden. Vorhandene Sicherungen laufen regulär aus; sofortige Entfernung daraus ist nicht vereinbart. Nach späterer Wiederherstellung müssen zwischenzeitliche Löschungen und Sperrungen vor Freigabe berücksichtigt werden. Dieses Verfahren in der Restore-Anleitung dokumentieren. Neue Registrierung derselben Person ist mit einer neuen Einladung möglich und erzeugt ein leeres Konto ohne alte Rechte. #work-entry Datum, Kunde, Projekt und positive ganze Stunden sind Pflicht. Freitextbeschreibung ist optional, keine Tags. Pro Nutzer und Kalendertag über alle Kunden und Projekte zusammen höchstens zwölf Stunden. Mehrere Einträge für denselben Kunden und Tag sind ausdrücklich erlaubt; normalerweise wenige, selten mehr als drei, jedoch keine Begrenzung auf drei. Nur heute und vergangene Tage; heute richtet sich nach der aktuellen Gerätezeitzone. Client liefert eine gültige IANA-Zeitzone für die serverseitige Prüfung. Datum als kalendarisches LocalDate speichern und bei Reisen nicht umdatieren. Eintrag ändern, einschließlich Datum/Kunde/Projekt, oder nach Bestätigung löschen; keine Revisionshistorie. Summengrenze transaktional auch bei parallelen neuen Einträgen und Datumswechseln prüfen. Versionsprüfung nur am einzelnen Datensatz genügt dafür nicht: je Nutzer/Tag serialisieren oder gleichwertig absichern. #catalog Durchsuchbare Comboboxen für Kunde und Projekt. Projekte sind vom ausgewählten Kunden abhängig. Die zuletzt verwendete nicht archivierte Kombination vorbelegen; Stunden und Beschreibung bleiben leer. Bei Kundenwechsel ungültige Projektauswahl zurücksetzen. Unbekannter Name bietet ausdrücklich die Aktion „… anlegen“; keine automatische Anlage durch Speichern des Arbeitseintrags. Neue Auswahl danach sofort nutzbar. Kunden und Projekte gehören ausschließlich dem jeweiligen Nutzer. Archivieren entfernt Optionen für neue Einträge, erhält vorhandene Datensätze und Summen; Wiederherstellen möglich. Archivierter Kunde macht dessen Projekte für neue Einträge unbenutzbar. Alte Einträge dürfen mit ihrer bestehenden archivierten Zuordnung angezeigt und korrigiert werden; Auswahl einer neuen archivierten Zuordnung nicht zulassen. Umbenennung gilt rückwirkend für Anzeige, Auswertungen und künftige Exporte, da Einträge stabile IDs referenzieren. Keine Namenssnapshots pro Arbeitseintrag. Kunden können nach ausdrücklicher Checkbox-Bestätigung mit allen Projekten und Buchungen gelöscht werden; einzelne Projekte weiterhin nur ohne Buchungen. Entschieden (A): trimmen, leere Namen ablehnen, Namen je Nutzer beziehungsweise Kunde ohne Beachtung der Groß-/Kleinschreibung eindeutig halten. #work-views Heute-Dashboard mit heutigen Einträgen, Summe der Stunden und schneller Arbeitserfassung. Navigation zu vergangenen Tagen und Monatsauswahl für Summen je Kunde. Keine zusätzlichen Wochen-, Projekt- oder frei wählbaren Zeitraumreports erforderlich. Freie Tage ändern keine Stunden oder Summen. Nach Speichern und Löschen zugehörige Ansichten aktualisieren. Nach Konto-/Trackerwechsel keine Daten des vorherigen Kontexts weiterverwenden. #concurrency Optimistisches Locking für Arbeitseinträge und Tages-Habit-Zähler. Zweiter Schreibzugriff mit veralteter Version wird abgewiesen; aktuellen gespeicherten Stand erklären/anzeigen. Lokalen Entwurf erhalten, damit Nutzer bewusst neu speichern kann. Keine automatische Überschreibung und keine automatische Wiederholung einer konflikthaften Änderung. Ein Löschversuch auf inzwischen geänderte Arbeit muss denselben Schutz haben. Wiederholte HTTP-Anfragen dürfen nicht doppelt buchen; Vorschlag: Idempotenzschlüssel für Neuanlagen und Zählermutationen, ohne dadurch unabhängige konkurrierende Klicks automatisch zusammenzuführen. #habit-count Jede Zähleinheit eines frei benannten Habits zählt als eins. Keine Bruchteile, einzelnen Ereigniszeitstempel oder Notizen. Tageswert mit Plus/Minus ändern; Korrektur früherer Tage ermöglichen. Nicht unter null. Bei gleichzeitigen Änderungen auf zwei Geräten gewinnt nur die erste gültige Version. Zweite Änderung meldet Konflikt; nicht beide Klicks still addieren. Konflikterkennung auch beim erstmaligen Anlegen eines Tageswerts mit eindeutiger Nutzer-Datum-Kombination absichern. Offene kleine Fachentscheidung: zukünftige Habit-Tage. Vorschlag: Kalender zeigt sie, Erfassung bleibt wie Arbeit auf heute und Vergangenheit beschränkt. #habit-limit Je Habit vier optionale ganze nichtnegative Grenzen: Tagesminimum, Tagesmaximum, Wochenminimum, Wochenmaximum. Leer bedeutet ohne entsprechende Grenze; null ist ein gültiger Grenzwert. Minimum darf das zugehörige Maximum nicht überschreiten. Alle Grenzen sind ausschließlich Hinweise. Unter Minimum und über Maximum wird der Abstand durch Text und Farbe angezeigt. Zählen bleibt möglich, auch unter Mindestwerten und über Höchstwerten; nur negative Zähler sind verboten. Keine Bestätigung, Sperre oder Push-Erinnerung wegen Habit-Grenzen. Wochen beginnen montags und enden sonntags. Wochenzuordnung aus dem gespeicherten Kalenderdatum, aktuelle Woche aus Gerätezeitzone. Änderungen aller Grenzen gelten ab Montag der aktuellen Woche und für folgende Wochen; vergangene Wochen behalten ihren Verlauf. Mehrere Änderungen derselben Woche ersetzen deren gültige Konfiguration. Vor der ersten Festlegung bestehen keine Grenzen. #habit-calendar Monatskalender zur Ansicht und Korrektur von Tageswerten mit vollständigen Montag-Sonntag-Summen. Wochen, die Monats- oder Jahresgrenzen überschreiten, vollständig berechnen; angrenzende Tage sichtbar kennzeichnen. Historischen Wochenwert der Grenze verwenden. Umsetzungsvorschlag: fehlender Tagesdatensatz bedeutet Zählerstand null für Summen; kein daraus abgeleitetes Gesundheits- oder Abstinenzversprechen. #day-off Einzelnes Datum als frei markieren und Markierung entfernen, auch im Voraus. Keine automatischen Feiertage oder Urlaubsbereiche. Arbeit und Frei-Markierung dürfen gleichzeitig bestehen. Markierung unterdrückt die Arbeitserinnerung, verändert aber keine Stunden und wird beim Speichern von Arbeit nicht automatisch entfernt. #dashboard Startseite kombiniert heutige Arbeit, Stunden, Hinzufügen und Habit-Plus/Minus mit Wochenanzeige. Arbeit zunächst sichtbar und in Einstellungen deaktivierbar; Habits werden ausdrücklich angelegt, ohne Vorgabe. Jeder aktive Habit erscheint mit eigenem Zähler. Ausblenden löscht keine Daten. Arbeitstracker deaktivieren schaltet seine Erinnerungen auf allen Geräten aus. Vorschlag: Reaktivieren aktiviert Push nicht still erneut. Kein Zwang, beide Tracker zu nutzen. JSON-Export enthält weiterhin vorhandene eigene Daten deaktivierter Tracker. #locale Beim ersten Anmelden Browserpräferenz verwenden: Deutsch oder Englisch entsprechend den bevorzugten unterstützten Sprachen, andernfalls Englisch. Danach Einstellung pro Nutzer speichern. UI, Validierung, Konflikt-, Wartungs-/Offline-Meldungen und Push-Texte übersetzen; Nutzertexte und Kundennamen nicht automatisch übersetzen. Datum und Uhrzeit passend zur Sprache formatieren. Wochen bleiben unabhängig von der Sprache Montag-Sonntag. #design Schlicht, funktional, große Touchflächen, responsive Anordnung für Desktop und Smartphone. Farbvorbild https://michael.hoennig.de: Petrol mit Blaustich, Grau und Schwarz auf Weiß. Exakte CSS-Farbwerte vor UI-Gestaltung aus dem Blog ermitteln; bislang nicht visuell/CSS-technisch verifiziert. Hell/Dunkel/System pro Gerät, Standard System. Darkmode mit passenden Kontrasten, nicht bloß invertierten Farben. Tastaturbedienung, sichtbarer Fokus, beschriftete Eingaben und verständliche Fehlermeldungen als Qualitätskriterien umsetzen. App-Icon und Favicon aus einfacher eigener Gestaltung ableiten; konkretes Motiv später abstimmen. #pwa Manifest, Icons, Startadresse und Standalone-Darstellung; Service Worker über Vaadin-PWA-Integration. HTTPS durch vorgeschalteten Webserver. Android-Installation und Web Push praktisch prüfen. Desktop Chrome/Chromium und Firefox offiziell testen. Allgemeine Standards für iPhone berücksichtigen, aber keine iPhone-/Safari-Tests zunächst. Offline nur verständliche Meldung; keine offline abgeschlossenen Schreibvorgänge. Private Tracking-Seiten/Antworten nicht als allgemeine Offline-Daten cachen. Offline- und Wartungserlebnis einschließlich Sprache und Theme in Service Worker/Frontend berücksichtigen. Nach Updates Service-Worker-Versionierung und Asset-Wechsel prüfen, damit alte Clients keine inkompatiblen Ressourcen mischen. #drafts Ungespeicherte Formulareingaben lokal je Nutzer, Gerät und Formular/Datensatz speichern. Nach Wartung oder Neuladen wiederherstellen und bewusstes Speichern anbieten, niemals automatisch buchen. Erfolg oder ausdrückliches Verwerfen entfernt den Entwurf. Auswahlwerte anhand stabiler IDs nachladen; archivierte/gelöschte Optionen erklären. Abmeldung löscht Entwürfe; ein anderes Konto darf sie nie sehen. Browserspeicher kann vom Nutzer oder Browser gelöscht werden, daher keine uneingeschränkte Dauerhaftigkeitszusage. Native Flow-Serverzustände überleben einen Neustart nicht. Entwürfe müssen deshalb tatsächlich im Browser liegen. Lokal bereits eingetippte Werte vor einem Serverausfall erfassen; ausschließlich serverseitige ValueChange-Listener reichen als Garantie nicht. Entwürfe sind keine bestätigten Habitsbuchungen. Unklar beantwortete Speichervorgänge nach Verbindungsabbruch anhand Idempotenz/Serverstand klären, bevor ein erneutes Speichern angeboten wird. #maintenance-ui Neue Aufrufe erhalten eine statische Wartungsseite am vorgeschalteten Webserver mit HTTP 503, soweit geeignet Retry-After. Bereits geöffnete Frontends erkennen Wartung über einen unabhängig vom Backend verfügbaren Status und reagieren zusätzlich auf fehlgeschlagene Serververbindungen. Keine generische endlose Flow-Fehleranzeige. Deutsch: „Wartungsmodus – bitte in wenigen Minuten erneut versuchen.“ Englisch: „Maintenance in progress — please try again in a few minutes.“ Entwurfserhalt erklären. Echte Offline-Situation getrennt von bestätigter Wartung behandeln. Nach erfolgreichem Start aktualisieren/wiederverbinden und Entwurf wieder anbieten. Keine Anmeldung oder Speicherung über den öffentlichen Zugang freigeben, bevor die Prüfung erfolgreich war. Cache-Control für Wartungsstatus verhindert hängenbleibende Meldungen. #push-optin Keine Geräteliste. Im aktuellen Browser beziehungsweise der installierten PWA Erinnerungen ein-/ausschalten und Berechtigungsstatus erklären. Browserberechtigung nach Nutzeraktion anfordern. Smartphone kann aktiviert bleiben, Tablet und Desktop ausgeschaltet. Abonnements dauerhaft einem Nutzer und einer Geräteanmeldung zuordnen. Nur registrierte berechtigte Abonnements verwenden, ungültige Endpunkte entfernen. VAPID-Schlüssel dauerhaft in geschützter Konfiguration; nicht bei jedem Deployment neu generieren. Keine Habitserinnerungen. #schedule Fester Zeitplan je Gerät: Montag-Freitag 20:00 in dessen zuletzt bekannter IANA-Zeitzone. Beim Öffnen Zeitzone aktualisieren; Server kann Reisen bei geschlossener App nicht laufend erkennen. Pro Gerät und lokalem Datum höchstens eine logische Erinnerung. Unmittelbar vor Versand prüfen: Konto aktiv, Arbeitstracker aktiv, Anmeldung/Abonnement gültig, keine Arbeit für betreffendes Datum, keine Frei-Markierung. Bei Serverausfall oder Wartung ab 20:00 bis 22:00 desselben lokalen Tages nachholen, sofern Bedingungen noch gelten. Danach verwerfen. Sommerzeit und Neustarts berücksichtigen. Versandledger mit Nutzer/Abonnement/Datum und Status vorsehen. Ausfälle zwischen Versand und Bestätigung können ohne Unterstützung des Push-Dienstes keine mathematisch garantierte Exactly-once-Zustellung bieten. Stabile Benachrichtigungskennung und zeitlich begrenzte Wiederholungen zur Deduplizierung nutzen. TTL bis zum Ende des Erinnerungsfensters begrenzen; tatsächliche Zustellung hängt von Gerät, Netzwerk und Push-Dienst ab. Ein Arbeitseintrag auf einem beliebigen Gerät unterdrückt noch nicht versandte Erinnerungen anderer Geräte für dasselbe Kalenderdatum. Bereits zugestellte Benachrichtigungen lassen sich nicht zuverlässig zurückholen. #push-target Antippen führt direkt zu Arbeit erfassen mit Datum der Erinnerung, auch beim Öffnen an einem späteren Tag. Falls nötig erst anmelden, danach sicheren internen Rücksprung durchführen. Kunde/Projekt nach den allgemeinen Vorbelegungsregeln. Datum und Ziel im Push-Payload validieren; keine fremden Nutzer-IDs als Berechtigungsersatz. Umsetzungsvorschlag: neutraler Text ohne Kunden- oder Projektnamen auf dem Sperrbildschirm. Zukunftsdatum durch zwischenzeitliche Zeitzonenänderung nicht still buchen; Formular erklärt die Datumsgrenze. #export Jeder Nutzer exportiert ausschließlich eigene Daten in genau einer JSON-Datei pro gewähltem Monat oder Kalenderjahr. Arbeitseinträge, tägliche Habit-Zähler und freie Tage im Zeitraum; zugehörige Kunden/Projekte einschließlich archivierter und umbenannter Namen sowie die für den Zeitraum wirksamen Wochenlimits. Vorgeschlagenes Format: schemaVersion, exportedAt als UTC-Zeitpunkt, period mit Typ/from/toExclusive, workEntries, habitDays, daysOff, customers, projects, weeklyLimitChanges. IDs als stabile Zeichenketten, Fachdatum YYYY-MM-DD, Stunden/Habits als ganze Zahlen. Grenzwertzustand am Periodenbeginn mit exportieren, auch wenn die Festlegung früher liegt. Keine Zugangstokens, Push-Endpunkte oder Betriebsgeheimnisse exportieren. Grenzüberschreitende Wochen dürfen nicht versehentlich zusätzliche personenbezogene Tracking-Tage außerhalb des gewählten Zeitraums aufnehmen. Export liefert Tagesdaten und wirksame Limits; keine unvollständigen Wochensummen als vollständige deklarieren. Einstellungen nur soweit fachlich zum Verständnis erforderlich; dies ist ein Tracking-Export, kein vollständiges Account-Backup oder Importformat. Monat/Jahr-Auswahl prüfen; konsistenten Datenbanksnapshot verwenden. Umsetzungsvorschlag: werkjournal-YYYY-MM.json beziehungsweise werkjournal-YYYY.json. Kein Import, CSV oder öffentlicher API-Endpunkt. #h2 Durch den Dateipersistenz-/Migrationsprototyp bestätigt; Entscheidung in docs/decisions/0001-h2-jdbc.md. H2 zunächst ohne PostgreSQL-Kompatibilitätsmodus prüfen. Bekannte Erfahrung: Liquibase und Groß-/Kleinschreibung im PostgreSQL-Modus verursachten im Werkbaum-Backend Probleme. Schema-/Tabellen-/Spaltennamen konsequent unquoted und einheitlich schreiben; keine Mischung von quoted case-sensitive und unquoted Bezeichnern. Entscheidung und tatsächliches JDBC-Metadatenverhalten testen, nicht bloß aus Namenskonvention ableiten. Ein Prozess besitzt die Datenbank; keine gleichzeitig laufenden alten/neuen Anwendungsinstanzen auf derselben Datei. Datenverzeichnis liegt außerhalb austauschbarer Releases. Dateirechte auf Dienstnutzer begrenzen. Verbindungspool für kleinen Nutzerkreis dimensionieren. Ein späterer PostgreSQL-Wechsel wird durch überschaubares Schema und abgegrenzte Persistenz vorbereitet. Keine Portabilitätsgarantie, kein zweiter produktiver Dialekt oder duale CI in V1. #liquibase Versionierte formatted-SQL-Changelogs, zunächst nur H2. Bereits ausgelieferte Changesets nicht nachträglich verändern; neue Changesets hinzufügen. Tests für leere Datenbank, Upgrade eines bestehenden Schemas, Prüfsummen und erneuten Start ohne erneute Änderungen. DDL-Fehler können Teiländerungen hinterlassen. Produktionsrollback stellt deshalb die vollständige vorherige Datei und passendes Programm wieder her, statt sich auf transaktionales DDL oder automatische Down-Migrationen zu verlassen. Migration läuft in Wartung und vor Nutzerfreigabe. Wiederhergestellte Datei nicht versehentlich erneut mit dem fehlgeschlagenen Kandidaten öffnen. #access-choice Drei Varianten lokal praktisch geprüft; Auswahl H2 und jOOQ mit Spring-Transaktionen. Elf JVM-Tests und Produktions-JAR-PWA-Prüfung bestanden; Werkator-Verifikation abgeschlossen: Commit d61aaf9 erfolgreich in 120 Sekunden. Begründung in docs/decisions/0001-h2-jdbc.md. JdbcTemplate, Spring Data JDBC und jOOQ an einem kleinen repräsentativen Modell vergleichen: Eigentümerfilter, versionierte Änderung, Tagessummengrenze, Monatssumme und SQL-Migration. Kriterien: wenig Code/implizites Verhalten, JVM-Ausführung, klare Transaktionen und einfache Tests. Entscheidung als ADR festhalten. JPA/Hibernate ist nicht ausgewählt. SQLite nur als Rückfalloption bewerten, wenn H2 wesentliche Probleme macht; Wechsel begründen und Auswirkung auf Liquibase sowie Treiber prüfen. #model Weitgehend in src/main/resources/db/changelog.sql umgesetzt. Push-Schema aktuell in Bearbeitung und noch nicht abschließend geprüft; Kontolöschung folgt separat. AppUser: ID, noch festzulegende lokale Login-Zuordnung, Anzeigename, Sprache, aktiv, Administrator, Tracker-Einstellungen. Invitation: Tokenhash, erstellt/ablaufend, widerrufen/verbraucht. DeviceSession: widerrufbare Anmeldung und letzte relevante Aktivität. PushSubscription: Eigentümer, Zuordnung zur Geräteanmeldung, Endpoint und Schlüssel, Zeitzone, aktiviert. ReminderDelivery: Abonnement, lokales Datum, Status/Versuch. Customer: ID, owner, name, archived, version. Project: ID, owner/customer, name, archived, version. WorkEntry: ID, owner, date, customer/project, integer hours, optional description, version. Habit: ID, owner, name, active, version. HabitDay: habit/date eindeutig, integer count, version. DayOff: owner/date eindeutig. HabitLimit: habit/effectiveMonday eindeutig, optionale Tages- und Wochenminima/-maxima, version. AccountDefaults: einmalige Initialisierungsmarkierung je Nutzer. Beziehungen erzwingen, dass ein Projekt zum Kunden und alle Referenzen zum selben Eigentümer gehören. Transaktionen sichern Summen, konkurrierende Änderungen, Einladungen und Löschung. Technische Zeitpunkte als UTC-Instant, fachliche Tage als LocalDate. Zeitzonen als IANA-Kennung. Browserentwürfe nicht in dieses Servermodell aufnehmen. Längenlimits, Normalisierung und genaue Indexe sind Implementierungsdetails, vor UI/API-Validierung einheitlich festlegen. Vorschlag: keine unnötigen JSON-Spalten oder herstellerspezifischen Datentypen als Primärmodell. #environment CI mit Werkator: https://git.javagil.de/mi/werkator . Build innerhalb Werkdock: https://git.javagil.de/mi/werkdock . Die beigefügte Anleitung „Werkator for LLM Agents“ ist ausgewertet; die Repository-Inhalte und gesonderte Werkdock-Anleitung wurden nicht abgerufen. Dokumentiert sind YAML-Konfiguration, branchbezogene Worktrees, Werkdock über bubblewrap und Artefaktverwaltung. Die tatsächlich installierte Version und ergänzende Deployment-Konventionen vor Umsetzung prüfen. Ziel Linux x86-64 Intel/AMD, derzeit Debian Bookworm, demnächst Trixie. JDK und benötigte Build-Werkzeuge innerhalb der Build-Umgebung. Auf dem Produktionshost installiert tools/remote backend install-jdk ein eigenes JDK unter ~/opt/jdk25. System-Java wird nicht verändert. Die systemd-Unit verwendet den absoluten Java-Pfad und explizite Speichergrenzen. JVM-Anwendung als systemd User Service mit kontrolliertem Restart-Verhalten und festem Userport. .htaccess-Proxy zur Anwendung; HTTPS-Terminierung am vorgeschalteten Webserver. Keine eigenen Backend-TLS-Zertifikate. Betrieb ohne Container-Daemon entsprechend Werkdock-Konzept, dessen genaue Möglichkeiten erst prüfen. #secrets Geheimnisse des noch festzulegenden Loginverfahrens, VAPID-Schlüssel, Bootstrap-Code und weitere Geheimnisse in einer vom systemd User Service eingebundenen geschützten Datei. Repository und Artefakte enthalten nur Beispielnamen, keine Werte. Deployment überschreibt diese Datei nicht. systemd-Zugriffsrechte und Variable-/Dateiparsing dokumentieren. Logs dürfen keine Cookies, Tokens, Login-Codes, Push-Schlüssel, Einladungslinks oder privaten Arbeitsbeschreibungen enthalten. Technische Fehler mit korrelierbarer Kennung loggen. Pipeline und Dienstlogs sind zunächst einzige Betriebsbeobachtung; kein zusätzlicher Versand. #pipeline Kein dauerhafter Staging-Dienst. Ein Repository für Code und Betrieb. Pipeline: reproduzierbare Toolchain, JVM-Tests einschließlich ausführbarer Gherkin-Szenarien, Vaadin-Produktionsbuild, JVM-Produktionsbuild, Start-/Erreichbarkeitsprüfung des Produktions-JARs und dann automatisches Produktionsdeployment vom Hauptbranch. Produktionsartefakt-Prüfung startet mit wegwerfbarer Testkonfiguration/Datenbank und erreicht einen Bereitschaftsendpunkt. Kein versehentlicher Produktions-Push oder produktiver Login-Versand im Test. Vollständige Fachtests laufen auf JVM; nicht still eine vollständige zusätzliche Produktionsartefakt-Testsuite als Pflicht ergänzen. Build- und Deployment-Läufe serialisieren, sodass keine parallelen Migrationen auftreten. Artefakt und Commit-ID eindeutig zusammenführen; alte überholte Kandidaten nicht nach neueren Releases aktivieren. Nur erfolgreich getestetes Artefakt deployen, kein unkontrollierter Neubuild während Installation. #deploy Empfohlener verbindlicher Ablauf zur Erfüllung der Entscheidungen: 1. Deployment-Lock erwerben, getesteten Kandidaten bereitstellen und benötigte Konfiguration prüfen. 2. Unabhängige Wartungsanzeige aktivieren; öffentliche Schreibzugriffe sperren, laufende Transaktionen geordnet beenden. 3. systemd-Dienst stoppen und tatsächlichen Prozessstillstand prüfen. 4. Konsistente Datenbanksicherung samt bisherigem freigegebenem Programm und Manifest/Prüfsumme erstellen. Keine Live-Dateikopie einer offenen H2-Datei als Konsistenzgarantie. 5. Kandidat starten beziehungsweise Migration kontrolliert ausführen; öffentliche Wartung bleibt aktiv. 6. Start-/Bereitschaftsprüfung am internen Port: Anwendung gestartet, Migration beendet, Datenbank erreichbar. Keine privaten Daten im Health-Output. 7. Erst nach Erfolg Kandidat als freigegeben markieren, Wartung entfernen und Scheduler freigeben. Alte Clients reconnecten und Entwürfe anbieten. Während Migration/Probe keine Nutzerbuchungen oder Push-Sendungen zulassen, die beim Rollback verloren gingen. Ein persistenter Freigabezustand oder vergleichbare Sperre muss auch nach Absturz/reboot sicher bleiben. #rollback Bei Migrations-/Startfehlern Kandidat vollständig stoppen, konsistente Sicherung atomar zurückspielen, exakt dazugehöriges vorheriges Programm aktivieren, prüfen und erst danach Wartung beenden. Fehler und Rollback-Ergebnis in Pipeline-Status/Logs zeigen. Bei fehlgeschlagenem Rollback Wartung beibehalten, Fehler ausweisen, nicht endlos mit falscher Datenbank starten. Fehlgeschlagene Kandidaten dürfen nie known-good oder den letzten erfolgreichen Rückfallstand verdrängen. Auch zwei oder mehr aufeinanderfolgende Fehlschläge müssen wieder auf denselben zuletzt lauffähigen Stand zurückkehren können. Aufbewahrung: ein vorheriger erfolgreicher Rückfallstand zusätzlich zum aktuell freigegebenen Stand; keine Historie fehlgeschlagener Kandidaten als Ersatz. Für jeden neuen Versuch temporär eine frische konsistente Sicherung der aktuellen Daten anlegen, damit seit dem letzten Release hinzugekommene Buchungen erhalten bleiben. Erst nach erfolgreicher Freigabe Rückfallzeiger aktualisieren und überzählige Sicherungen entfernen. Atomare Manifeste/Zeiger und eindeutige Release-IDs benutzen. Erstdeployment hat noch keinen vorherigen Programmstand: bei Fehlschlag Wartung beibehalten und Erstinstallationszustand sauber behandeln. Ein später manuell ausgelöster Rücksprung nach bereits erfolgten Nutzerbuchungen ist nicht derselbe sichere automatische Rollback und benötigt bewussten Umgang mit Datenverlust. #backups Keine zusätzliche tägliche App-Backup-Routine und keine extra externe Sicherung vereinbart. Vorhandene Hostsharing-Backups verwenden; unmittelbare konsistente Deployment-Sicherung zusätzlich. Vor Freigabe klären, wie Hostsharing den geöffneten H2-Dateibestand sichert und ob daraus ein konsistenter Stand wiederherstellbar ist. Reale Restore-Probe mit Testdaten, einschließlich Konten, Migrationstand, Limitverlauf und App-Version. Ist Konsistenz nicht nachweisbar, Entscheidung dem Nutzer mit konkreten Alternativen vorlegen; nicht still eine tägliche Zusatzsicherung einführen. Backups enthalten private Daten; Zugriffsrechte und vorhandene Aufbewahrung dokumentieren. Bei Restore widerrufene Zugänge/gelöschte Konten berücksichtigen, und Push-Scheduler zunächst sperren. Wiederherstellungsanleitung enthält systemd, Dateien, Geheimnisse und Freigabeschritte. #inventory Abgeschlossen am 2026-09-08. Befunde und Folgeprüfungen: docs/implementation/inventory.md. CI mih09-werkator@mih09.hostsharing.net; App mih04-werkjournal@mih04.hostsharing.net, Loopback-Port 18090. Öffentliche URL https://werkjournal.javagil.de ohne www. Produktions-JAR und eigene JDK-Laufzeit bleiben Aufgabe des Prototyps. Vorhandene Pipeline-Beispiele, Build-Isolation, Ressourcenlimits, GraalVM-Verfügbarkeit, .htaccess-Möglichkeiten, systemd User Service und Portbindung erfassen. Ausgabe: konkrete Build-/Betriebsschnittstellen ohne erfundene Konfiguration. #versions Versionsauswahl abgeschlossen am 2026-09-08: gradle/libs.versions.toml und docs/implementation/toolchain.md. Produktionslaufzeit noch im Prototyp zu prüfen; Liquibase 4.33.0 wegen Apache-2.0 ausdrücklich statt FSL-5.x. Stabile Kotlin-, Gradle-, Spring-Boot-, Vaadin-, GraalVM-, H2- und Liquibase-Versionen sowie freie Testwerkzeuge wählen. Versionen und Lizenznachweise im Repository dokumentieren. #acceptance Beispiele und Testzuordnung abgeschlossen: gherkin/*.feature und docs/implementation/acceptance.md. Step Definitions folgen in den Fachknoten; keine bestandene Testausführung behauptet. Szenarien aus diesem Dokument als .feature-Dateien anlegen; Testebenen pro Szenario bestimmen. Offene Fachdetails als explizite Entscheidungsliste behandeln. #runtime-spike Abgeschlossen am 2026-09-08. Eigene Temurin-JDK-Laufzeit per tools/remote backend install-jdk installiert und wiederholt geprüft. JVM-Produktionsbuild und PWA-Startprüfung lokal, in Bookworm-Werkdock, auf dem Zielhost sowie über die reale Werkator-Pipeline erfolgreich. CI-Commit b51f9e3, 185 Sekunden, Artefakthash gegen das auf dem Zielhost geprüfte JAR verifiziert. GraalVM bleibt optional zurückgestellt und ist kein Freigabekriterium der ersten Version. Ergebnisse: docs/implementation/runtime-spike.md; historische Native-Image-Befunde: docs/implementation/native-spike.md. Minimalen Kotlin-Flow-Screen als Produktions-PWA bauen. Produktions-JAR unter Bookworm x86-64 mit selbst installiertem JDK starten; JDK-Installation, PWA-Ressourcen und begrenzten Laufzeitspeicher prüfen. Trixie-Kompatibilitätsprüfung vor Hostumstellung. Abbruchkriterium: nicht reproduzierbarer Build oder nicht unterstützbare Laufzeit. #db-spike Erweiterter Vergleich lokal bestanden: elf JVM-Tests, Produktions-JAR-PWA-Prüfung, generiertes jOOQ-Schema, Spring-Transaktionsrollback, Eigentümer-/Versionsprüfung, parallele Tagesgrenze und Monatssummen. Werkator-Verifikation abgeschlossen: Commit d61aaf9 erfolgreich in 120 Sekunden einschließlich Clean-Build, jOOQ-Generierung, Tests und Produktions-JAR/PWA-Smoke. H2-Dateipersistenz, Liquibase und Wiederherstellung bleiben bestätigt. Befunde: docs/implementation/persistence-spike.md; Entscheidung: docs/decisions/0001-h2-jdbc.md. Datei anlegen, SQL-Migrationen ausführen, Beispieldaten schreiben, Prozess stoppen/starten, Daten und Groß-/Kleinschreibung prüfen. Upgrade mit Fehler und vollständige Dateiwiederherstellung testen. JdbcTemplate, Spring Data JDBC und jOOQ anhand repräsentativer Transaktionen vergleichen. #first-deploy Abgeschlossen am 2026-09-08: CI-Artefakt f7464cf mit geprüfter SHA-256 deployt, systemd aktiv und enabled, HTTP→HTTPS, unabhängige Wartungsanzeige und öffentliche PWA-Ressourcen geprüft. DirectoryIndex disabled verhindert die Apache-Umleitung von Flow-Init nach index.html. Browser rendert Werkjournal und Online. Befunde: docs/implementation/first-deploy.md. Auf Nutzerwunsch vorgezogen: vorhandenes CI-geprüftes Produktions-JAR mit eigenem JDK als systemd-User-Service auf Port 18090 unter https://werkjournal.javagil.de ohne www bereitstellen. Hostsharing-Proxy, HTTPS und PWA-Ressourcen öffentlich prüfen. Die Anwendung enthält noch keine produktive Datenerfassung; vollständiger Datenbank-/Migrationsrollback und automatisches Deployment bleiben #deploy-build und #ci-build. #auth-spike Neu ausgerichtet am 2026-09-09: Die bisher dokumentierten OIDC-Proben sind historische Nachweise und kein Ziel mehr. Das unter return-login entschiedene E-Mail-Verfahren sowie Einladung, dauerhafte Anmeldung, Sperrung, Wiederherstellung und frische Bestätigung zur Kontolöschung ohne Provider praktisch prüfen. Versandweg und Absender sind unter mail-delivery entschieden und geprüft. Die Implementierung ist unter auth-build abgeschlossen; verbleibende End-to-End-Abnahme erfolgt ohne Provider. #pwa-spike Teilweise umgesetzt und geprüft: PWA-Ressourcen, Offline-Anzeige, Wartung und lokale Entwürfe. Echte Android-Installation und Hintergrund-Web-Push noch offen; daher in Arbeit statt ausschließlich als Risiko markiert. Installation, Permission, registriertes Gerät, Push bei geschlossener Oberfläche und datierten Klick testen. Krypto-/HTTP-Abhängigkeiten des Push-Versands prüfen. Flow-Ausfall mit ungespeichertem lokalem Entwurf und Wartungsanzeige demonstrieren. #prototype-exit Teilnachweise und Persistenzentscheidung liegen in docs/implementation/runtime-spike.md, persistence-spike.md und docs/decisions/0001-h2-jdbc.md vor. Gesamtabschluss wartet auf Login- und Android-/Push-Abnahme. Prototyp gilt erst als abgeschlossen, wenn konkrete Ergebnisse, Grenzen und reproduzierbare Befehle vorliegen. H2 bestätigen oder SQLite begründet neu bewerten; JDBC-Variante wählen. Keine Machbarkeit allein aus Dokumentation ableiten. Wesentliche Abweichungen vor Fachimplementierung mit Nutzer klären. #guest-mode Auf Nutzerwunsch: vollständige Fachfunktionen ohne vorgeschaltete Anmeldung über ein festes persistentes Gastkonto anbieten. Alle Besucher verwenden zunächst denselben Gast-Datenbestand. Eigentümerbezug bleibt im Datenmodell erhalten; spätere lokale Anmeldung ersetzt die Auflösung des aktuellen Nutzers. Gastbetrieb ist eine ausdrückliche Konfiguration. Auth-Abnahme blockiert die Fachimplementierung nicht mehr. #foundation Abgeschlossen: produktives H2-/Liquibase-/jOOQ-Fundament, persistentes Gastkonto, Eigentümer-Transaktionsgrenzen, Schema-Invarianten und sichere UI-Fehlermeldungen. 26 JVM-Tests und Produktions-JAR/PWA-Smoke lokal bestanden; Werkator c672820 erfolgreich in 105 Sekunden. Befunde: docs/implementation/foundation.md. MIT, Gradle Kotlin DSL, Anwendungsstruktur/Pakete, Konfigurationsbeispiele, Liquibase-Schema, Transaktionsgrenzen und Fehlerdarstellung einrichten. Schema-Invarianten und Eigentümerfilter testen. #auth-build Abgeschlossen: E-Mail-Anmeldung mit Code oder alternativem Link, Einladungen, einmalige Ersteinrichtung, geschützter Gastzugang, Geräteanmeldungen, Adminverwaltung, Sperrung und Abmeldung implementiert. OIDC-Rückbau abgeschlossen; Kontolöschung und separate Adminwiederherstellung sind ebenfalls umgesetzt. Der Betreiber hat die erfolgreiche Ersteinrichtung bestätigt. Gegen Code und Ergebnisse des lokalen Produktionsbuilds 0.1.12 geprüft: 57 Authentifizierungstests bestanden; vollständiger Lauf mit 131 JVM-Tests, 26 Betriebstests, 17 Frontendtests und Produktions-Smoke bestanden. Nachweis und Anforderungszuordnung: docs/implementation/email-authentication.md. Gherkin-Ausführung und vollständige Browser-/Geräteabnahme bleiben unter identity-tests, auth-spike und browser-accept offen. #shell-build Abgeschlossen: 29 lokale JVM-Tests, Produktions-Smoke und Browserprüfung bestanden; Werkator d733867 erfolgreich in 136 Sekunden. Befunde: docs/implementation/shell.md. Navigation, Today-Dashboard-Gerüst, Tracker-Schalter, Sprache, Gerätezonen, Hell/Dunkel/System, Petrol-Theme, Offline-Seite und Service Worker implementieren. #catalog-build Implementiert; 33 JVM-Tests und Produktions-Smoke bestanden, Browserprüfung der Anlage, Archivierung, Wiederherstellung, Umbenennung und Konflikte erfolgt. Werkator aec192f erfolgreich in 123 Sekunden. Befunde: docs/implementation/catalog.md. Anlegen-Aktion, Vorbelegung, Abhängigkeit Kunde/Projekt, Umbenennen, Archivieren und Wiederherstellen inklusive Eigentümerprüfung liefern. #work-build Abgeschlossen: Fachregeln, Formular, Konfliktauflösung, Entwürfe je Tab mit Wiederaufnahme und Wiederholungsschutz implementiert. Vollständiger lokaler JVM-Build mit Produktions-Smoke sowie Browserprüfung von Speichern, Zwölfstundengrenze, Serverunterbrechung, Konflikten, Neuladen, getrennten Tabs und Löschung bestanden. Nachweise in docs/implementation/work.md. Automatisierte Gherkin-Browserabnahme bleibt im Testknoten; öffentlich in 6e6daa1 bereitgestellt. Datumsgrenzen, ganze Stunden, transaktionale Zwölfstundengrenze, optionaler Text, edit/delete, Versionskonflikte, lokale Entwürfe und Wiederholungsschutz implementieren. #reports-build Implementiert: Tagesdetails und Monatskundensummen mit Monatswahl und Tageslinks. Vollständiger Produktionsbuild, Fachtests und lokale Browserprüfung bestanden; Nachweise in docs/implementation/reports.md. Navigation und sofortige Aktualisierung der Summen mit mehreren Einträgen, archivierten und umbenannten Kunden testen. #habits-build Versionskonflikte statt Additionsmerge, Nulluntergrenze, optionales Limit, historische Wochenwerte und Monatskalender inklusive Grenzwochen testen. #off-build Einzelne freie Tage vorab markieren; Arbeit parallel erlauben. Daten bei Tracker-Deaktivierung erhalten und Versandberechtigung entziehen. #export-build Monat/Jahr, Zeitraumgrenzen, referenzierte Stammdaten und wirksame Limits, eigener Snapshot und Ausschluss geheimer Daten prüfen. #push-build In Arbeit: Geräteabonnement- und Tagesledger-Schema, Montag–Freitag-Zeitfenster 20:00 bis vor 22:00 in Gerätezeitzone und kaskadierende Bereinigung bei Geräteabmeldung implementiert. Vollständiger lokaler CI-Ablauf einschließlich JVM-/Frontend-Tests und Produktions-Smoke erfolgreich am 2026-09-09. Gerätegebundener Abonnementdienst ergänzt: aktive eigene Anmeldung erforderlich, Versionskonflikte, getrenntes Opt-in, keine Aktivitätsverlängerung und Erhalt des Tagesledgers bei erneutem Opt-in. Gezielte Diensttests erfolgreich. Versand, Wiederholung, Wartungsprüfung und Opt-in-Oberfläche fehlen noch; kein fertiger Push behauptet. Abonnements, letzte Gerätezeitzone, Fristen, Neustart-Nachholen, Tagesledger und datierten Formularlink mit kontrollierten Testdiensten umsetzen. Vor jedem Versand die dauerhafte Wartungsdatei unter doms/werkjournal.javagil.de/htdocs-ssl/maintenance.flag prüfen und Versand bis zur Freigabe unterdrücken. #admin-recovery Umgesetzt: tools/remote backend prepare-admin-recovery hält den Dienst unter Wartung an, erzeugt einen separaten einmaligen Code für 24 Stunden und startet nach Bereitschaftsprüfung neu. Nur ohne vorhandenen Administrator; alter Einrichtungscode bleibt verbraucht. E-Mail-Nachweis erforderlich, bestehende Nutzer behalten ihre Daten. Gesamtprüfung 0.1.12: 131 JVM-Tests, 26 Betriebstests, 17 Frontendtests und gepackter Offline-Modus bestanden. Nachweis: docs/implementation/admin-recovery.md. #delete-build Erneute Anmeldung, Bestätigung, vollständige Löschung, Entwurfsbereinigung, neue Einladung für alte Identität und serverseitig separat freigeschaltete Administratorwiederherstellung testen; der alte Einrichtungscode bleibt verbraucht. #ci-build Implementiert und real verifiziert: Werkator baut und testet main in Werkdock, erstellt das Release und deployt anschließend im selben Buildskript. Lauf 4b057dd erfolgreich in 129 Sekunden, Deployment PASS; Zielmanifest/current stimmen überein, kein offenes Deploymentjournal. Nachweise: docs/implementation/ci-deployment.md. JVM-Gherkin/Fach-/Integrationstests, Produktionsassets, JVM-Produktionsbuild, Startprobe und serialisiertes automatisches Deployment vom Hauptbranch implementieren. #deploy-build Abgeschlossen: 15 Betriebstests und vollständiger JVM-Build bestanden; Werkator 6e6daa1 erfolgreich. Tatsächliches Update mit geschlossener H2-Sicherung durchgeführt, öffentliche Oberfläche sowie passender Rückfallstand/Prüfsummen geprüft. Java-Exitcode 143 nach ordnungsgemäßem Stopp berücksichtigt; Regressionstest und tatsächliche Wiederherstellung vor dem erfolgreichen Neuversuch. Nachweise: docs/implementation/deployment.md. Der künftige Scheduler muss die vorhandene Wartungssperre vor jedem Versand beachten; diese Integration gehört zu push-build. Statusseite ohne Backend, Service Stop, frische Dateisicherung, Migration, Health-Freigabe, Scheduler-Sperre und Rollback mit atomaren Zeigern umsetzen. #restore-test Begonnen: tests/operations/test_update.py prüft unter anderem zwei fehlgeschlagene Upgrades, erhaltene Buchungen, Rollbackfehler und unterbrochene Deployments. Reale Wiederherstellung aus Hostsharing-Backups bleibt offen. Zwei aufeinanderfolgende fehlgeschlagene Releases, partiell angewandte Migration, fehlgeschlagener Rollback und erhaltene Buchungen seit letztem Release testen. Hostsharing-Restore-Konsistenz nachweisen. #runbook Zentrale Anleitung in docs/RUNBOOK.md: Erstinstallation, Zielpfade/Proxy, E-Mail-Zugang und Geheimnisse, Betrieb/Logs, konsistenter Operator-Backup-Restore, Admin-Recovery, Push und geplanter Trixie-Wechsel dokumentiert. Befehle/Links gegen Implementierung geprüft. Für rohe Hostsharing-Rücksicherungsbäume bleibt der konkrete geprüfte Importweg mit restore-test/WJ-024 offen; daher ist der Gesamtknoten noch nicht abgeschlossen. Erstinstallation, Domain/Proxy, Login-Konfiguration, Geheimnisse, systemd, manueller Restore, Logsuche, Bootstrap-Recovery und Trixie-Wechsel dokumentieren. Konkrete Userports/Pfade erst aus Zielkonfiguration übernehmen. #browser-accept Begonnen: lokale Chromium-Prüfungen für Desktop und mobile Viewports in den Implementierungsnachweisen dokumentiert. Das ersetzt keine echte Android-, Firefox-, Login- und Push-Abnahme. Chrome/Chromium und Firefox mit Deutsch/Englisch, Hell/Dunkel, Tastatur und responsive Layouts prüfen. Android-Installation, das gewählte Loginverfahren und Web Push getrennt von deterministischer CI abnehmen. #release-accept Alle verbindlichen Szenarien erfolgreich; kein fremder Datenzugriff, kein verlorener zweiter Konflikt, Rollback und Restore nachgewiesen. Betreiberkonfiguration vorhanden und keine geheimen Daten in Artefakten/Logs. Erst danach erste produktive Freigabe; keine Implementierung im Rahmen dieser Dokumentlieferung. #identity-tests Feature: Invitation-only private accounts @WJ-010 @service Scenario: Redeem an invitation exactly once Given an unused invitation created less than seven days ago When two different recipients redeem it concurrently Then exactly one new account is created And the other request is rejected @WJ-011 @service Scenario Outline: Reject unavailable invitations Given an invitation that is When a new recipient attempts registration with it Then registration is rejected Examples: | state | | expired | | revoked | | used | @WJ-012 @service Scenario: Administrators cannot inspect another user's tracking data Given Alice has work entries and habit counts And Bob is an administrator with his own private records When Bob requests Alice's records by their identifiers Then no private record is returned or changed And Bob can still administer account status @WJ-013 @service Scenario: Disable an account with existing sessions Given Alice is signed in on two devices When an administrator disables Alice's account Then both devices are denied on their next protected request And no new reminder is sent for Alice And Alice's stored tracking data remains intact @WJ-014 @service Scenario: Expire an inactive login Given a device login has had no user activity for thirty days And background heartbeats have continued When the device requests private data Then a new login is required @WJ-015 @browser Scenario: Sign out everywhere Given Alice has active sessions and push subscriptions on two devices When Alice selects sign out everywhere Then all her sessions are revoked And all her push subscriptions are disabled And each reachable client removes its local drafts And an unreachable client removes them on its next authenticated contact @WJ-016 @service Scenario: Delete and register again Given Alice has confirmed deletion using a dedicated email code When Alice explicitly confirms account deletion Then her active account data and access credentials are removed When the same person redeems a new valid invitation Then a new empty account without former permissions is created @WJ-017 @service Scenario: Recover after the last administrator deletes their account Given the last administrator has deleted their account Then the old setup code does not enable registration When the operator explicitly enables recovery with a new one-time code And a recipient successfully redeems that code Then that recipient becomes administrator And the recovery code cannot be reused @WJ-018 @service Scenario: Account creation requires an invitation or authorized setup code Given a visitor has no application account And it has no valid invitation or authorized setup code When the visitor attempts to create an account Then no application account or tracking access is granted @WJ-019 @service Scenario: Deletion requires fresh identity confirmation Given Alice has an existing application session When she attempts to delete her account without a fresh deletion proof Then deletion is not performed And a dedicated email confirmation is required #work-tests Feature: Whole-hour work tracking @WJ-043 @service Scenario: Save several entries for one customer on the same day Given Alice has a customer with an active project When Alice saves entries of 2 and 3 hours for today with no descriptions Then both entries exist And the daily total is 5 hours And the monthly customer total includes 5 hours @WJ-044 @service Scenario Outline: Reject invalid work durations When Alice submits a work entry with hours Then the entry is rejected without changing stored totals Examples: | hours | | 0 | | -1 | | 1.5 | | 13 | @WJ-045 @service Scenario: Enforce the daily limit across concurrent insertions Given Alice has 10 hours recorded on a date When two devices concurrently add 2 hours on that date Then exactly one addition succeeds And the final daily total is 12 hours @WJ-046 @service Scenario: Reject a future date in the current device timezone Given the server has calculated today from the supplied valid device timezone When Alice submits work for tomorrow Then the entry is rejected @WJ-047 @service Scenario: Keep calendar dates stable during travel Given Alice recorded work dated 2026-09-08 When she opens the app in another timezone Then that entry is still dated 2026-09-08 @WJ-048 @browser Scenario: Require an explicit catalog creation action Given Alice types an unknown customer name into the combobox Then no customer is created merely by typing When Alice selects the offered create action Then her customer is created and selected @WJ-049 @service Scenario: Reject a project belonging to a different customer Given project M belongs to customer A When Alice submits an entry for customer B with project M Then the entry is rejected @WJ-050 @service Scenario: Archive and rename catalog entries without losing work Given Alice has work recorded for a customer and project When she renames the customer and archives the project Then historical work displays the new customer name And the hours remain in monthly totals And the project is not offered for new entries @WJ-051 @browser Scenario: Detect conflicting work edits Given two devices have loaded the same work entry version When the first device saves a change And the second device saves its different change Then the second save reports a conflict And the first change remains stored And the second device retains its unsaved draft @WJ-052 @service Scenario: Require both customer and project Given Alice is authenticated When she submits work without a customer or without a project Then the entry is rejected @WJ-053 @service Scenario: Edit a work date without exceeding the destination total Given Alice has 12 hours on yesterday and 1 hour today When she moves today's entry to yesterday Then the change is rejected And both daily totals remain unchanged @WJ-054 @browser Scenario: Delete work only after confirmation Given Alice has a saved work entry When she cancels the delete confirmation Then the entry remains stored When she confirms deletion of the current version Then the entry is removed and the totals are updated @WJ-055 @service Scenario: Restore an archived project Given Alice has archived a project of an active customer When she restores that project Then it is offered for new entries again #habit-tests Feature: Daily habit counts and historical weekly limits @WJ-001 @browser Scenario: Count without a configured limit Given Alice has never configured a weekly limit When she adds a habit for today Then the weekly consumption is shown And no remaining allowance or limit warning is shown @WJ-002 @service Scenario: A habit count cannot become negative Given today's habit count is zero When Alice requests a decrement Then the stored count remains zero @WJ-003 @service Scenario: Concurrent increments report a conflict Given two devices have loaded today's count of 2 at the same version When the first device increments the count And the second device increments using the old version Then the stored count is 3 And the second device is shown a conflict and the current count And no automatic retry is made @WJ-004 @service Scenario: Change the allowance for the current week only onward Given last week's allowance was 4 And this week's allowance is 4 When Alice changes the allowance to 2 this Wednesday Then this entire Monday-to-Sunday week has allowance 2 And future weeks use allowance 2 until another change And last week's allowance remains 4 @WJ-005 @browser Scenario: Record a habit above the allowance Given Alice has consumed her weekly allowance When she adds one habit Then the habit is saved without an extra confirmation And the weekly display states that she is one habit over the limit @WJ-006 @browser Scenario: Calculate a week spanning two months Given a Monday-to-Sunday week overlaps two months When Alice views either month's calendar Then that week's total includes all seven calendar dates And the effective limit for that week is displayed @WJ-007 @browser Scenario: Record work on a day off Given Alice marked today as a day off When she saves 3 hours of work for today Then the work is included in her totals And the day-off marker remains set And no work reminder is due for today @WJ-008 @browser Scenario: Disable a tracker without deleting its data Given Alice has work entries and enabled work reminders When she disables the work tracker Then its dashboard section is hidden And all her work reminders are disabled And her work entries remain available for export @WJ-009 @service Scenario: The first allowance does not change earlier weeks Given Alice has never configured a weekly allowance When she sets an allowance of zero this Wednesday Then the current week has allowance zero And earlier weeks still have no allowance And she can still record habit counts @WJ-056 @service Scenario: All four boundaries are advisory Given a habit has daily minimum 2 and maximum 3 And weekly minimum 5 and maximum 6 When Alice sets today's count to 20 Then the count is saved And both maximum violations are indicated When Alice sets today's count to 1 Then the count is saved And both minimum shortfalls are indicated @WJ-057 @service Scenario: Initial habits remain ordinary editable data Given Alice opens her account for the first time Then customer Allgemein with project Allgemein is available And Reading and Walks each have daily minimum 1 and weekly minimum 5 And neither has a maximum When Alice deactivates both habits And opens the application again Then no active habits are shown #push-tests Feature: Device-local work reminders @WJ-028 @service Scenario: Remind only an opted-in smartphone Given Alice enabled reminders on her smartphone but not her tablet And it is Monday at 20:00 in the smartphone's last known timezone And Alice has no work entry or day-off marker for that date When the scheduler evaluates due reminders Then one logical reminder is sent to the smartphone subscription And none is sent to the tablet @WJ-029 @service Scenario Outline: Suppress an ineligible reminder Given it is a weekday at 20:00 in the device's last known timezone And When the scheduler evaluates due reminders Then no reminder is sent Examples: | condition | | work is already recorded for that date | | the date is marked as a day off | | the work tracker is disabled | | the account is disabled | | the subscription is disabled | @WJ-030 @service Scenario: Catch up after maintenance Given a reminder was due at 20:00 during maintenance And it is now 21:00 on the same local date And no work or day-off marker exists for that date When the released application resumes scheduling Then that reminder is sent And another scheduler run does not create another logical reminder @WJ-031 @service Scenario: Do not catch up after the window closes Given a reminder was missed during an outage And it is after 22:00 in the device's last known timezone When scheduling resumes Then that missed reminder is discarded @WJ-032 @service Scenario: Use the last observed timezone while the app is closed Given the smartphone last reported Europe/Berlin And its owner travels without reopening the app When the server schedules the reminder Then it uses Europe/Berlin When the app opens and reports a new valid timezone Then subsequent scheduling uses the newly reported timezone @WJ-033 @browser Scenario: Open an old notification Given a reminder refers to 2026-09-08 When Alice taps it on 2026-09-09 Then the work entry form opens for 2026-09-08 And the normal customer and project defaults apply @WJ-034 @service Scenario: Do not remind at weekends Given an opted-in device has no recorded work or day-off marker today And today is Saturday or Sunday in its last known timezone When the scheduler evaluates reminders at 20:00 Then no reminder is sent @WJ-035 @service Scenario: Work recorded on another device suppresses a reminder Given Alice's smartphone is opted in for reminders And Alice records work on her desktop for the smartphone's current date When the smartphone reminder becomes due Then no reminder is sent @WJ-060 @service Scenario: Removing a day-off marker restores reminder eligibility Given Alice's smartphone is opted in for reminders And Alice marks the current date as a day off and then removes the marker When the smartphone reminder becomes due Then one logical reminder is sent to the smartphone subscription #ux-tests Feature: Reliable personal browser experience @WJ-036 @browser Scenario: Keep a work draft across deployment Given Alice has typed an unsaved work entry When the backend stops for deployment Then the open client shows a maintenance message And a fresh public request shows a maintenance page When the deployment succeeds and Alice reconnects Then her draft is available for review And it has not been automatically saved @WJ-037 @browser Scenario: Show an offline notice without committing work Given the device loses connectivity When Alice opens the app Then an offline notice is displayed And no work or habit mutation is reported as saved @WJ-038 @browser Scenario: Initialize and override the language Given a new user's preferred supported browser language is German When the user first signs in Then the interface is German When the user chooses English Then the account uses English on subsequent sign-ins @WJ-039 @browser Scenario: Keep theme overrides local to the device Given Alice's smartphone is set to dark and her desktop to system When both devices open Werkjournal Then the smartphone uses the dark theme And the desktop follows its own system preference @WJ-040 @browser Scenario Outline: Export private tracking data Given Alice and Bob both have tracking data When Alice exports Then one versioned JSON file contains only Alice's records in that period And referenced catalog names and effective allowances are included And no credentials or push secrets are included Examples: | period | | September 2026| | the year 2026 | @WJ-041 @browser Scenario: Default to English for an unsupported browser language Given a new user has no German or English browser language preference When the user first signs in Then the interface is English @WJ-042 @browser Scenario: A different account cannot recover a private draft Given Alice has an unsaved local draft When Alice signs out and Bob signs in on the same browser Then Alice's draft is removed And Bob cannot recover Alice's draft @WJ-058 @browser Scenario: Preserve a second tab's work draft after saving the first Given two tabs have separate drafts for the same work entry When the first tab saves its changes And the second tab reloads and opens its draft Then the second tab still shows its own unsaved input And adopting the first tab's version requires an explicit action @WJ-059 @browser Scenario: Recover a work draft from a closed tab Given Alice has an unsaved work draft in a tab When she closes that tab and opens the same form in a new tab Then she can explicitly open the earlier draft from this device And no work is saved merely by opening the draft #ops-tests Feature: Reproducible releases with recoverable data @WJ-020 @production_smoke Scenario: Production JAR smoke check Given the full JVM test suite has passed When the production JAR starts with isolated test configuration Then the process starts successfully And its readiness endpoint becomes reachable And no production notification is sent @WJ-021 @deployment Scenario: Roll back a partially failed migration Given a known-good release with a fresh consistent pre-deployment backup When a candidate migration fails after modifying part of the schema Then the candidate process is stopped And the matching database backup and known-good executable are restored And public access remains in maintenance until readiness succeeds @WJ-022 @deployment Scenario: Preserve known-good state across two failed releases Given release A is running successfully And a new work entry was saved after A was deployed When candidates B and C fail in consecutive deployments Then A remains the known-good executable And the new work entry is still present after each rollback And neither B nor C replaces the successful rollback target @WJ-023 @deployment Scenario: Keep maintenance active after a failed rollback Given a deployment fails When restoration cannot pass readiness checks Then the public maintenance page remains active And the pipeline records deployment and rollback failure @WJ-024 @operator_restore Scenario: Restore from a Hostsharing backup Given a representative saved database and its application version When the operator follows the restore procedure in an isolated environment Then the database opens with a consistent migration state And expected work entries and historical limits are present And reminder sending remains disabled until explicitly released @WJ-025 @deployment Scenario: Upload does not activate an unverified candidate Given release A is the known-good release When the operator uploads candidate B using tools/remote And restarts the service without deploying B Then release A remains active @WJ-026 @deployment Scenario: CI deploys the exact tested artifact Given a main-branch artifact has passed the required checks When CI invokes tools/remote with that artifact in non-interactive mode Then deployment does not rebuild the application And the deployed commit matches the tested artifact manifest @WJ-027 @deployment Scenario: A failed deployment remains failed after successful rollback Given tools/remote is deploying a candidate When the candidate fails readiness and rollback succeeds Then tools/remote returns a nonzero exit code And its log records the candidate failure and successful recovery #werkator-detail Integration umgesetzt und nachgewiesen: .werkator.yml, tools/ci-jvm, tools/ci-deploy und docs/implementation/ci-deployment.md. Die nachstehend ursprünglich offene Zugangsintegration ist durch den dedizierten SSH-Zugang im ausschließlich vertrauenswürdigen main-Build geklärt. Ein später fehlgeschlagener Anwendungsbuild bleibt separat zu beheben. Werkator baut konkrete Commit-SHAs in persistenten Branch-Worktrees unter .git/werkator/worktrees; niemals den primären Checkout als Build-Verzeichnis voraussetzen. Ein Build je Branch, zusätzliche globale Grenze executor.maxConcurrent. Für Builds zunächst einen parallelen Build als Vorschlag einplanen und anhand Ressourcenmessung prüfen. Projektkonfiguration .werkator.yml versionieren; Host-/Git-Geheimnisse bleiben in .git/werkator/.werkator.yml beziehungsweise bestehender Maschinenkonfiguration. Das ist getrennt von der geschützten systemd-Environment-Datei der Werkjournal-Anwendung. Sandbox-Richtlinien und Trust-Gates gehören zu den gepinnten Einstellungen, nicht zu frei änderbaren Feature-Branch-Werten. Dokumentierter Build-Runtime-Abschnitt: builds.default.werkdock.enabled, rootfs, binary und env. rootfs für Bookworm x86-64 mit kompatiblem JDK, Node-/Vaadin-Buildtooling, Gradle-Voraussetzungen und Python für Startprüfungen bereitstellen. Werkdock leert die Umgebung; benötigte nicht geheime Buildwerte ausdrücklich übergeben. Netz und UID werden laut Anleitung mit dem Host geteilt; diese Isolation nicht als Container-Netzwerk- oder separate Benutzergrenze darstellen. Dokumentierte Builddefinitionen builds. mit buildCommand, cleanCommand, artifactDirs, stdoutLog/stderrLog. trigger mit onPush und branches; jede benannte Definition erhält ihren eigenen Trigger, weil dieser nicht geerbt wird. CI für Entwicklungsbranches und automatische Freigabe ausschließlich für den geprüften Hauptbranch unterscheiden. Exakten Hauptbranchnamen am Repository prüfen, vorgeschlagen main. Unterschiedliche Statuskontexte für unterschiedliche Jobs verwenden und in vertrauenswürdiger Konfiguration festlegen. Tests, JVM-Produktionsbuild und Smoke-Test innerhalb eines zusammenhängenden Build-Kommandos oder eines nachweislich geordneten Ablaufs ausführen. Die Anleitung dokumentiert keine Job-DAG oder needs-Abhängigkeiten; nicht mehrere unabhängige Trigger als garantierte Reihenfolge interpretieren. Shell-Skript beendet sich bei Fehler vor Artefaktfreigabe. Artefaktverzeichnisse beispielsweise build/reports und ein bewusst erzeugtes Release-Verzeichnis. Nur Binärdatei, benötigte öffentliche Assets, Release-Manifest und nicht geheime Berichte archivieren. Werkator-Lese-UI und Artefakte sind laut Anleitung ohne Authentifizierung zugänglich: keine produktiven H2-Dateien, Datenbanksicherungen, privaten Testdaten oder Geheimnisse darunter ablegen. artifacts.keepLatestGreen: true erhält den neuesten erfolgreichen Build auch über normale Retention hinaus. Dies passt zur Nutzerforderung bei mehrfachen Fehlern, sagt aber nichts über erfolgreichen Produktionsstart oder passende Datenbanksicherung aus. Build-Erfolg, Deployment-Erfolg und known-good Produktionsstand getrennt speichern. Deployment-Sicherungen liegen außerhalb öffentlich ausgelieferter Artefakte. Kritische offene Integration: Ein Build in Werkdock soll nicht pauschal Produktionsdateien, EnvironmentFile oder systemd-Steuerung erhalten. Der Nutzer hat tools/remote als Bash-Vordertür für Deployment und Betrieb festgelegt, mit delegierten Skripten unter scripts/. Die Anleitung bietet weiterhin keinen dokumentierten post-success Host-Hook und keinen allgemeinen Schritt außerhalb der Sandbox. Den Aufruf von tools/remote aus einem vertrauenswürdigen CI-Kontext konkretisieren; der Ablauf prüft erfolgreichen Hauptbranch-Commit, unveränderliches Artefakt und Deployment-Lock. Kein erfundenes YAML-Feld oder Umgehen gepinnter Sandbox-Richtlinien. Ob tools/remote im vorhandenen Ausführungskontext sicher per SSH arbeiten kann oder ein äußerer Wrapper nötig ist, anhand der tatsächlichen Werkdock-Mounts und Zugangsdatenbereitstellung prüfen. Eine Werkator-Erweiterung nicht voraussetzen; falls dennoch erforderlich, Umfang explizit abstimmen. Statusabfrage ist dokumentiert unter /api/repos//status/ beziehungsweise mit Buildname; latestBuild.status und commitSha gemeinsam prüfen. Keine Freigabe allein anhand eines beweglichen latest-green Links. Ein entkoppelter Deployer muss Deployment-Ergebnis in einem überprüfbaren Status/Log sichtbar machen; ob ein eigener Gitea-Status oder Werkator-Erweiterung nötig ist, gehört zur Integrationsprüfung. Die Anleitung enthält ein älteres flaches Branch-Konfigurationsbeispiel neben der verschachtelten builds-Struktur. Die tatsächliche Version/Schemavalidierung ist maßgeblich; Konfiguration mit config:print ohne show-secrets prüfen. Keine unbestätigte produktionsfertige YAML-Datei aus dem widersprüchlichen Beispiel erzeugen. #open Statusprüfung 2026-09-09: H2/jOOQ, Toolchain, Zielpfade, Port, Design/Logo und Namensnormalisierung sind inzwischen geklärt. Offen bleiben insbesondere Login-/Android-/Push-Abnahme, Hostsharing-Restore und Trixie-Prüfung. Ältere Vorschläge unten sind im Licht der jeweiligen Implementierungsnachweise zu lesen. Die wesentlichen Produkt- und Architekturentscheidungen sind erfasst. Folgende Punkte sind noch keine gesicherten Tatsachen oder abschließend bestätigten Fachregeln. Sie dürfen bei Umsetzung nicht als bereits getestet oder vom Nutzer ausdrücklich gewählt dargestellt werden. An den Prototyp delegiert: H2-Endentscheidung, JDBC versus Spring Data JDBC, kompatible Versionen und JVM-Integration von Login, Liquibase und Web Push. Technische Voraussetzungen: reale Werkator-/Werkdock-Konfiguration, Build-Ressourcen, Proxy-/Wartungsmechanismus, konkrete Ports/Pfade/Dienstnamen, vorhandene Hostsharing-Backup-Konsistenz, Trixie-Kompatibilität. Zielsysteme wurden geprüft und die Gastanwendung wiederholt automatisch deployt; Nachweise unter docs/implementation/inventory.md und ci-deployment.md. Hostsharing-Backup-Restore und Trixie-Abnahme bleiben offen. Kleine Fachdetails mit dokumentierten Vorschlägen: Namenseindeutigkeit/Normalisierung, zukünftige Habit-Zähler, gewöhnliche lokale Abmeldung und deren Push-Wirkung, Reaktivierungsverhalten, genaue Datengrenzen und Icon. Diese gezielt vor dem jeweiligen Arbeitspaket bestätigen; nicht die gesamte bereits entschiedene Spezifikation erneut abfragen. Gherkin-Dateien und zahlreiche fachliche JVM-, Frontend- und Betriebstests liegen vor. Die automatisierte Ausführung der Feature-Dateien über Runner und Step Definitions fehlt weiterhin; vorhandene direkte Tests ersetzen diesen Nachweis nicht. Die Feature-Dateien enthalten bewusst noch keine projektspezifische Runner-/Step-Definition-Syntax. CI-Login-Tests müssen auf das gewählte lokale Verfahren umgestellt werden; Android-/Push-Prüfungen erfolgen separat. Erinnerungszustellung exakt um 20:00 und genau einmal kann ein Web-Push-Dienst nicht uneingeschränkt garantieren. Die Anwendung garantiert ihre Entscheidungsregeln und begrenzt Versandversuche; technische Grenzen im Betrieb dokumentieren. #sources Primäre Quelle der Anforderungen: ausdrücklich bestätigte Entscheidungen im Gespräch bis einschließlich gewünschter Werkbaum-Dokumentlieferung. Notation: beigefügte Datei „Werkbaum notation — guide for AI agents“. Normative SPEC unter https://git.javagil.de/mi/werkbaum/src/branch/main/docs/SPEC.md konnte über den verfügbaren Webzugriff nicht abgerufen werden. Daher gegen die beigefügte Anleitung strukturell geprüft, nicht mit dem Originalparser validiert. Werkbaum-Editor: https://werkbaum.javagil.de . Datei lokal öffnen/importieren; kein Upload oder Veröffentlichen wurde vorgenommen. Vaadin PWA: https://vaadin.com/docs/latest/flow/configuration/pwa Vaadin Web Push: https://vaadin.com/docs/latest/flow/configuration/webpush Vaadin Native Image: https://vaadin.com/docs/latest/flow/production/native GraalVM Native Image: https://www.graalvm.org/latest/reference-manual/native-image/ Werkator: zusätzlich vom Nutzer beigefügte Dokumentation „Werkator for LLM Agents“, ausgewertet. Werkdock: beschriebene Werkator-Integration bekannt, separate Werkdock-Dokumentation noch zu prüfen. Blog-Farbvorbild: https://michael.hoennig.de . Farben gemäß Nutzerbeschreibung, exakte CSS-Werte offen. #remote-tool Ergänzung aus der Nutzerentscheidung: Ein Bash-Skript tools/remote ist die zentrale Vordertür für alles, was auf dem Server passiert. Einzelne Aufgaben bleiben in direkt aufrufbaren Skripten unter scripts/. Das mitgelieferte Werkbaum-Hilfebeispiel ist eine Konventionsvorlage, kein Auftrag, dessen Masterpasswort- oder Dokumentenlistenfunktionen zu übernehmen. Die JDK-Installation wird aufgrund der späteren Nutzerentscheidung ausdrücklich übernommen. Werkjournal ist eine gemeinsame Vaadin-Flow-Anwendung mit ausführbarem Backend-JAR und dazugehörigen Assets. Kein unabhängiges statisches Frontend-Release. Statische Wartungs-/Statusressourcen am Proxy gehören dennoch zum koordinierten Deployment. remote backend install-jdk [--force] installiert ein eigenes JDK im Home des Zielusers, ohne Root-Rechte. Verbindlich übernommen ist die Bedienkonvention. tools/remote ist vorhanden: JDK-Installation, Deployment und Wiederaufnahme unterbrochener Deployments sind implementiert. Die übrigen unten beschriebenen Befehle und Flags bleiben noch umzusetzen. #remote-basics Abgeschlossen: Unit-Setup aus versionierter Vorlage mit Rücknahme bei Reloadfehler, getrennte interne/öffentliche Versionsprüfung und SSH-Kurzbefehl mit wörtlichen Argumenten. Deploy akzeptiert das vereinbarte -y ohne Prüfungen zu umgehen. Manueller Restore und automatischer Rollback verwenden denselben Datenbank-Austauschkern. 68 Betriebstests und erneute isolierte JAR/H2-Wiederherstellung bestanden; setup, info und SSH auf Hostsharing erfolgreich geprüft. Nachweis: docs/implementation/remote-utilities.md. #remote-restore Abgeschlossen: remote backend restore --backup FILE verifiziert die Sicherung vor ausdrücklicher Bestätigung, sichert den Vorzustand und stellt Datenbank samt passender Anwendung unter Wartung wieder her. Dauerhafter Zustandsnachweis und --recover verhindern erneutes Einspielen nach Freigabe und erhalten neu erfasste Daten. 58 Betriebstests bestanden; echte manuelle Sicherung isoliert mit enthaltenem JAR/H2 und tools/probe-restore erfolgreich geprüft. Keine Produktionswiederherstellung. Nachweis: docs/implementation/operator-restore.md; Hostsharing-eigene Backup-Abnahme bleibt unter restore-test offen. #remote-backup Abgeschlossen: remote backend backup [FILE] sichert den geschlossenen H2-Bestand samt passendem JAR und Prüfsummen unter gemeinsamer Deployment-Sperre. Vorherigen Betriebs-/Wartungszustand erhalten, lokalen Dateinamen erst nach vollständiger Prüfung veröffentlichen, keine Überschreibung. 47 Betriebstests bestanden. Echte Hostsharing-Sicherung nach korrekt abgewehrter Deployment-Überschneidung erfolgreich, 60.719.515 Bytes, Modus 0600, Git-ignoriert; öffentliche Anwendung danach wieder erreichbar. Nachweis: docs/implementation/operator-backup.md. Restore bleibt separat offen. #remote-upload Abgeschlossen: remote backend upload [-y] --artifact DIRECTORY nutzt die bestehende Artefaktprüfung, SSH-Übertragung und Deployment-Sperre. Nur Kandidatenablage, keine Dienst-/Datenbank-/Zeigeränderung; spätere Aktivierung ausschließlich durch deploy mit allen bisherigen Prüfungen. 39 Betriebstests bestanden einschließlich Transport, wiederholtem Upload, Fehlerbereinigung und anschließender expliziter Aktivierung. Nachweis: docs/implementation/candidate-upload.md. #remote-service Abgeschlossen: tools/remote backend start|stop|restart|status|enable|disable und log mit sicherer Argumentübergabe. Mutationen teilen die Deployment-Sperre; Start/Neustart prüfen freigegebenes Manifest und Bereitschaft. Wartung bleibt unverändert. 33 Betriebstests bestanden; Status und begrenzte Logabfrage am Hostsharing-Ziel erfolgreich geprüft. Nachweis: docs/implementation/service-control.md. #remote-commands Abgeschlossen: JDK-Installation, Deployment/Wiederaufnahme, Kandidaten-Upload, Dienststeuerung/Logs, Unit-Setup, Versions-/Bereitschaftsabfrage, SSH-Kurzbefehl, manuelle Sicherung, bestätigter Restore samt Wiederaufnahme und separate Admin-Recovery. Vollständiger Befehlsabgleich und Nachweise: docs/implementation/remote-utilities.md. Hostsharing-eigene Backup-Abnahme und vollständiges Runbook bleiben separate Knoten. Vorgeschlagene Bedienung: tools/remote [ARGS]. Hilfe ohne Argumente zeigt Zweck, Optionen, Voraussetzungen und Konfigurationsdatei auf Deutsch. remote backend deploy [-y] --artifact PATH: bereits gebautes, geprüftes JVM-Release samt Manifest hochladen und den vereinbarten Wartungs-/Backup-/Migrations-/Start-/Rollback-Ablauf ausführen. CI baut genau einmal in Werkdock; das Deployment baut niemals ungefragt neu. Optionaler lokaler Build-Komfort darf später ergänzt werden, ist keine Voraussetzung. remote backend upload [-y] --artifact PATH: Kandidat nur bereitstellen, niemals laufende Binärdatei überschreiben oder den freigegebenen Release-Zeiger ändern. Kandidat wird erst durch explizites deploy nach Sicherung und Prüfung aktiviert; ein gewöhnlicher Neustart aktiviert keinen ungeprüften Upload. remote backend start|stop|restart|status|enable|disable: systemctl --user für die konfigurierte Werkjournal-Unit. Vorhandenen Wartungszustand respektieren; Restart allein führt kein neues Release ein. remote backend setup: Unit aus versionierter Vorlage schreiben, EnvironmentFile referenzieren und daemon-reload ausführen. Geheimnisse nicht überschreiben oder ausgeben. Bestätigte Unit werkjournal-backend.service und Installationspfad ~/opt/werkjournal verwenden. remote backend log [ARGS]: dokumentierte Logausgabe des Dienstes, vorzugsweise journalctl --user -u UNIT. Falls vorhandene Betriebsstandards eine Datei vorgeben, diese konsistent nutzen. Keine unkontrollierte Shell-Auswertung der Argumente. remote backend info: freigegebene Version/Commit und Bereitschaft abfragen, vorzugsweise über https://werkjournal.javagil.de, damit Proxy und HTTPS mitgeprüft werden. Vorgeschlagener minimaler Betriebsendpunkt /api/v1/info liefert nur Version, Commit und unkritischen Status, keine privaten Daten. Dies ist keine öffentliche Tracking-API. Während Wartung zuerst intern prüfen, nach Freigabe zusätzlich öffentlich. remote backend backup [datei]: gemeinsame Deployment-/Backup-Sperre erwerben, Wartung aktivieren, laufenden Dienst geordnet stoppen, konsistenten H2-Dateibestand und Versionsmanifest sichern und vorherigen Betriebszustand wiederherstellen. War der Dienst vorher gestoppt, ihn nicht unerwartet starten. Backup außerhalb öffentlicher Artefakte und außerhalb Git speichern. Fehler lassen einen erklärten sicheren Zustand zurück. Dies ist eine manuell aufrufbare Sicherung, keine zusätzliche tägliche Routine. remote backend restore --backup PATH: Wiederherstellungsablauf mit passendem Programmstand, Wartung und Zustandsprüfung; destruktive manuelle Wiederherstellung ausdrücklich bestätigen. Automatischer Rollback innerhalb deploy nutzt denselben geprüften Kern ohne Rückfrage und ist bereits autorisiert. remote backend prepare-admin-recovery: einmaligen Wiederherstellungscode geschützt erzeugen, nur ohne vorhandenen Administrator. Ersteinrichtung erfolgt ebenfalls mit serverseitigem Einrichtungscode und E-Mail-Nachweis. Codes erscheinen weder in Logs noch Prozessargumenten. remote ssh [CMD]: SSH-Zugang zum konfigurierten Server. Sichere Argumentübergabe, keine eval-Konstruktion für unkontrollierte Eingaben. Lokale beziehungsweise CI-seitige, git-ignorierte .env im Repository mit .env.example für SSH-Ziel, Zielverzeichnis, Port, Unitname und öffentliche Adresse. Tatsächliche Namen gemäß .env.example: BACKEND_SSH, BACKEND_DIR, BACKEND_JDK_DIR, BACKEND_PORT, BACKEND_URL und DEPLOY_TARGET; der Unitname ist werkjournal-backend.service. Das konkrete Konto und SSH-Schlüsselhandling aus der Zielumgebung übernehmen. Anwendungsgeheimnisse bleiben ausschließlich in der separat geschützten serverseitigen systemd-Konfiguration. Keine Produktionsdateien in Build-Artefakte kopieren. Eine versionierte .envrc im Repository-Wurzelverzeichnis enthält PATH_add tools. Bei aktiviertem direnv ist tools/remote damit als remote aufrufbar. Nach Prüfung der Datei einmal direnv allow im Repository ausführen. Die .envrc lädt keine .env automatisch; die vereinbarte Konfigurationsverarbeitung bleibt Aufgabe von tools/remote. Die mitgelieferte .envrc ist für das spätere Werkjournal-Repository bestimmt, nicht für das outputs-Verzeichnis als Projektwurzel. #remote-ci Umgesetzt und real geprüft: tools/ci-jvm ruft tools/ci-deploy und damit tools/remote backend deploy für das geprüfte Artefakt auf. Nachweis: docs/implementation/ci-deployment.md. Noch fehlende Remote-Unterbefehle sind remote-commands zugeordnet. tools/remote und scripts/ werden gemeinsam mit der Anwendung versioniert und in README und Betriebsanleitung beschrieben. CI und Betreiber verwenden dieselbe Implementierung, keine zweite abweichende Deployment-Logik. Nach JVM-Tests, JVM-Produktionsbuild und Start-/Erreichbarkeitsprüfung des Produktions-JARs wird ausschließlich das zu diesem erfolgreichen Hauptbranch-Commit gehörende Artefakt an tools/remote übergeben. -y erlaubt den ausdrücklich gewünschten automatischen Ablauf, umgeht aber keine Prüfungen. Exitcode ungleich null bei fehlgeschlagenem Deployment auch dann, wenn der Rollback erfolgreich war. Kandidatenfehler und Wiederherstellung getrennt in Logs ausweisen. Dokumentierte Werkdock-Eigenschaften bleiben relevant: geleerte Umgebung und maskierter Bereich .git/werkator. Produktions-EnvironmentFile niemals in die Sandbox reichen. Ob ein dedizierter SSH-Agent/-Zugang eingeschränkt verfügbar gemacht werden kann oder ein vertrauenswürdiger äußerer Aufruf nötig ist, vor Umsetzung prüfen. Das Bash-Werkzeug klärt die Bedienoberfläche, aber beweist noch nicht dessen Erreichbarkeit aus der Sandbox. Automatischer Aufruf nur aus vertrauenswürdigem Hauptbranch-Kontext; Feature-Branch-Builds dürfen nicht allein durch Änderung ihres buildCommand produktiven SSH-Zugang erhalten. Bestehende Werkator-Trust-Konventionen prüfen. SSH-Hostschlüssel verifizieren, Zugangsdaten nicht in Repo, Artefakte oder Logs schreiben. Separates Deployment-Lock weiterhin nötig: Ein Build je Branch in Werkator verhindert keine Konkurrenz mit manuellen tools/remote-Aufrufen oder anderen Branches. Backup, Restore und Deployment verwenden dieselbe Sperre. Aufruf ohne Neubuild, Artefakt-/Commitprüfung und atomare Kandidatenfreigabe automatisiert testen. #guest-preview Abgeschlossen: CI-Artefakt aec192f öffentlich veröffentlicht und tatsächliche Flow-Oberfläche im Browser über HTTPS geprüft. Persistentes Gastkonto, Heute, Einstellungen und Kunden-/Projektpflege sind erreichbar. Befunde: docs/implementation/guest-preview.md. Auf Nutzerwunsch die vorhandene Oberfläche umgehend veröffentlichen: Heute, Einstellungen und Kunden-/Projektpflege. Einmaliger Übergang vom nachweislich datenlosen Prototyp; vorbestehende Daten verweigern, Wartung und Rückfall auf den bisherigen Stand absichern. Vollständige Arbeitserfassung folgt danach; der allgemeine datenbewahrende Upgradeprozess bleibt eigener Betriebsknoten. #habit-config-decision Auf Nutzerwunsch keine fest eingebaute Gewohnheit im Quellcode. Jeder Nutzer konfiguriert null, eine oder mehrere benannte Gewohnheiten mit getrennten Tageszählern. Je Habit sind Tagesminimum, Tagesmaximum, Wochenminimum und Wochenmaximum optional konfigurierbar. Alle Grenzen sind ausschließlich Hinweise und verhindern keine Zähleränderung; negative Zählerstände bleiben ausgeschlossen. Änderungen gelten ab der aktuellen Montag–Sonntag-Woche. Neue Nutzer erhalten einmalig die veränderbaren Habits Reading und Walks mit Tagesminimum 1 und Wochenminimum 5, ohne Maxima. Beide können deaktiviert werden; keine automatische Wiederanlage. Ein Startkunde Allgemein mit Projekt Allgemein wird ebenfalls einmalig angelegt. Bestehende Nutzerdaten bleiben erhalten. #habit-config Abgeschlossen: generisches Datenmodell, Eigentümerprüfung, vier Hinweisgrenzen, einmalige Startvorgaben, Konfiguration und tägliche Zähler im Frontend. 46 JVM-Tests, 3 Betriebstests, Produktions-JAR-Prüfung sowie Browserprüfung bestanden. Upgrade der veröffentlichten Version auf separater Datenbank geprüft; Nachweise in docs/implementation/habits.md. Öffentlich in 6e6daa1 bereitgestellt; bestehende Kunden und Einstellungen bei der Umstellung erhalten. Historische Kalendermonatsansicht und weitere Abnahme bleiben im habits-build-Knoten. #project-terminology Entschieden: Die fachliche Bezeichnung lautet Projekt in Oberfläche, Quellcode und Spezifikation. Daten und Zuordnungen bleiben bei der Migration erhalten. #today-polish Implementiert und lokal geprüft: Tages-, Montag–Sonntag-Wochen- und Kalendermonatssummen über alle Kunden/Projekte, direkter Erfassungsbutton, englische Beispielnamen, Petrol/Rot mit gleicher Schriftstärke. Produktionsbuild, Tests und Browserprüfung bestanden. Nachweise: docs/implementation/today.md. CI b3c4790 erfolgreich; öffentlich deployt und im Browser geprüft. Historische Gastphasen-Ausnahme aufgehoben: Seit bestätigter Ersteinrichtung müssen alle Bestandsdaten erhalten bleiben; siehe data-preservation. #design-shell-today Implementiert: Journal-Logo, obere Desktopnavigation und mobile Symbolnavigation, Petrol-Arbeitskarte, Tages-/Wochen-/Monatssummen, Habit-Zähler und mobile einklappbare Tagesdetails. Produktionsbuild und lokale Browserprüfung auf Desktop/Smartphone erfolgreich; docs/implementation/journal-design.md. Designentwürfe für Today, Work, Reports, Habits, Kunden/Projekte und Einstellungen einschließlich Journal-mit-Stift-Logo freigegeben. Petrol-Arbeitskarte, klare Typografie, luftige Anordnung und runde Habit-Zähler. Today-Einträge mobil zunächst eingeklappt, Desktop geöffnet. Aktionsbuttons mobil als Symbol, bei ausreichend Platz mit Symbol und Text; zugängliche Namen und Desktop-Tooltips bleiben erhalten. #design-other-pages Work-Erfassungsaktion dezent in die Datums-/Stundenkarte integrieren. Monatswahl in Reports in den Auswertungskopf integrieren. New Habit dezent in den Habit-Bereich integrieren. Kunden/Projekte als Listen und Formulare in Dialogen. #return-login Entschieden am 2026-09-09: Zur Wiederanmeldung wird eine E-Mail mit Einmalcode und alternativ anklickbarem Anmeldelink versendet. Beide Wege gehören zu derselben Login-Freigabe. Der Code darf auf einem anderen Gerät eingegeben werden; ein Cookie des anfordernden Browsers darf dafür keine Voraussetzung sein. Angemeldet wird das Gerät, auf dem der Code erfolgreich eingegeben beziehungsweise der Link eingelöst wird. Einmaligkeit gilt gemeinsam: Erfolgreiche Einlösung per Code entwertet auch den Link und umgekehrt; parallele Einlösungen dürfen nur eine Anmeldung erzeugen. Einladungslinks bleiben getrennte Berechtigungen zur Kontoanlage und werden nicht zu wiederverwendbaren Login-Links. Noch keine festgelegten Detailwerte: Codeformat, Gültigkeitsdauer und Versuchslimits. Diese als Implementierungsvorschlag konkretisieren; kurze Codes benötigen begrenzte Versuche. E-Mail-Zuordnung und Bestätigung bei der Kontoanlage, Wiederherstellung bei Verlust des Postfachs sowie frische Bestätigung zur Kontolöschung gesondert berücksichtigen. Die Entscheidung über das Verfahren ist abgeschlossen, seine Implementierung weiterhin offen unter auth-build. #mail-delivery Lokaler Versand geprüft: Postfix bietet /usr/sbin/sendmail und erlaubt Einlieferung durch den App-User; Nachweis in docs/implementation/local-mail.md. Absender bestätigt: Werkjournal . Keine Antwortbearbeitung durch die Anwendung, kein Reply-To auf eine betreute Adresse; die E-Mail weist sprachabhängig darauf hin, dass Antworten nicht gelesen werden. Ein Reply-Button im Mailprogramm lässt sich durch die Anwendung nicht verhindern. Keine Änderung an Postfach, Alias oder serverseitiger Annahme von Antworten ohne separate Anweisung. Eine ausdrücklich autorisierte Testnachricht wurde am 2026-09-09 lokal erfolgreich angenommen (sendmail Exitcode 0). Der Empfänger hat den Eingang bestätigt; lokale Einlieferung und Zustellung dieser Probe sind nachgewiesen. Login-Implementierung bleibt offen unter auth-build. Keine Zugangsdaten in Werkbaum oder Repository ablegen. Ein kontrollierter Testversand gehört in die CI; echter Versand benötigt die bestätigte Betreiberkonfiguration. #remove-oidc Abgeschlossen am 2026-09-09: Provider-Code und Bibliotheken entfernt, vollständiger lokaler CI-Ablauf erfolgreich. Historische Zuordnungstabelle bleibt ungenutzt erhalten. Nachweis: docs/implementation/remove-oidc.md. Nach Festlegung des Ersatzverfahrens die vorhandenen Google-/OIDC-Providerklassen, Callback-Routen, providerbezogenen Abhängigkeiten, Secrets/Beispiele, Testanbieter und Betriebsanleitungen entfernen beziehungsweise ersetzen. Allgemeine Zugriffskontrolle, Eigentümerbindung, Einladungen und widerrufbare Geräteanmeldungen soweit passend weiterverwenden. Spring Security ist damit nicht automatisch abgewählt. Datenmodell und Migrationen unter Erhalt aller bestehenden Konten, Gastdaten und Beziehungen an lokale Konten anpassen; die frühere Erlaubnis zum Verwerfen des Gastbestands ist aufgehoben. Abschließend prüfen, dass der produktive Login keinen externen Identitätsanbieter mehr voraussetzt. #local-mail-check Read-only-Prüfung abgeschlossen am 2026-09-09: /usr/sbin/sendmail ist Postfix 3.7.11, authorized_submit_users erlaubt das Anwendungskonto, postdrop besitzt die erforderliche Setgid-Konfiguration. Keine verhindernde systemd-Einschränkung festgestellt. Absolute Programmadresse verwenden; Standard-Absenderdomain wäre h68.hostsharing.net. Keine Mail versendet; externe Zustellung bleibt separat zu prüfen. Nachweis: docs/implementation/local-mail.md. #login-navigation-polish Nutzerergänzungen vom 2026-09-09: Loginseite mit explizitem Gast/Guest-Button zum bisherigen gemeinsamen Gastkonto. Icon und Werkjournal-Schriftzug oben führen zu Today. Footer analog zum tatsächlichen Werkator-Footer: Produkt, Versionslink, Copyright/Autor, Impressum und Datenschutz, responsiv. Installierte PWA verwendet das vorhandene petrolfarbene Journal-Logo statt Vaadins Standardicon. Implementiert und lokal geprüft: vollständiger CI-Ablauf mit JVM-/Frontend-Tests und Produktions-Smoke erfolgreich; Gastlogin im Browser, Rückkehr von Work nach Today über die Marke, Footer in Login und App sowie Smartphone-Ansicht geprüft. Ausgeliefertes PWA-Manifest referenziert Journal-PNGs in 144/192/512 Pixeln mit Petrol-Theme. Echte Android-Neuinstallation bleibt Teil der Geräteabnahme. Nachweis: docs/implementation/login-navigation.md. #push-device-store Gerätegebundener Dienst implementiert und mit H2 geprüft: getrenntes Opt-in, aktive eigene Geräteanmeldung, 30-Tage-Ablauf, Versionskonflikte, eindeutiger Endpoint, HTTPS und echte P-256-Kurvenpunktprüfung. Deaktivieren und Endpointwechsel erhalten das Tagesledger; Abmeldung entfernt das Abonnement kaskadierend. Keine Verlängerung der Geräteanmeldung durch Abonnementzugriff. Gezielte PushSubscriptionsTest-Prüfung erfolgreich am 2026-09-09. HTTP-Anbindung, Browser-Opt-in und Versand bleiben unter push-build offen. #push-device-http Interne Browser-Endpunkte unter /account/push implementiert: Gerätestatus lesen, Abonnement speichern und deaktivieren. Konto und Gerät werden ausschließlich aus der authentifizierten Sitzung und dem Gerätecookie ermittelt. Änderungen erfordern CSRF; abgelaufene oder widerrufene Geräte erhalten 401, veraltete Versionen 409, ungültige Abonnements 400. Antworten enthalten keine Endpoints oder Schlüssel. HTTP-Integrationstests mit echter Sicherheitskette und H2 sowie Diensttests erfolgreich am 2026-09-09. Browser-Opt-in und Versand bleiben offen unter push-build. #login-deploy-check Repariert am 2026-09-09: Nach aktivierter Anmeldung erwartete die Deploymentprüfung weiterhin anonymen Zugriff auf Versionsendpunkt und Flow-Initialisierung. Der CI-Build c4d632f bestand alle Tests, scheiterte aber an dieser Prüfung und hielt die Wartungssperre. Prüfung meldet sich nun vorübergehend als Gast an, prüft Version und Flow und meldet das Prüfgerät wieder ab. Versionsendpunkt explizit freigegeben; bei historischen Releases mit 403 werden die Buildmetadaten aus dem geprüften JAR gelesen. 18 Betriebstests sowie AuthenticatedHttpTest erfolgreich. Reale Wiederherstellung mit tools/remote backend recover erfolgreich, öffentliche Loginseite danach HTTP 200. CI-Lauf 98445d4 einschließlich Deployment erfolgreich in 146 Sekunden. #push-eligibility Fälligkeitsdienst implementiert: eigenes aktives Abonnement, aktives Konto, aktivierte Arbeitserfassung und nicht abgelaufenes Gerät erforderlich. Gerätezeitzone bestimmt Datum und Werktagsfenster 20:00 bis vor 22:00. Arbeitseinträge und freie Tage unterdrücken nur für den passenden Eigentümer und Tag. Sprache wird aus Kontoeinstellung gewählt, mit Englisch als Rückfall. Dienst- und Zeitfenstertests erfolgreich mit H2 File-Modus. Späterer Versand muss diese Prüfung unmittelbar vor dem Senden erneut ausführen; Scheduler, Wartungssperre und Transport bleiben offen. #push-queue Dauerhafte Tageswarteschlange implementiert: Reservierung für 60 Sekunden, zunehmende Wiederholungsabstände bis 15 Minuten, Fristablauf und Versuchszähler gegen verspätete Rückmeldungen. Prüfung pro Reservierung auf aktuelle Fälligkeit. Tests mit H2-Dateidatenbank: Wiederaufnahme, Parallelzugriff, freie Tage, Fristablauf und Tagesledger bei Endpointwechsel erfolgreich. Transport und Wartungssperre bleiben offen; externe Zustellung kann bei verlorener Bestätigung weiterhin mehrdeutig sein. #login-troubleshooting Diagnose am 2026-09-09: Öffentliche frische Formulare funktionieren; gleicher CSRF-Wert ohne ursprüngliche Sitzung reproduziert 403. Laufender Prozess enthält denselben Einrichtungscode wie die geschützte Serverdatei. Keine Login-Mail-Versandfehler im betrachteten Dienstlog; tatsächlicher Erstversand dadurch nicht nachgewiesen. Verständlicher 403-Hinweis mit Link zum erneuten Öffnen der Loginseite implementiert, CSRF-Schutz bleibt aktiv; AuthenticatedHttpTest und EmailLoginHttpTest im Produktionsmodus erfolgreich. Ursache geklärt: Ersteinrichtung wurde ohne Server-Einrichtungscode versucht; deshalb keine E-Mail ausgelöst. Nach Erklärung des Einrichtungscodes bestätigt der Nutzer die erfolgreiche Ersteinrichtung. #data-preservation Verbindliche Entscheidung vom 2026-09-09 nach vom Nutzer bestätigter erfolgreicher Ersteinrichtung: Migrationen müssen ohne Verlust vorhandener Daten erfolgen, einschließlich Gastdaten. Frühere Erlaubnis zum Verwerfen von Daten ist aufgehoben. Keine Datenbank-Resets oder destruktive Ersatzinitialisierung. Änderungen als neue Liquibase-SQL-Changesets mit erhaltender Übernahme vorhandener Werte und Beziehungen; angewendete Changesets nicht nachträglich ändern. Migrationen gegen befüllten Vorgängerstand prüfen. Vor Migration Schreibzugriffe sperren, Dienst stoppen und konsistente Sicherung erstellen. Rückfall vor erneuter Freigabe stellt Anwendung und genau diese Sicherung zusammen wieder her; nach Freigabe keine alte Sicherung über neue Buchungen zurückspielen. Explizite fachliche Löschaktionen bleiben davon getrennt. #push-dispatch Versandkoordinator mit kontrolliertem Transport implementiert. Wartungssperre vor Reservierung und nochmals vor Transport prüfen; bei nicht prüfbarem Verzeichnis nicht senden. Fälligkeit nach Reservierung neu lesen. Datierter Work-Formularlink, sprachabhängiger Text, Tages-Tag und TTL bis zur Abendfrist. Transportfehler bleiben wiederholbar; ungültiger Endpoint deaktiviert nur die unveränderte Abonnementversion. Tests mit H2-Dateidatenbank inklusive Wartungsbeginn und neuem freien Tag zwischen Reservierung und Versand erfolgreich. Noch kein produktiver Transport oder Scheduler angeschlossen; diese sowie Browser-Opt-in bleiben unter push-build offen. CI e257e79 einschließlich Deployment erfolgreich in 163 Sekunden. #push-transport WebPushTransport implementiert: AES128GCM und VAPID über webpush-java 5.1.2, explizite jose4j-/BouncyCastle-Abhängigkeiten, JDK-HTTP-Client mit 5 Sekunden Verbindungs- und 20 Sekunden Requestlimit, keine Weiterleitungen. Zulässige HTTPS-Push-Diensthosts begrenzt; Statuscodes für Erfolg, ungültiges Abonnement und Wiederholung abgebildet. Kontrollierter Test entschlüsselt die Nutzlast und verifiziert VAPID-Signatur; keine echte Nachricht versendet. Vollständiger lokaler CI-Ablauf einschließlich Produktionstest erfolgreich. Nachweis: docs/implementation/web-push-transport.md. Produktive Schlüsselkonfiguration, Scheduler und Browser-Opt-in bleiben offen. #push-runtime Spring-Konfiguration und Scheduler implementiert: nur bei werkjournal.push.enabled=true aktiv, VAPID-Schlüsselpaar bei Initialisierung prüfen, Fehler ohne Schlüsselwerte ausgeben. 60 Sekunden Startverzögerung, 30 Sekunden Pause nach einem begrenzten Batch. Hostsharing-Wartungspfad als Vorgabe, absoluter Override möglich. Tests für deaktivierten und aktivierten Kontext, keine Sofortsendung, ungültige Schlüssel, Wartungspfad und Schedulerfehler erfolgreich. Produktive Schlüsselbereitstellung und Geräte-Opt-in stehen noch aus; auf dem Server wurde Push nicht aktiviert. #push-key-setup remote backend setup-push implementiert und auf dem Deploymentserver erfolgreich ausgeführt. P-256-VAPID-Paar mit vorhandenem JDK direkt auf dem Server erzeugt; nur in geschützter Umgebungsdatei gespeichert, keine Schlüsselausgabe oder Übertragung zurück. Bestehende Login-Konfiguration bleibt erhalten, vollständige Schlüsselpaare werden bei erneutem Aufruf nicht ersetzt. Atomarer Schreibvorgang unter Deploymentlock; Teilkonfiguration und unsichere Dateien werden abgelehnt. 22 Betriebstests erfolgreich. Kein Dienstneustart; Versand bleibt deaktiviert bis Geräte-Opt-in und Freigabe. #push-worker Eigener PWA-Service-Worker implementiert: Vaadin-Offline-/Verbindungslogik erhalten; Push-Nutzlast mit Journal-Icon und Tages-Tag anzeigen. Klick navigiert ein vorhandenes App-Fenster zum datierten Work-Formular oder öffnet ein neues. Fremde Ziele und ungültige Daten werden verworfen. Frontendtests, Produktionsbuild, Prüfung des gebündelten Workers und HTTP-Produktions-Smoke erfolgreich. Erzwungener Produktionsfrontendbuild verhindert Wiederverwendung des alten Standardworkers; Smoke prüft nun die ausgelieferte Worker-Datei. Nachweis: docs/implementation/push-worker.md. Geräte-Opt-in und reale Android-Zustellung bleiben offen. #push-opt-in Gerätebezogener Schalter in Einstellungen implementiert, DE/EN. Status aus authentifiziertem Geräteendpunkt; Browserberechtigung ausschließlich nach bewusstem Einschalten. Einschalten speichert Abonnement und Gerätezeitzone mit Versionsprüfung; Ausschalten deaktiviert zuerst serverseitig. Meldungen für fehlende Unterstützung, Servervorbereitung, verweigerte Berechtigung, Konflikte und abgelaufene Sitzung. Frontendtests, Kotlin-/Produktionsbuild und lokale Browserprüfung der eingebundenen Einstellungsseite erfolgreich. Testserver mit isolierten Daten und gesperrtem Versand. Produktiver Versand bleibt deaktiviert; echte Geräteanmeldung/Zustellung und laufende Zeitzonenaktualisierung noch prüfen. #push-live Am 2026-09-09 aktiviert, nachdem CI 76df11b einschließlich Deployment in 200 Sekunden erfolgreich war. Unter Deploymentlock vorhandenes VAPID-Paar und passenden Anwendungsstand geprüft, Wartungssperre gesetzt, ausschließlich WERKJOURNAL_PUSH_ENABLED auf true gesetzt und Dienst kontrolliert neu gestartet. Bereitschaft einschließlich Flow bestätigt, Wartungssperre entfernt, öffentliche Loginseite HTTP 200. Keine Datenbankdateien durch Aktivierung verändert, keine Schlüssel rotiert, keine Testnachricht erzwungen. Erinnerungen gelten nur für ausdrücklich angemeldete Geräte. Echte Android-Zustellung und Formularnavigation bleiben unter browser-accept offen. #push-zone Letzte Gerätezeitzone wird beim Laden der App, bei Rückkehr ins sichtbare Fenster und minütlich während sichtbarer Nutzung auf Änderungen geprüft. Nur Änderungen werden übertragen; abgelöste Beobachter werden entfernt. MainLayout aktualisiert ausschließlich das zur aktiven Geräteanmeldung gehörende Abonnement. Kein neues Opt-in, keine Verlängerung der Anmeldung und keine Änderung fremder Geräte. Metadatenaktualisierung lässt die Version für Opt-in/Endpoint-Konflikte unverändert. Frontendtests und H2-Diensttests erfolgreich. #push-login-return Implementiert: Beim anonymen Aufruf des datierten Arbeitsformulars bleibt das geprüfte Datum in der HTTP-Sitzung erhalten. Nach erfolgreicher Anmeldung per Code, Link oder Gastzugang führt der gemeinsame Abschluss zum Formular zurück und verwirft die alte Sitzung. Es werden keine beliebigen Weiterleitungsziele übernommen. Neun HTTP-Integrationstests bestanden, einschließlich Gast-Rückkehr, ungültigem Datum, fremdem Redirect und E-Mail-Code aus einer anderen Sitzung. Reale Android-Push-Abnahme bleibt separat offen. #mobile-refinement Nacharbeit: kompakte Stundenanzeige mit h und rechtsbündigem Plus, zentrierte Zählbuttons, Habit-Details eingeklappt mit Grenzwertfarbe am Zähler, rechtsbündiges Menü mit Schließen. Habits mit Tageswerten und Limits löschen; Kunden nach Checkbox-Bestätigung samt Projekten und Arbeitseinträgen löschen. Fachliche Löschaktionen, keine Datenbank-Resets. #release-version-policy Ab jetzt vor jedem Push die Micro-Version erhöhen. Bei wesentlichen neuen Funktionen vor einer Minor- oder Major-Erhöhung den Nutzer fragen. %% Nachweis mobile-refinement: Gesamtprüfung mit 110 ausgeführten JVM-Tests, einem übersprungenen Browser-Harness, 22 Betriebstests, Frontendtests und Produktionsstart erfolgreich. Lokale Browserprüfung Desktop und 360px, DE/EN, keine horizontale Überbreite, Menü-Schließen und Checkbox-Freigabe/Abbrechen geprüft. Löschtransaktionen durch Persistenztests geprüft. Version 0.1.2-SNAPSHOT. #delete-mail Eigene deutsch-/englischsprachige E-Mail mit eindeutigem Löschzweck. Code und Link dürfen nicht zur Anmeldung verwendet werden; der Text erklärt die nachfolgende ausdrückliche Bestätigung und dass das Ignorieren der Nachricht nichts löscht. Gemeinsamer lokaler Sendmail-Transport mit Adressvalidierung, Zeitlimit und ohne Geheimnisse in Logs. Dieser Teil bereitet nur die Nachricht vor; Ausstellung und Einlösung folgen unter delete-proof, Oberfläche unter delete-ui. Abgeschlossen: fünf LoginMailTest-Tests erfolgreich, einschließlich beider Sprachen, eigenem Betreff, Code/Link, Abgrenzung vom Login, Header-Injection und geheimnisfreiem Fehlerfall. Kein echter Mailversand. #delete-proof Separate Kontolösch-Challenge mit gehashtem Code/Link, zwei Stunden Gültigkeit ab Anforderung für Greylisting, fünf Versuchen und 60 Sekunden Anforderungsabstand. Einlösung nur für dasselbe aktive private Konto mit gültiger Geräteanmeldung. Sie erzeugt eine separate fünfminütige, gerätegebundene Löschfreigabe, maximal bis zum ursprünglichen Ablauf. Verbrauch nur innerhalb der späteren Löschtransaktion. Login-Codes/-Links ebenfalls auf zwei Stunden angehoben; bereits ausgestellte Tokens behalten ihren Ablauf. Neue additive Migration, befüllter H2-Vorgängerstand wird auf Datenerhalt geprüft. Abgeschlossen: sieben AccountDeletionProofsTest-Prüfungen einschließlich befüllter Dateidatenbank-Migration, Gerätebindung, paralleler Einlösung, Ersetzung, Widerruf, Ablauf und Transaktionsrollback erfolgreich. Login-Einlösung nach 90 Minuten separat geprüft. Vollständige lokale CI: 120 ausgeführte JVM-Tests, ein übersprungener Browser-Harness, 22 Betriebstests, Frontendtests und Produktionsstart erfolgreich. Kein echter Mailversand. #delete-transaction Löschtransaktion verbraucht frische gerätegebundene Freigabe erst nach expliziter Bestätigung. Entfernt ausschließlich das angemeldete private Konto einschließlich Tracking-Daten, Einstellungen, Identitätsbindungen, offenen Login-Codes, Geräteanmeldungen und Push-Warteschlangen. Verbrauchte Einladungen bleiben ungültig, offene Einladungen des Kontos werden widerrufen und Erstellerverweise aufgelöst. Letzter Admin darf löschen; alter Bootstrap/Wiederherstellungscode wird nicht reaktiviert. Keine weitere Migration und noch keine öffentlich aufrufbare Löschroute. Abgeschlossen: fünf AccountDeletionTest-Prüfungen für vollständige Löschung und Fremddatenerhalt, fehlende/fremde Bestätigung, späten Datenbankfehler mit vollständigem Rollback, Wiederregistrierung und parallele Bestätigung erfolgreich. Zusammen mit sieben Freigabe- und zwei Login-HTTP-Tests sind 14 finale Tests bestanden. Version 0.1.8-SNAPSHOT. #delete-ui Einstellungen bieten privaten Konten den Einstieg „Konto löschen“. E-Mail-Anforderung und Code-/Linkprüfung sind von der abschließenden Bestätigung mit Pflichtcheckbox getrennt. GET löscht nichts, POST ist authentifiziert und CSRF-geschützt. Anonyme Empfänger melden sich zuerst an und öffnen danach den Link erneut oder geben den Code ein. Finale Freigabe nur in HTTP-Sitzung, nicht in Formular oder URL. Abbrechen verwirft die Freigabe; erfolgreiche Löschung beendet Anmeldung und bereinigt lokale Entwürfe dieses Kontos. Abgeschlossen: vollständige lokale CI mit 128 ausgeführten JVM-Tests, einem übersprungenen Browser-Harness, 22 Betriebstests, Frontendtests und Produktionsstart bestanden. HTTP-Prüfung umfasst Anfordern, Code/Link, getrennte Bestätigung, CSRF, Gast-/anonyme Sperre, Abbrechen und Sitzungs-/Cookie-Ende. Lokale Browserprüfung mit simuliertem Mailversand, DE-Formular bei 360px, Pflichtcheckbox und Rückkehr zu Einstellungen erfolgreich; keine Browserfehler. Version 0.1.10-SNAPSHOT. #work-service-gherkin Abgeschlossen: 13 fachliche Beispiele aus gherkin/work-tests.feature werden durch Cucumber gegen reale Dienste und frisch migrierte H2-Dateidatenbanken ausgeführt. Formularvalidierung nutzt denselben ausgelagerten Parser wie die Flow-Oberfläche. Alle Schritte bestanden. Vollständige lokale CI: 144 ausgeführte JVM-Testfälle, vier übersprungene Testcontainer/-fälle, 68 Betriebstests, 17 Frontendtests und Produktionsstart samt Admin-Wiederherstellungsprüfung erfolgreich. Browser-Szenarien bleiben offen. Details: docs/implementation/work-gherkin.md. Version 0.1.25-SNAPSHOT. #habit-service-gherkin Abgeschlossen: sechs fachliche Habit-Gherkin-Szenarien laufen gegen frisch migrierte H2-Dateidatenbanken und reale Dienste. Zwei Flow-Zähler prüfen Konflikt und aktuellen Wert ohne erneute Mutation; Grenzwertprüfungen nutzen die tatsächlichen Status-Elemente. Default-Namen im Szenario auf Reading/Walks korrigiert. Konfliktanzeige lädt den aktuellen Wert, ohne den Klick zu wiederholen. Vollständige lokale CI: 150 ausgeführte JVM-Testfälle, neun übersprungene Fälle (Browser-Abnahme bleibt offen), 68 Betriebstests, 17 Frontendtests und JAR-/Admin-Recovery-Smoke erfolgreich. Keine Datenbankmigration. Details: docs/implementation/habit-gherkin.md. Version 0.1.27-SNAPSHOT. #push-service-gherkin Abgeschlossen: zwölf fachliche Push-Beispiele mit realem Scheduler, dauerhafter Warteschlange, H2-Dateidatenbank und kontrolliertem Testtransport ausgeführt. Wartungsflag, 20–22-Uhr-Fenster, beide Wochenendtage, Geräte-Opt-in, Ausschlussgründe und gemeldeter Zeitzonenwechsel geprüft. Neue Regression WJ-060 beweist: entfernte freie Tage dürfen nicht weiter unterdrücken; Erinnerungsabfrage berücksichtigt jetzt marked=true. CI-Fehler der Habit-Fixture durch starke UI-Referenz behoben. Vollständige lokale CI: 162 ausgeführte JVM-Testfälle, zehn übersprungene Fälle (Browser-Abnahme offen), 68 Betriebstests, 17 Frontendtests sowie JAR-/Admin-Recovery-Smoke bestanden. Keine Migration, kein echter Versand. Details: docs/implementation/push-gherkin.md. Version 0.1.29-SNAPSHOT. #identity-service-gherkin Abgeschlossen: elf Konten-Service-Beispiele mit frisch migrierten H2-Dateidatenbanken, echtem Gerätefilter/AuthenticatedCurrentUser und kontrollierten Login-/Lösch-E-Mails ausgeführt. Einmalige konkurrierende Einladungsnutzung, private Datentrennung auch für Administratoren, Sperrung zweier Geräte, Ablauf nach passiven Heartbeats, dedizierte Löschfreigabe, Wiederregistrierung und einmalige Admin-Wiederherstellung geprüft. Veraltete Szenariobegriffe korrigiert. Vollständige lokale CI: 173 ausgeführte JVM-Testfälle, elf übersprungene Browser-/Harness-Fälle, 68 Betriebstests, 17 Frontendtests und JAR-/Admin-Recovery-Smoke erfolgreich. Alle 42 angebundenen Gherkin-Beispiele bestanden. Keine Produktivcode-/Schemaänderung, kein echter Mailversand. Details: docs/implementation/identity-gherkin.md. Version 0.1.31-SNAPSHOT. #browser-gherkin-runtime Abgeschlossen: WJ-041 läuft mit echtem Chromium gegen eine isolierte Spring-/Vaadin-Anwendung samt eigener H2-Datei und abgefangenem E-Mail-Code. Anmeldung, sichtbares englisches Dashboard, Einstellungsseite und gespeicherte Sprache geprüft. Gepinnte Chromium-/Firefox-Binaries mit Systembibliotheken im neuen Werkdock-Image; Host-Rootfs-Override ebenfalls aktualisiert. Lokale Gesamtprüfung bestanden. Werkator-Commit d0e97b6 erfolgreich einschließlich Deployment; CI-Artefakt belegt alle drei Browser-Schritte als passed und Produktions-/Admin-Recovery-Smoke PASS. Öffentliche Version 0.1.34 bestätigt. Firefox-Ausführung, weitere Browser-Szenarien und Android-Abnahme bleiben offen. Details: docs/implementation/browser-gherkin.md. Abschlussversion 0.1.35-SNAPSHOT. #browser-preferences Abgeschlossen: WJ-038 prüft deutsche Browser-Vorgabe, englische Sprachwahl und erneute Anmeldung mit gespeicherter Kontosprache. WJ-039 prüft getrennte Smartphone-/Desktop-Kontexte für dasselbe Konto, persistentes dunkles Smartphone-Theme und wechselnde Desktop-Systempräferenz anhand tatsächlicher CSS-Farben. Reales Chromium mit isolierter Anwendung und abgefangenen Test-E-Mails; keine Produktivdatenänderung. Vollständige lokale CI: 176 ausgeführte JVM-Fälle, 18 weiterhin offene/übersprungene Abnahmefälle, 68 Betriebstests, 17 Frontendtests und Produktions-/Admin-Recovery-Smoke erfolgreich. Android-/Firefox-Abnahme bleibt offen. Details: docs/implementation/browser-preferences.md. Version 0.1.37-SNAPSHOT. #browser-closed-draft Abgeschlossen: WJ-059 erfasst im echten Chromium einen ungespeicherten Entwurf, schließt den Tab und öffnet dasselbe Formular in einem neuen Tab desselben Geräts. Explizite Wiederherstellung von Datum, Kunde, Projekt, Stunden und Beschreibung geprüft; zuvor leeres Formular und unveränderte Buchungs-/Mutationsdatenbank belegen ausbleibende automatische Speicherung. Alle vier Browser-Szenarien und vollständige lokale CI bestanden: 177 ausgeführte JVM-Fälle, 17 noch offene/übersprungene Abnahmefälle, 68 Betriebstests, 17 Frontendtests und Produktions-/Admin-Recovery-Smoke. Keine Produktivcode- oder Schemaänderung. Details: docs/implementation/browser-closed-draft.md. Version 0.1.39-SNAPSHOT. #browser-tab-conflict Abgeschlossen: WJ-058 bearbeitet denselben Arbeitseintrag in zwei echten Chromium-Tabs. Nach Speichern im ersten Tab und Neuladen im zweiten bleiben dessen Stunden und Beschreibung erhalten. Normaler Speicherversuch meldet Konflikt; erst ausdrückliche Übernahme der angezeigten Basis und erneutes Speichern ersetzen die gespeicherten Werte. Datenbankprüfungen sichern jede Grenze ab. Alle fünf Browser-Szenarien sowie vollständige lokale CI bestanden: 178 ausgeführte JVM-Fälle, 16 noch offene/übersprungene Abnahmefälle, 68 Betriebstests, 17 Frontendtests und Produktions-/Admin-Recovery-Smoke. Keine Produktivcode-/Schemaänderung. Details: docs/implementation/browser-tab-conflict.md. Version 0.1.41-SNAPSHOT. #browser-draft-owner Abgeschlossen: WJ-042 erstellt einen privaten Entwurf, lädt einen zweiten Nutzer über die Admin-Oberfläche ein und prüft nach Ab-/Anmeldung im selben Browser sowie neuem Tab leere Formulare ohne Wiederherstellung. Erneute Anmeldung des ersten Nutzers beweist tatsächliche Entwurfslöschung. Dabei entdeckten Deadlock durch einheitliche Sperrreihenfolge Konto vor Gerät in DeviceLoginService behoben; Nebenläufigkeitstest wartet auf echte H2-Sperre und prüft beide Aufrufe. Alle sechs Browser-Szenarien und vollständige lokale CI bestanden: 180 ausgeführte JVM-Fälle, 15 noch offene/übersprungene Abnahmefälle, 68 Betriebstests, 17 Frontendtests und Produktions-/Admin-Recovery-Smoke. Keine Migration. Details: docs/implementation/browser-draft-owner.md. Version 0.1.43-SNAPSHOT. #browser-habit-limits Abgeschlossen: WJ-001 und WJ-005 erstellen normale Habits über die Oberfläche im mobilen Chromium-Kontext. Ohne Grenzwerte erscheinen Wochensumme, aber keine Limitwarnungen. Überschreiten des Wochenmaximums speichert ohne Bestätigungsdialog; Zählerwarnung und Wert bleiben nach Neuladen, Details nennen die genaue Überschreitung und Plus bleibt bedienbar. Datenbankwerte separat geprüft. Alle acht Browser-Szenarien sowie vollständige lokale CI bestanden: 182 ausgeführte JVM-Fälle (206 gemeldet, 24 durch Suite-Filter/noch fehlende Bindungen übersprungen), 68 Betriebstests, 17 Frontendtests und Produktions-/Admin-Recovery-Smoke. Keine Produktivcode-/Schemaänderung. Details: docs/implementation/browser-habit-limits.md. Version 0.1.45-SNAPSHOT. #browser-habit-month Abgeschlossen: WJ-006 prüft die Woche 31. August bis 6. September 2026 in beiden Monatskalendern mit sieben unterschiedlichen Tageswerten, vollständiger Summe 28, korrekten Nachbarmonatstagen und Wochenmaximum 30 statt der abweichenden Nachbarwochenlimits. Mobile Monatsauswahl und Vor-/Zurücknavigation im echten Chromium geprüft. Alle neun Browser-Szenarien und vollständige lokale CI bestanden: 183 ausgeführte JVM-Fälle (206 gemeldet, 23 durch Suite-Filter/fehlende Bindungen übersprungen), 68 Betriebstests, 17 Frontendtests und Produktions-/Admin-Recovery-Smoke. Keine Produktivcode-/Schemaänderung. Details: docs/implementation/browser-habit-month.md. Version 0.1.47-SNAPSHOT. #browser-work-dayoff Abgeschlossen: WJ-007 markiert im mobilen Browser einen kontrollierten Mittwoch als frei und erfasst drei Stunden. Today zeigt Tages-/Wochen-/Monatssumme; Freimarkierung bleibt erhalten. Reale ReminderEligibility ist vor Markierung fällig, danach bereits ohne Arbeitsbuchung und nach Speicherung nicht mehr fällig; kein Versand. Today nutzt dieselbe Tagesermittlung wie WorkService. CI-Kalenderfehler durch Touch-Auswahl und Warten auf nicht gesperrte Eingabe korrigiert; Produktionsmodus explizit an HTTP-Tests weitergegeben. Vollständige lokale CI: 184 ausgeführte JVM-Fälle (206 gemeldet, 22 gefiltert/noch nicht angebunden), zehn Browser-Szenarien, 68 Betriebstests, 17 Frontendtests und Produktions-/Admin-Recovery-Smoke bestanden. Keine Migration. Details: docs/implementation/browser-work-dayoff.md. Version 0.1.49-SNAPSHOT. #browser-disable-work Abgeschlossen: WJ-008 deaktiviert Arbeit über Einstellungen im echten Browser. Today blendet die Arbeitssektion aus, Habits bleiben sichtbar. Zwei zuvor fällige Geräte-Erinnerungen sind danach nicht mehr fällig. Echter Jahres-JSON-Download enthält die unveränderte Buchung samt Datum, Dauer und Beschreibung. Alle elf Browser-Szenarien und vollständige lokale CI bestanden: 185 ausgeführte JVM-Fälle (206 gemeldet, 21 gefiltert/noch nicht angebunden), 68 Betriebstests, 17 Frontendtests und Produktions-/Admin-Recovery-Smoke. Alle Szenarien von habit-tests.feature sind damit angebunden und bestanden. Vorheriger CI/CD-Lauf 7d24120 einschließlich Kalenderkorrektur erfolgreich. Details: docs/implementation/browser-disable-work.md. Version 0.1.51-SNAPSHOT. #browser-private-export Abgeschlossen: Beide WJ-040-Beispiele laden echte Monats-/Jahresdateien mit zwei per Einladung und E-Mail angemeldeten Testkonten. Exakte Periodengrenzen für Arbeit, Habit-Tage und freie Tage, eigene Werte/Katalognamen, Referenzen und historische Limits geprüft. Erlaubte Schlüssel auf jeder JSON-Ebene verhindern zusätzliche Zugangsdatenfelder; fremde Kontodaten ausgeschlossen. Zeitabhängige Touch-Bestätigung im Kalender-Test durch unterstützte Enter-Bestätigung direkt im Kalendergrid ersetzt; echte Android-Touch-Abnahme bleibt offen. Vollständige lokale CI: 187 ausgeführte JVM-Fälle (206 gemeldet, 19 gefiltert/noch nicht angebunden), 13 Browser-Beispiele, 68 Betriebstests, 17 Frontendtests und Produktions-/Admin-Recovery-Smoke bestanden. Keine Produktivcode-/Schemaänderung. Details: docs/implementation/browser-private-export.md. Version 0.1.53-SNAPSHOT. #browser-work-delete Abgeschlossen: WJ-054 erstellt die Buchung über das Formular, prüft drei Summen, öffnet und bricht den Löschdialog ab und prüft unveränderte Daten. Erst ausdrückliche Bestätigung entfernt den Eintrag und setzt Tages-/Wochen-/Monatssummen auf null. Datenbank nach Öffnen, Abbrechen und Löschen geprüft. Vollständige lokale CI: 188 ausgeführte JVM-Fälle (222 gemeldet, 34 durch zusätzliche Feature-Auswahl gefiltert/noch nicht angebunden), 14 Browser-Beispiele, 68 Betriebstests, 17 Frontendtests und Produktions-/Admin-Recovery-Smoke bestanden. Keine Produktivcode-/Schemaänderung. Details: docs/implementation/browser-work-delete.md. Version 0.1.55-SNAPSHOT. #browser-customer-create Abgeschlossen: WJ-048 tippt einen unbekannten Kunden in die Combobox und verlässt das Feld. Nur die Anlageaktion erscheint; Datenbank enthält noch keinen neuen Kunden. Erst Klick legt genau einen eigenen Kunden an und wählt ihn aus. Projektwahl wird geleert, Stunden/Beschreibung bleiben ungespeichert erhalten. Vollständige lokale CI: 189 ausgeführte JVM-Fälle (222 gemeldet, 33 gefiltert/noch nicht angebunden), 15 Browser-Beispiele, 68 Betriebstests, 17 Frontendtests und Produktions-/Admin-Recovery-Smoke bestanden. Keine Produktivcode-/Schemaänderung. Details: docs/implementation/browser-customer-create.md. Version 0.1.57-SNAPSHOT. #browser-work-conflict Abgeschlossen: WJ-051 meldet dasselbe Konto auf zwei getrennten Browser-Kontexten an. Beide bearbeiten dieselbe Version; erste Änderung bleibt gespeichert, zweite Speicherung meldet Konflikt und erhält eigenen Entwurf auch nach Neuladen. Keine Cookies oder Entwurfsspeicher zwischen Geräten kopiert. Vollständige lokale CI: 190 ausgeführte JVM-Fälle (222 gemeldet, 32 gefiltert/noch nicht angebunden), 16 Browser-Beispiele, 68 Betriebstests, 17 Frontendtests und Produktions-/Admin-Recovery-Smoke bestanden. Alle Szenarien von work-tests.feature sind damit angebunden und bestanden. Keine Produktivcode-/Schemaänderung. Details: docs/implementation/browser-work-conflict.md. Version 0.1.59-SNAPSHOT. #work-quick-actions Today-Einträge verlinken den jeweiligen eigenen Datensatz; Arbeit markiert/fokussiert ihn. Plus/Minus ändern nur die Stunden über die versionierte Speicherlogik (mindestens 1, höchstens 12 pro Tag). Dialogkopf: Schließen mit erhaltenem Entwurf; Papierkorb: Entwurf verwerfen. WJ-061 in Chromium und Firefox bestanden; siehe docs/implementation/work-quick-actions.md.