# Sprint 6E.4B – Gesundheitsakte, Dokumentworkflow, Kalender und Tagesansicht

## Ausgangspunkt und Scope

- Verbindliche Basis: `95c9c03b222169c50b866e83129bbf2e497d80ee`
- Privates Profil: `health-record-6e`
- V5-only: V4 wurde weder regeneriert noch ersetzt.
- Keine Datenbank-/FTS-Migration, keine öffentliche Route und kein neuer Tunnel.
- Sprint 6E.4C, Sprint 6F und das vollständige Cockpit-Redesign sind nicht Bestandteil dieses Releases.

## Reale read-only Reproduktion vor der Änderung

Die bestehende private Runtime wurde mit Browser-Session und realer Datenquelle ausschließlich read-only auditiert. Erfasst wurden nur sichere technische Zähler und Statusklassen; keine Titel, Inhalte, Werte, Pfade, IDs, URLs, Cookies oder Zugangsdaten.

| Vertrag | Sichere technische Evidenz |
|---|---:|
| Listenaufrufe | 3 |
| gelistete Dokumentmetadaten | 70 |
| `review_status=geprueft` | 4 |
| `review_status=nicht_geprueft` | 45 |
| `review_status=unknown` | 21 |
| Detail HTTP 200 | 4 |
| Detail HTTP 404 | 66 |
| geprüfte Details mit extrahiertem Inhalt | 4 |
| alter `original_available=true`-Wert | 4 |
| davon `HEAD /original` HTTP 200 | 3 |
| davon `HEAD /original` HTTP 404 | 1 |
| vollständig per GET technisch verifiziertes reales Original | **ja** |

Damit war der reale Fehler reproduziert: Ein gespeicherter Pfad erzeugte vier positive Verfügbarkeitswerte, obwohl die autoritative Originalroute einen davon fail-closed ablehnte.

Die Rootanalyse blieb ebenfalls rein technisch:

- zwei konfigurierte Rootklassen;
- vier geprüfte Dokumente lagen in Rootklasse 1;
- davon drei `available`, eines `unsupported`;
- 40 weitere Metadatensätze lagen in Rootklasse 1, 26 außerhalb; alle 66 waren nicht geprüft und wurden deshalb unabhängig vom Pfad als `not_reviewed` behandelt;
- kein zusätzlicher privater Root war für ein geprüftes gültiges Original erforderlich.

## Einheitlicher Dokumentvertrag

Listen-, Detail-, HEAD- und GET-Pfade verwenden jetzt denselben fail-closed Originalprüfer.

### Öffentliche Zustände

```text
review_status:
- geprueft
- nicht_geprueft
- unknown

content_status:
- available
- not_reviewed
- no_extracted_content
- unavailable

original_status:
- available
- not_reviewed
- missing
- blocked
- unsupported

document_date_status:
- known
- unknown
```

`original_available` bleibt im Detail nur als kompatibles boolesches Feld erhalten und ist exakt dann wahr, wenn `original_status == available` gilt. Ein gespeicherter Pfad allein ist kein Verfügbarkeitsnachweis mehr.

### Sicherheitsvertrag

- geprüfter Dokumentstatus bleibt zwingend;
- absolute oder relative Kandidaten müssen unter einer konfigurierten Rootklasse liegen;
- Rootkonfiguration wird beim Serverstart validiert;
- komponentenweises `openat` mit `O_NOFOLLOW`;
- keine Symlinks in Zwischen- oder Endkomponenten;
- gepinnter Dateideskriptor, danach `fstat`;
- nur reguläre Dateien;
- Größenlimit 20 MiB;
- Magic-Prüfung für PDF, PNG und JPEG;
- generischer Downloadname ohne gespeicherten Originalnamen;
- HEAD und GET öffnen und prüfen jeweils neu; ein erfolgreiches HEAD ist kein Capability-Token;
- keine Pfade, Originaldateinamen, Drive-IDs, URLs oder numerischen Datenbank-IDs in Browserantworten.

Ungeprüfte Dokumente bleiben chronologisch als Metadaten sichtbar. Inhalts- und Originalaktionen bleiben deaktiviert; der Detailvertrag liefert weiterhin 404.

## Gesundheitsakte

- neue visuelle Aktenübersicht mit sechs fachlichen Kennzahlen;
- kompakte Gruppen für Labor, Medikamente, Termine und Dokumente;
- Dokumenthistorie als responsive Timeline statt Datentabelle;
- Filter für Volltext, Datum, Kategorie, Institution, Typ, Prüfstatus und Sortierung;
- explizite Statuschips für Prüfung, Inhalt, Original und Datum;
- eigene Vieweransicht mit Rücknavigation, Originalstatus, Inhaltsverzeichnis sowie Vorher-/Nächster-Treffer;
- Fokus- und History-Verträge bleiben reload- und zurück/vorwärtsfest;
- mobile Tabs umbrechen statt die Seite horizontal zu verbreitern;
- interaktive Ziele mindestens 44 × 44 px.

## Kalender

FullCalendar Standard `6.1.21` ist lokal gebündelt und über Integritätshash, MIT-Lizenz und Metadaten gepinnt. Enthalten sind ausschließlich Core, DayGrid, Interaction, List und die deutsche Locale; keine Premium-/Scheduler-Komponente und kein Browser-CDN.

- echtes Monatsraster mit Montag als Wochenbeginn;
- deutsche Monats- und Wochentagsbezeichnungen;
- autoritativer Server-Tag und `Europe/Zurich`;
- vorheriger/nächster Monat, Heute und expliziter Monatspicker;
- Ereigniskategorien bleiben farb- und symbolunabhängig erkennbar;
- mobil kompakte Kategoriepunkte;
- Maus-/Touch-Auswahl eines Bereichs sowie explizite Von/Bis-Felder;
- Bereichsübergabe an den bestehenden Explorer;
- Tastaturnavigation über Pfeile, Enter und Leertaste;
- sechs Monate zurück, leere Monate, Reload und Browser-History getestet.

## Visuelle Tagesansicht

- priorisierte Tageskennzahlen für Schlaf, Ruhepuls, HRV, Schritte und Symptomstatus;
- pro dokumentierter Kennzahl ein lokaler ECharts-7-Tage-Kontext;
- ausgewählter Tag und persönlicher Median sind visuell markiert;
- keine neuen Durchschnitts-/Summen-/Direktableitungen im primären Inhalt;
- Symptome, Ernährung, Medikamente, Labor, Ereignisse und Dokumente nur bei vorhandenem Inhalt als Karten;
- fehlende Bereiche in einem einzigen kompakten Hinweis;
- technische Datenherkunft in einem sekundären `details`-Bereich;
- 390 × 844 px ohne Seitenoverflow, mit 44-px-Zielen.

## Wiederverwendbare V5-Grundlage

`dashboard-v5.css` enthält ergänzend:

- Abstands-, Radius-, Schatten-, Border-, Surface- und Status-Tokens;
- 12-Spalten-Raster;
- Surface-/KPI-/Leer-/Fehler-/Skeleton-Komponenten;
- Primary-, Secondary- und Tertiary-Buttons;
- Statuschips;
- responsive Record-, Kalender-, Viewer- und Tageslayouts.

Diese Grundlage nimmt das vollständige Cockpit-Redesign noch nicht vor; das bleibt Sprint 6E.4C.

## Tests und Gates

- fokussierte Pythonregressionen: **33 bestanden**;
- fokussierte Browserfälle für Akte, Originale, Kalender und Tag: **29 bestanden**;
- vollständige Python-Suite: **227 bestanden**;
- isolierte Browsermatrix: **66 bestanden**, **4 bewusst stillgelegte Legacy-Chart.js-Fälle**, **9 Gruppen**;
- Ruff für alle geänderten Python-Dateien, Python-/Node-/Bash-Syntax und `git diff --check`: bestanden;
- reale synthetische Servergruppe mit temporärer SQLite-Datenbank und echten temporären PDF-/PNG-Dateien: bestanden;
- HEAD→Dateiaustausch→GET wird erneut geprüft und fail-closed abgelehnt;
- FullCalendar-Integrität, Lizenz und lokale Browserladung: bestanden;
- der nicht verwendete eingebettete `fcicons`-Data-Font wurde entfernt; der Browservertrag prüft zusätzlich null CSP-/Konsolenfehler;
- keine Nicht-Same-Origin-Anfragen in den neuen Kalenderfällen;
- Datenschutzscan und visuelle Kontrolle der acht Bilder: bestanden.

## Synthetische Screenshot-Evidenz

- `docs/test-results/sprint6e4b-assets/record-overview-desktop.png`
- `docs/test-results/sprint6e4b-assets/record-documents-desktop.png`
- `docs/test-results/sprint6e4b-assets/record-viewer-desktop.png`
- `docs/test-results/sprint6e4b-assets/record-mobile.png`
- `docs/test-results/sprint6e4b-assets/calendar-desktop.png`
- `docs/test-results/sprint6e4b-assets/calendar-mobile.png`
- `docs/test-results/sprint6e4b-assets/day-desktop.png`
- `docs/test-results/sprint6e4b-assets/day-mobile.png`

Alle Screenshots stammen aus synthetischen Fixtures. Die visuelle Prüfung zeigte keine abgeschnittenen Inhalte, Überlappungen oder horizontalen Seitenoverflows.

## V4, Deployment und Rollback

V4-Prüfsumme vor dem Release:

```text
012f39afefa97dc7a310c52bd2151c18d45f533ce42fda96c334309574eddb6a
```

Vor dem privaten V5-Deployment wird das Rollback-Bundle mit bisherigem V5-HTML, Runtime-Skripten, Assets und Checksummen aktualisiert. Deployment und Rollback ersetzen ausschließlich V5-Artefakte und starten den privaten Dashboard-Service kontrolliert neu. V4 wird nicht regeneriert oder ersetzt. Nach dem Deployment folgen privater Real-Data-Smoke, erneuter Dokumentstatusaudit und V4-Prüfsummenvergleich.

## Bewusste Restpunkte

- vollständiges Cockpit-Redesign: Sprint 6E.4C;
- weitere Produktbereiche und Sprint 6F: nicht begonnen;
- keine neuen Schreib-, Upload-, Mapping- oder Erfassungspfade in Sprint 6E.4B.
