Responsive & Design:
- Sidebar wird unter 900px zum Off-Canvas-Menue (Hamburger-Button,
Backdrop, Auto-Close bei Navigation) statt fix 228px breit zu bleiben
- Formular-/Statistik-Grids brechen bei 900px/560px auf weniger Spalten
um, Modals gehen unter 560px auf Vollbild, iOS-Zoom-Bug bei
Formularfeldern durch font-size:16px auf Mobile vermieden
- Wärmere Optik ausschliesslich über CSS-Variablen (:root): Creme-
Hintergrund, weichere Akzentfarbe, groessere Radien, neuer
--shadow-Token auf Card/Modal - kein Redesign pro Seite noetig, da
die App durchgehend über diese Variablen themt
Abo-/Zahlungsgeruest (Anbieter voraussichtlich PayPal, noch nicht
angebunden):
- nutzer.abo_bis / abo_typ + globaler Schalter einstellungen.abo_pflicht
(Default AUS) - solange PayPal nicht wirklich läuft, sperrt das Gate
niemanden aus
- _hat_aktiven_zugang() zentral in global_auth_check(): blockiert bei
aktiver Zahlungspflicht ohne gueltiges Abo mit 402 Payment Required,
laesst /api/abo/* und /api/auth/logout immer durch
- POST /api/abo/aktivieren ist bewusst ein 501-Stub bis PayPal echt
angebunden ist - kein vorgetaeuschter Erfolg
- Admin-Dashboard: "Freischalten"-Aktion pro Konto (1-12 Monate,
Pflicht-Begruendung, audit-geloggt) - deckt die geforderte
Moeglichkeit ab, Konten kostenlos freizuschalten
(POST /api/admin/nutzer/<uid>/abo-freischalten)
- Backend-Einstellungen: neue Karte "Abo & Zahlung" fuer Preis und
den abo_pflicht-Schalter
- Frontend: neue Seite "Mein Abo" (pgMeinAbo), aboBlockiert-Flag in
initApp() leitet jede Navigation dorthin um, wenn kein Zugang besteht
Verifiziert: JS-Syntax-Check, Playwright-Screenshots auf Desktop/
Tablet/Mobile (Sidebar-Slide-in, Grid-Umbruch, Interview-Wizard auf
Handy), API-Tests fuer das komplette Abo-Gate (Toggle an/aus, 402,
Freischaltung, Stub-Endpoint, Restore auf sicheren Default).
- Neue Seite admindash (pgAdminDash) mit Kontenuebersicht: Status,
Patientenanzahl, Sperren/Entsperren/Loeschen mit Pflicht-Begruendung
- "Loeschen" ist bewusst Soft-Delete: Konto wird gesperrt (aktiv=0) und
alle aktiven Patienten werden ueber die bestehende Archivierungs-
Logik archiviert (10/30 Jahre Aufbewahrungsfrist, § 630f/§ 199 BGB)
statt physisch geloescht zu werden
- Bestehende Hard-Delete-Route (DELETE /api/nutzer/<uid>) lehnt jetzt
ab, solange das Konto noch Patienten besitzt - schliesst die Luecke
verwaister Patientendatensaetze
- nutzer.aktiv wird bei jedem Request geprueft -> Sperren wirkt sofort,
auch bei bereits offener Sitzung, ohne zusaetzlichen Session-Store
- Neue Tabelle admin_audit_log (unveraenderlich, analog notizen_verlauf):
jede Sperr-/Entsperr-/Loesch-/Export-Aktion mit Admin, Zeitstempel,
Ziel und Pflicht-Begruendung protokolliert
- DSGVO-Export (POST /api/admin/patienten/<pid>/dsgvo-export): admin-only,
verlangt Rechtsgrundlage/Aktenzeichen, liefert ZIP mit allen
Datensaetzen (daten.json) plus Dokumenten/Briefen/Fotos, in-memory
ohne Temp-Dateien
- Selbst-Sperrung/-Loeschung durch den handelnden Admin blockiert
(kein Lockout-Risiko)
- GET /api/nutzer liefert jetzt zusaetzlich patienten_anzahl
Verifiziert: API-Tests fuer alle Guards (Begruendung-Pflicht, Self-Lock-
Block, Hard-Delete-Block bei zugeordneten Patienten, sofortige Session-
Sperrung, 403 fuer Nicht-Admins), ZIP-Inhalt geprueft, Audit-Log-Eintraege
korrekt, Dashboard + Modal per Playwright-Screenshot visuell verifiziert.
Dritter und letzter Baustein aus refactoring.md.
- patienten.nutzer_id (FK -> nutzer.id) als neue Migration in init_db()
- _get_owned_patient(pid) und _scope_sql(column) als zentrale Helper,
auf alle patientenbezogenen Routen angewendet (patienten, antraege,
leistungen, aufgaben, pflegetagebuch, dokumente, kalender, dashboard)
- Admin-Rolle bleibt von der Isolation ausgenommen (sieht weiterhin alle)
- Neue Patienten werden automatisch dem anlegenden Nutzer zugeordnet
- aufgaben ohne patient_id: Erstellung durch Nicht-Admins jetzt
patient_id-pflichtig, damit Lese-/Schreibpfad konsistent bleiben
- Verifiziert per End-to-End-Test mit zwei Nutzerkonten + Admin
Erster Baustein aus refactoring.md; Interview-Flow und Admin-Dashboard
folgen nach Rücksprache (siehe CLAUDE.md).
Fixt außerdem UnicodeEncodeError in start.py (▶-Zeichen crashte auf
Windows-Konsolen mit cp1252-Codepage vor app.run()) durch UTF-8-Zwang
auf stdout/stderr.