{ "task_id": "REVIEW-USER-THEME-001", "summary": "Review und Reparatur des End-to-End-Theme-Prozesses mit klarer Aufloesungsreihenfolge global -> tenant -> user, inklusive Konsistenz zwischen persistierten Werten (DB), Session-Kontext und Frontend-Anzeige. Fokus ist die stabile Anwendung der Theme-Policy bei Login, Tenant-Wechsel und User-Theme-Aenderung sowie die Vermeidung von Drift zwischen Session-State und UI-State.", "assumptions": [ "Die bestehende Prioritaet bleibt fachlich erhalten: tenant default_theme ueberschreibt globales app_theme; user theme greift nur wenn allowUserTheme effektiv true ist.", "Theme-Persistenz fuer User bleibt serverseitig in users.theme; Frontend setzt kein Theme in localStorage als Source of Truth.", "Der Scope umfasst Review plus konkrete Reparaturmassnahmen im bestehenden Codepfad, nicht ein komplettes Redesign des Theme-Subsystems.", "Falls neue Guard- oder Contract-Tests eingefuehrt werden, bleiben sie auf den Theme-Flow begrenzt." ], "scope": { "in": [ "Theme-Aufloesung und Policy-Helfer in lib/Support/helpers/app.php (appDefaultTheme, currentTheme, allowUserTheme)", "Tenant-Session-Hydration und Tenant-Wechsel-Flow in lib/Service/Auth/AuthSessionTenantContextService.php, lib/Service/User/UserTenantContextService.php und pages/admin/users/switch-tenant().php", "User-Theme-Update-Endpunkt in pages/admin/users/theme().php sowie Session-Abgleich in pages/admin/users/edit($id).php", "Theme-UI-Anbindung in templates/default.phtml, templates/partials/app-topbar.phtml und web/js/components/app-theme-toggle.js", "Gezielte Tests in tests/Service und tests/Architecture fuer Theme-Resolution/Policy und Session-Refresh-Szenarien" ], "out": [ "Neues Theme-Design, neue Theme-Paletten oder CSS-Redesign", "Aenderungen an nicht themenrelevanten Auth-, RBAC- oder Tenant-Features", "Migration auf clientseitige Theme-Persistenz in localStorage", "API-Versionierungs- oder OpenAPI-Redesign ausserhalb notwendiger Theme-Contract-Anpassungen" ] }, "guardrails": { "required_guard_ids": [ "GR-CORE-001", "GR-CORE-003", "GR-SEC-001", "GR-UI-009", "GR-UI-010", "GR-UI-011", "GR-TEST-001", "GR-TEST-002" ], "required_quality_gate_ids": [ "QG-001", "QG-002", "QG-003", "QG-005", "QG-006" ] }, "success_criteria": [ { "id": "SC-001", "criterion": "Die effektive Theme-Aufloesung ist eindeutig dokumentiert und im Code konsistent umgesetzt: global app_theme, tenant default_theme override, user theme nur bei erlaubter User-Theme-Policy." }, { "id": "SC-002", "criterion": "Nach Tenant-Wechsel ist die Session vollstaendig konsistent (user.current_tenant_id und current_tenant-Daten), und das gerenderte Theme entspricht der Ziel-Prioritaet ohne stale Zustand." }, { "id": "SC-003", "criterion": "Bei deaktivierter User-Theme-Policy wird kein inkonsistenter User-Theme-Zustand in Session/Antworten sichtbar, und Theme-UI verhält sich deterministisch (inkl. Fehler-Rollback)." }, { "id": "SC-004", "criterion": "Theme-Flow ist ueber reproduzierbare Tests abgedeckt (mindestens Login-/Hydration-, Tenant-Switch- und Theme-Update-Szenario inkl. Negativfaelle)." }, { "id": "SC-005", "criterion": "Alle geforderten Quality Gates laufen erfolgreich und zeigen keine Regression in Architektur, Typen, Stil und JS-Smoke." } ], "implementation_steps": [ { "id": "S1", "title": "Ist-Analyse und Entscheidungs-Flow fixieren", "description": "Erstelle eine verbindliche Theme-Decision-Matrix fuer die vorhandenen Pfade (helpers/app.php, AuthSessionTenantContextService, users/theme endpoint, tenant switch, topbar toggle). Dokumentiere pro Entry-Point Input-Quellen, Prioritaet und erwarteten Output in Session + HTML data-theme.", "guard_refs": [ "GR-CORE-001", "GR-TEST-002" ] }, { "id": "S2", "title": "Konsistenzluecken im Session-Refresh beheben", "description": "Repariere Theme-relevante Session-Synchronisation bei Tenant-Wechsel und Profil-/Theme-Updates, so dass current_tenant und user.theme nicht auseinanderlaufen. Stelle sicher, dass bei Policy-Wechseln (allow/disallow user theme) keine veralteten Werte den gerenderten Zustand verfälschen.", "guard_refs": [ "GR-CORE-001", "GR-CORE-003", "GR-SEC-001" ] }, { "id": "S3", "title": "Frontend-Theme-Toggle gegen Drift absichern", "description": "Haerte app-theme-toggle.js und topbar Theme-Menue gegen race/failure Situationen ab (optimistic update mit robustem rollback, konsistente active-state Markierung, keine lokale Persistenz als Wahrheit). Verifiziere, dass nur serverbestaetigte Aenderungen dauerhaft gelten.", "guard_refs": [ "GR-UI-011", "GR-UI-009" ] }, { "id": "S4", "title": "Gezielte Testabdeckung fuer Theme-Policy und Tenant-Kontext aufbauen", "description": "Ergaenze/aktualisiere Service- und Architekturtests fuer Theme-Aufloesung und Policy-Edge-Cases: tenant override vorhanden/leer, global fallback, user theme erlaubt/verboten, tenant switch mit geaenderter allow_user_theme/default_theme Kombination, Fehlerpfade bei Theme-POST.", "guard_refs": [ "GR-TEST-001", "GR-TEST-002", "GR-SEC-001" ] }, { "id": "S5", "title": "Guard/Gate-Nachweis und Abschluss-Review", "description": "Fuehre QG-001, QG-002, QG-003, QG-005 und QG-006 aus, mappe Ergebnisse auf SC-IDs und dokumentiere explizit die korrigierte Theme-Prioritaet sowie die Session-Konsistenz nach Tenant-Wechsel und Theme-Update.", "guard_refs": [ "GR-TEST-001", "GR-UI-009" ] } ], "tests": [ "Unit-Test fuer Theme-Aufloesung: appDefaultTheme/currentTheme/allowUserTheme mit Kombinationen aus app_theme, tenant default_theme, tenant allow_user_theme und user.theme.", "Service-Test fuer AuthSessionTenantContextService::hydrateForUser inklusive no_active_tenant, current_tenant fallback und tenant-bezogener Theme-/Policy-Daten in Session.", "Endpoint-Test fuer pages/admin/users/theme().php: valid theme, invalid theme, theme_disabled, csrf failure, unauthorized; inkl. Session-Update-Verhalten.", "Integration-/Flow-Test fuer Tenant-Switch (pages/admin/users/switch-tenant().php + JS): erfolgreicher Wechsel, nicht zugewiesener Tenant, Fehler-Rollback im UI.", "QG-001: docker compose exec php vendor/bin/phpunit", "QG-002: docker compose exec php vendor/bin/phpstan analyse -c phpstan.neon --no-progress", "QG-003: docker compose exec php vendor/bin/phpunit tests/Architecture/CoreStarterkitContractTest.php", "QG-005: Browser-Smoke fuer Theme-Wechsel und Tenant-Wechsel ohne neue JS-Fehler", "QG-006: docker compose exec php composer cs:check" ], "acceptance_checks": [ "SC-001: Decision-Matrix und Code stimmen ueberein; keine widerspruechliche Theme-Prioritaet zwischen Helpern, Endpoints und Rendering.", "SC-002: Nach Tenant-Wechsel zeigt HTML data-theme reproduzierbar das korrekte effektive Theme des neuen Tenant-Kontexts.", "SC-003: Bei deaktivierter User-Theme-Policy kann User-Theme nicht inkonsistent aktiv bleiben; Theme-POST liefert deterministisches Verhalten.", "SC-004: Alle definierten Theme-Flow-Tests laufen gruen und decken mindestens einen Failure- oder Edge-Case je Hauptpfad ab.", "SC-005: QG-001, QG-002, QG-003, QG-005 und QG-006 sind PASS." ], "ux_notes": { "affected_patterns": [ "Topbar account dropdown theme menu", "Document root data-theme rendering in default layout", "Theme toggle interaction in app-theme-toggle.js", "Tenant switch dropdown interaction" ], "ui_states_required": [ "loading", "empty", "error", "success" ], "a11y_touchpoints": [ "Theme option menu items with active state and aria-current semantics", "Theme toggle button/icon state change feedback", "Tenant switch menu links with pending and error handling", "Error feedback visibility for failed theme/tenant actions" ] }, "risks": [ { "risk": "Verteilte Theme-Logik in Helpern, Session-Hydration und UI fuehrt zu partiellen Fixes statt stabiler Gesamtloesung.", "mitigation": "Vor Code-Aenderung verbindliche Decision-Matrix erstellen und jede Aenderung gegen dieselbe Matrix validieren." }, { "risk": "Optimistische UI-Updates erzeugen kurzzeitige falsche Darstellung bei Request-Fehlern oder Race-Conditions.", "mitigation": "Explizites rollback auf letzten servergueltigen Zustand und testbarer Fehlerpfad im Toggle/Switch-Flow." }, { "risk": "Tenant-Policy-Edge-Cases (inherit/allow/disallow) bleiben ungetestet und regressieren spaeter.", "mitigation": "Gezielte Matrix-Tests fuer alle Policy-Kombinationen plus mindestens ein End-to-End-Szenario je Kombination." }, { "risk": "Nebenwirkungen in bestehenden Auth-/Tenant-Flows durch Session-Refactor.", "mitigation": "Aenderungen auf Theme-relevante Session-Felder begrenzen und mit QG-001/QG-003 voll regressionspruefen." } ] }