Commit Graph
22 Commits
Author SHA1 Message Date
adminandClaude Sonnet 5 899fa41b77 CLAUDE.md: pflegepilot_v3-Neubau im Repository-Layout dokumentiert
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-19 13:47:53 +02:00
adminandClaude Sonnet 5 c0a66ced8d open.md: Phase-1-Fortschritt bei Punkt 6 nachgetragen
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-19 13:47:18 +02:00
adminandClaude Sonnet 5 81156f5239 Pflegepilot v3 Phase 1: Patienten-CRUD, Mandantentrennung, Dashboard
get_owned_patient/scoped_patienten_query als typsichere FastAPI-Dependencies
(Ersatz fuer die alten SQL-String-Helper), Patienten-CRUD mit 3er-Cap pro
Konto, Notizen mit Aenderungshistorie, Pflegegrad-Patch, Dashboard-Route.
Frontend: ResponsiveTable/DateWheelPicker/BentoGrid als wiederverwendbare
Bausteine, Patientenliste, Patientenakte, Kurzformular fuer neue Patienten.

Isolation Ende-zu-Ende verifiziert: zweites Konto sieht/erreicht die
Patienten des ersten Kontos nicht (404 statt 403, um Existenz nicht zu
verraten), Admin sieht weiterhin alle Konten uebergreifend.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-19 13:46:48 +02:00
adminandClaude Sonnet 5 47f1665f0f Pflegepilot v3 Phase 0: FastAPI+PostgreSQL+Next.js-Grundgeruest
Kompletter Parallel-Neubau (open.md Punkt 6) neben der unveraenderten
Flask/SQLite-App, verifiziert per docker compose: Auth Ende-zu-Ende
(Login/Registrierung/Logout/Demo-Login), alle 11 Tabellen per Alembic
migriert, WeasyPrint-PDF-Smoke-Test, Admin-Konto gemeinsam angelegt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-19 13:36:10 +02:00
adminandClaude Sonnet 5 559d606d4f Sicherheits-Audit behoben: RCE-Risiko, Stored-XSS, Upload-Whitelist, Rate-Limiting
Alle 12 Findings aus dem Code-Review vom 2026-07-19 (open.md Punkt 5) gefixt:
Direktstart-Bindung auf 0.0.0.0 mit debug=True, fehlende Datei-Typ-Pruefung
beim Brief-Upload, ungesaeuberte X-Forwarded-For-IP im Admin-Dashboard,
fehlendes Rate-Limiting auf Login/Registrierung, fehlende Security-Header,
Freemium-Sperre umgehbar ueber /api/antraege, sowie mehrere kleinere Haertungen
(Passwort-Mindestlaenge, SVG-Upload, toter Code, unbenutzter Import).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-19 12:43:42 +02:00
adminandClaude Sonnet 5 eb6e3e157f Rechnungen rechtskonform nach § 14 UStG, eigene Rechnungsanschrift fuer Admin
Neue Backend-Karte "Rechnungsstellung": eigene Rechnungsanschrift und
Steuerdaten des Betreibers (Steuernummer, USt-IdNr., Kleinunternehmer-
regelung, USt-Satz) - bewusst getrennt von der Betrieb-Karte, da eine
Rechnung eine andere/vollstaendigere Anschrift braucht als das Branding.

Rechnungsnummer wird jetzt serverseitig atomar vergeben (neuer Endpoint
POST /api/admin/rechnungsnummer/naechste, Format {Jahr}-{Nummer:04d}) statt
geraten - Pflicht nach § 14 Abs. 4 Nr. 4 UStG (fortlaufend, einmalig). Die
generierte Rechnung weist je nach Kleinunternehmer-Einstellung entweder
Netto/USt-Satz/USt-Betrag/Brutto getrennt aus oder den Hinweis nach § 19
UStG - vorher fehlten Steuerdaten und Steuerausweis komplett.

Verifiziert per curl: Einstellungen speichern/lesen, fortlaufende
Rechnungsnummern ueber mehrere Aufrufe, Rechtepruefung (nur Admin), Docker-
Rebuild auf leerem Volume. Changelog-Eintrag 1.2.1 ergaenzt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 20:07:24 +02:00
adminandClaude Sonnet 5 44b459bce6 open.md Punkte 1-4: Admin-Fokus, Selbstregistrierung, Rechnungen, Rechtstexte
- KI-Claude-API-Bereich im Backend entfernt (ungenutzt).
- Impressum/Datenschutz/Nutzungsbedingungen im Backend editierbar, oeffentlich
  abrufbar, per Sidebar-Link erreichbar - Betrieb-Karte bewusst NICHT entfernt
  (wird fuer PDF-Briefkopf/Sidebar-Branding aktiv gebraucht, Abweichung von
  der urspruenglichen open.md-Formulierung dokumentiert).
- Admin-Sidebar zeigt nur noch admin-relevante Bereiche, Login/Reload leitet
  Admin direkt auf das Admin-Dashboard statt das allgemeine Dashboard.
- Admin-Dashboard ist jetzt die vollstaendige Nutzerverwaltung: Bearbeiten-
  Button (inkl. Rechnungsanschrift), Registriert-am/Letzter-Login/IP-Spalten.
- Selbstregistrierung (POST /api/auth/registrieren, oeffentlich) mit
  Pflichtfeld Rechnungsanschrift; neue Konten duerfen sofort lesen, aber
  Briefe/Leistungen/Kalender-Eintraege anlegen ist gesperrt bis ein Abo
  vorliegt (selbst_registriert-Flag, unabhaengig vom globalen
  abo_pflicht-Schalter - admin-angelegte Konten sind nicht betroffen).
- Admin kann PDF-Rechnungen pro Konto erstellen (clientseitig, gleiche
  Technik wie Musterbrief/Widerspruch).
- Login-Seite zeigt keine Standard-Zugangsdaten (admin/admin) mehr an.
- Changelog-Eintrag 1.2.0 ergaenzt (siehe Aenderungs-Policy in CLAUDE.md).

Verifiziert per curl (kein Playwright, wie gewuenscht): alle vier Punkte
end-to-end getestet inkl. Schreibsperre/Freischaltung/Rechte-Trennung admin-
vs. selbstregistriert, sauberer Docker-Rebuild auf leerem Volume.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 19:53:23 +02:00
adminandClaude Sonnet 5 d8097e1cf5 Changelog admin-editierbar gemacht; open.md mit neuen Punkten umsortiert
Changelog laeuft jetzt DB-gestuetzt (Tabelle changelog_eintraege) statt rein
statisch aus changelog.py: die Datei bleibt der Entwickler-Seed fuer
Release-Notes zu echten Code-Aenderungen (synct einmalig beim Start alles
Fehlende in die DB), Admin kann Eintraege zusaetzlich direkt im Admin-Bereich
anlegen/bearbeiten/loeschen (neue Route /api/admin/changelog, Steuerung auf
der bestehenden "Was ist neu?"-Seite) - z.B. fuer Ankuendigungen ohne Deploy.
App-Version wird jetzt aus dem neuesten DB-Eintrag abgeleitet statt aus einer
Konstante. Policy ergaenzt: jede kuenftige Aenderung bekommt einen
Changelog-Eintrag, nicht nur eine Commit-Message.

open.md: die 4 vom Nutzer nach dem Docker-Testlauf notierten Punkte nach
Abhaengigkeit/Aufwand sortiert und als Checkliste formatiert (KI-Claude-API
entfernen + Rechtstexte statt "Betrieb"-Karte zusammen, dann
Nutzerverwaltung-Bug + Admin-Dashboard-Fokus, dann Rechnungsanschrift +
Rechnungserstellung, Postgres/React-Migration bleibt als Punkt 5 am Ende).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 19:27:02 +02:00
adminandClaude Sonnet 5 15270ecfa0 open.md: erledigte Punkte 1-3 durch neue Beobachtungen nach Docker-Testlauf ersetzt
Notizen zu Admin-Dashboard-Fokus (Nutzerverwaltung statt Leistungskatalog),
Ersatz der veralteten Betrieb-Sektion durch Impressum/Datenschutz/AGB, und
fehlender Funktionalitaet bei manuell angelegten Testkonten (sperren/loeschen/
Freimonate/Rechnungsanschrift) fuer die naechste Arbeitsrunde festgehalten.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 19:13:20 +02:00
adminandClaude Sonnet 5 c631508d42 Update-Benachrichtigung / Changelog-System hinzugefuegt
Neues Datenmodul changelog.py (neueste zuerst, App-Version wird automatisch
aus dem obersten Eintrag abgeleitet - fuer ein Release reicht ein neuer
Eintrag ganz oben). Jedes Konto merkt sich per nutzer.letzte_gesehene_version,
was es schon gesehen hat; nach Login erscheint einmalig ein Hinweis-Modal mit
allem Neuen, per "Gelesen"-Button quittierbar. Neu angelegte Konten starten
bewusst auf aktuellem Stand, bestehende Konten sehen bei einem echten Update
korrekt den Hinweis - wichtig jetzt, wo die App als versionierte Docker-Images
statt eines durchlaufenden Dev-Prozesses ausgeliefert wird. Dazu ein
dauerhafter Sidebar-Eintrag "Was ist neu?" mit Verlaufsansicht.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 18:58:25 +02:00
adminandClaude Sonnet 5 960bcd6dbf Docker-Containerisierung der App (Flask + SQLite, kein Rewrite)
Dockerfile, docker-compose.yml, requirements.txt und .env (gitignored) fuer
pflegepilot_alpha_v2/pflegepilot ergaenzt. Ein App-Service ueber Gunicorn,
Isolation der Daten ueber zwei benannte Volumes (db, static) statt eines
separaten DB-Containers, da SQLite eingebettet ist. Secret-Key kommt jetzt
aus der Umgebungsvariable SECRET_KEY (lokaler Fallback bleibt fuer
"python start.py" ohne Docker erhalten), Host-Port und Worker-Anzahl sind
ueber .env konfigurierbar. Bewusst keine Domain hinterlegt, da die
DynDNS-Domain erst spaeter auf die Testbench gelegt wird.

Dabei einen Bug in der DB-Migrationsreihenfolge gefunden und behoben: die
nutzer-Tabelle wurde zu spaet angelegt und liess auf einer komplett leeren
Datenbank (z.B. frisches Docker-Volume) mehrere Spalten fehlen, was den
Demo-Konto-Bootstrap zum Absturz brachte.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 18:25:10 +02:00
adminandClaude Sonnet 5 6bfb7a07b6 E-Mail-Versand von SMTP auf mailto-Weiterleitung umgestellt
Server-seitiger SMTP-Versand (Zugangsdaten, /api/email/senden, /api/email/test)
vollständig entfernt und durch mailto: ersetzt: PDF wird lokal generiert und
heruntergeladen, danach öffnet sich das E-Mail-Programm des Nutzers mit
vorausgefülltem Empfänger. Vorbereitung für die Docker-Containerisierung, da
dort nur ein Admin (der Betreiber) existiert und die Lösung ohne
rollenspezifische Ausnahmen für jedes Konto gleichermassen funktionieren muss.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 18:16:18 +02:00
admin af43371a5b Demo-Login fuer Vorfuehrungen (open.md Punkt 1)
- nutzer.ist_demo-Spalte, permanentes Konto demo/demo wird in init_db()
  automatisch angelegt
- Vorausgefuellte fiktive Patientin "Grete Musterfrau" (Pflegegrad 3,
  1 Antrag, 2 Leistungen, 2 Aufgaben, 1 Pflegetagebuch-Eintrag) -
  _demo_seed()
- Automatischer Reset alle 6 Stunden per Lazy-Check (kein Cron/Thread
  noetig): _demo_reset_faellig()/_demo_reset() geprueft bei Login und
  bei jedem Request (global_auth_check), damit auch eine laufende
  Sitzung die 6h-Grenze nicht verpasst
- Demo-Konto von der Abo-Zahlungspflicht ausgenommen (_hat_aktiven_
  zugang) - wurde erst beim Testen entdeckt: bei aktiver Zahlungspflicht
  waere das Demo-Konto sonst mit "Zahlung erforderlich" ausgesperrt
  worden, was fuer eine Vorfuehrung inakzeptabel waere
- E-Mail-Versand (api/email/senden + /test) fuer das Demo-Konto
  gesperrt (403) - verhindert Missbrauch der echten SMTP-Konfiguration
  durch Demo-Besucher
- Login-Screen: neuer "Demo ausprobieren"-Button; Topbar zeigt waehrend
  einer Demo-Sitzung ein "Demo-Modus"-Badge

open.md: Reihenfolge sortiert (Docker-Containerisierung und React+
Postgres-Migration als getrennte Aufgaben markiert, da voellig
unterschiedlicher Umfang), Punkt 1 als erledigt markiert.

Verifiziert: Login, vorausgefuellte Patientendaten, Isolation
(Demo sieht nur eigene Patientin), erzwungener Reset (Patient-ID
aendert sich, demo_reset_at aktualisiert), E-Mail-Sperre (403),
Abo-Ausnahme (Zugriff bleibt moeglich auch bei abo_pflicht=1),
Login-Button und Demo-Badge visuell per Playwright bestaetigt.
2026-07-18 17:48:48 +02:00
admin 8a2e338e9d Sanfte Klapp-Animation, gestaffelte Interview-Fragen, Antragsdatum-Wheel
- Akkordeon-Karten (rtable) animieren jetzt sanft statt abrupt:
  display:none/block durch max-height/opacity/padding-Transition
  ersetzt (display ist nicht transition-faehig, das war die Ursache
  des "Hau-Ruck"-Effekts). Per Mid-Transition-Screenshot verifiziert.
- Interview Step 4 (Pflegealltag-Fragen) zeigt jetzt eine Frage nach
  der anderen statt einer langen Liste: neuWiz.q4sub trackt die
  Position, eigener duenner Fortschrittsbalken (.subdots) innerhalb
  des Schritts. Antwort-Klick rueckt automatisch zur naechsten Frage
  vor, ausser bei der letzten (dort erst per bewusstem "Weiter").
  Zurueck von Schritt 5 landet korrekt auf der letzten Unterfrage.
- openGebDatumPicker generalisiert zu openDatePicker(hiddenId,dispId,
  {fallback,titel,icon,yearMin,yearMax}) und beim Antragsdatum (#adt)
  im Antrag-Pflegegrad-Formular eingesetzt (Default-Scrollposition:
  heute, nicht heute-75 Jahre wie beim Geburtsdatum - fuer nahe
  Termine ist "heute" die sinnvollere Startposition)

Verifiziert per Playwright: alle 6 Unterfragen in Step 4 einzeln
durchgeklickt (inkl. Stopp vor Step 5 bei der letzten Frage und
korrekte Zurueck-Navigation), Antragsdatum-Picker mit korrektem Titel/
Icon/Default getestet, Klapp-Animation per Mid-Transition-Screenshot
bestaetigt.
2026-07-18 13:33:43 +02:00
admin 7cb6191e83 Audit-Log als Karten, Geburtsdatum-Wheel-Picker, Sticky-Quickbar
Drei gezielte Mobile-Verbesserungen nach Nutzer-Feedback:

- Audit-Log (bisher .audit-row Flex-Liste mit festen min-width, auf
  Handy unlesbar zusammengequetscht) zu einer echten Tabelle mit
  class="tw rtable" umgebaut - erbt automatisch das bestehende Karten-
  Akkordeon (nur ein Eintrag offen, Rest kompakt gestapelt)
- Neuer Geburtsdatum-Wheel-Picker (Tag/Monat/Jahr-Spalten mit CSS
  scroll-snap, openGebDatumPicker/dwConfirm/dwTriggerLabel) ersetzt
  natives <input type=date> gezielt nur bei echten Geburtsdatum-Feldern
  (Interview-Wizard, Widerspruch-Generator, Musterbrief) - erspart bei
  60-100 Jahre zurückliegenden Daten das endlose Monat-für-Monat-
  Zurückklicken, auf PC (Mausrad) wie Touch gleich schnell. Andere
  Datumsfelder (Antragsdatum, Bescheiddatum etc.) bleiben nativ, da dort
  ein normaler Kalender fuer nahe Termine schneller ist. Default-
  Scrollposition ist heute-75 Jahre statt heute.
- Schnellzugriff-Kachel wird auf dem Dashboard unter 560px zur
  fixierten Bottom-Bar (Icon-Tab-Leiste) statt Teil des scrollbaren
  Bento-Grids zu sein - Hauptaktionen immer ohne Scrollen erreichbar

Verifiziert per Playwright: Wheel-Picker-Interaktion (Scroll per
Mausrad, Bestätigen, korrekter ISO-Wert im hidden Input), Audit-Log-
Karten auf 390px, Sticky-Bar sichtbar+fixiert im Viewport-Screenshot,
Widerspruch/Musterbrief-Trigger inkl. Live-Vorschau-Aktualisierung.
2026-07-18 13:13:17 +02:00
admin 8dd141ea35 Karten-Akkordeon fuer rtable: nur eine Karte offen, Rest gestapelt
Auf Tablet/Handy sollen die Tabellen-zu-Karten-Ansichten weniger
Scrollen erfordern: jetzt ist immer nur eine Karte aufgeklappt, alle
anderen sind auf eine kompakte Kopfzeile reduziert und stapeln sich
eng darunter.

- Neue rtInit()-Helper-Funktion: erste Zeile startet offen, Klick auf
  eine Zeile oeffnet sie und schliesst alle anderen (Klicks auf
  verschachtelte Buttons/Links/Inputs/.tl loesen die Akkordeon-Logik
  nicht aus, damit Aktionen weiter unabhaengig funktionieren)
- Erste data-label-Zelle pro Tabelle als .rt-head markiert (mit
  Chevron-Icon), bleibt immer sichtbar; restliche data-label-Zellen
  nur bei .rt-open sichtbar. Zellen ohne data-label (Aktions-Buttons)
  bleiben immer erreichbar, auch bei zugeklappter Karte.
- rtInit() nach jedem rtable-Render aufgerufen: pgDash, renderPT
  (inkl. Filter-Refresh), pgAufgaben, renderAdminDash, loadPat
- Bugfix unterwegs: Chevron-Icon leckte in die normale Desktop/Tablet-
  Tabelle (display:none als Basis ergaenzt, nur im 700px-Breakpoint
  sichtbar) - vor dem Fix bei 820px Tablet-Breite als stoerendes Icon
  unter jedem Namen sichtbar

Verifiziert per Playwright auf 390px (Handy) und 820px (Tablet):
Standardzustand (erste Karte offen), Wechsel beim Klick auf andere
Karte, saubere Tabelle ohne Akkordeon-Artefakte oberhalb 700px.
2026-07-18 12:49:08 +02:00
admin 9ebb8f008a Glassmorphism-Redesign + echtes Bento-Grid-Dashboard
Nach Nutzer-Feedback ("immer noch zu klinisch, nicht modern") komplett
neu ausgearbeitet statt der vorherigen warmen CSS-Variablen-Anpassung:

- Neues Glass-Design-System (:root): transluzente Cards/Sidebar/Topbar/
  Modal/Login mit backdrop-filter:blur, weicher Mehrfarb-Gradient-
  Hintergrund (fixed), --bento-*-Farbverlaufstokens fuer Kachelakzente.
  Formularfelder bleiben bewusst blickdicht (Lesbarkeit).
- Dashboard strukturell zum echten Bento-Grid umgebaut: 4 farbige
  Stat-Kacheln + grosse Patienten-Kachel + Aufgaben- + Schnellzugriff-
  Kachel in einem 4-Spalten-Grid mit EXPLIZITER grid-column/grid-row-
  Platzierung (Auto-Placement fuellte die letzte Spalte nicht
  zuverlaessig auf, siehe CLAUDE.md-Hinweis)
- Neue .rtable-Technik: Tabellen werden unter 700px zu einzelnen
  Glass-Cards (Label ueber Wert via data-label + ::before) statt
  zusammengequetschter Spalten - angewendet auf Dashboard-Patienten-
  tabelle, Patientenliste, Aufgaben, Admin-Dashboard-Konten,
  Patientenakte-Antraege
- Login-Screen im gleichen Look neu gestaltet

Verifiziert: JS-Syntax-Check, Playwright auf Desktop/Tablet/Mobile
fuer praktisch alle Seiten (Dashboard, Patientenliste, Patientendetail,
Aufgaben, Katalog, Kalender, Backend, Admin-Dashboard, Interview-
Wizard, Mein Abo, Login). Dabei einen echten Bug gefunden und behoben:
Auto-Placement im Bento-Grid packte die vierte Kachel nicht neben die
dritte - jetzt mit expliziten grid-column/grid-row-Werten geloest.
Ausserdem: stale Flask-Template-Cache bei debug=False identifiziert
(Server muss nach jeder index.html-Aenderung neu gestartet werden,
sonst testet man einen alten Stand) - in CLAUDE.md dokumentiert.
2026-07-18 11:55:49 +02:00
admin 0884f02e15 Responsive/warme Neugestaltung + Abo-Zahlungsgeruest (4,99EUR/Monat)
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).
2026-07-18 11:26:57 +02:00
admin eb57a6eccf Admin-Dashboard: Konten sperren/loeschen, Audit-Log, DSGVO-Export
- 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.
2026-07-18 10:57:58 +02:00
admin bcce456cdb Interview-Onboarding-Flow: pgNeu() als gefuehrter Multi-Step-Wizard
- 6 Schritte statt Einzelformular: Persoenliche Daten, Kontakt/Adresse,
  Krankenversicherung, Pflegesituation, Einschaetzung & Pflegeperson,
  Uebersicht (neuWiz-State, neuRender/neuNext/neuBack/neuCollect)
- Situative Einschaetzung ist reine Regel-Heuristik (fester Punktescore
  ueber 5 Fragen, NEU_FRAGEN/neuSchaetzung) - explizit kein KI-Aufruf,
  mit deutlichem Disclaimer, dass nur die Begutachtung durch den
  Medizinischen Dienst massgeblich ist
- Zielgruppe wird ueber eine situative Frage statt Fachbegriff-Auswahl
  gesetzt (NEU_ZG_OPTIONEN)
- Ersetzt das alte Kompaktformular vollstaendig (kein Nebeneinander)
- Server: hartes 3-Patienten-Limit pro Nicht-Admin-Konto in
  api_neuer_patient (426/refactoring.md: "im Regelfall 1-3 Patienten")
- Verifiziert: JS-Syntax-Check, API-Test (3 Patienten ok, 4. abgelehnt),
  visuelle Pruefung aller 6 Schritte per Playwright-Screenshot

Zweiter Baustein aus refactoring.md; Admin-Dashboard folgt nach
Ruecksprache (siehe CLAUDE.md).
2026-07-18 10:40:43 +02:00
admin 022a286c55 Backend-Isolation: Nutzer sehen nur eigene Patienten
- 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).
2026-07-18 10:26:42 +02:00
admin f234399d28 Baseline commit: Pflegepilot Alpha v2 (lauffähiger Stand vor Refactoring)
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.
2026-07-18 10:19:28 +02:00