# Weboberfläche Phase 12. Die Oberfläche, über die man die Anlage bedient — und der Ort, an dem sich am leichtesten etwas vortäuschen ließe. Der Implementierungsplan nennt fünfzehn Seiten und zehn Kennzahlen. Nicht hinter allen steht heute ein Backend. Wie damit umgegangen wird, ist die eine Entscheidung, die diese Phase trägt. ## Was nicht da ist, wird benannt Drei Wege standen offen: 1. **Nur die fertigen Bereiche zeigen.** Verschweigt den Ausbaustand. Wer die Anlage bewertet, hält für nicht vorgesehen, was nur noch nicht gebaut ist. 2. **Alle Bereiche zeigen, leere Masken dahinter.** Täuscht den Ausbaustand vor. Eine leere Meldungsliste liest sich wie „keine Probleme". 3. **Alle Bereiche zeigen, unfertige benennen.** Gewählt. Ein unfertiger Bereich erscheint im Menü mit dem Vermerk „noch nicht verfügbar" und führt auf eine Seite, die drei Dinge sagt: was fehlt, warum es fehlt, und wo dieselbe Auskunft heute steht. Beispiel Meldungen: > Ein Meldungswesen gibt es noch nicht (Phase 14). Eine leere Liste an dieser > Stelle hieße „keine Probleme" und würde bedeuten „es wird nicht geprüft". Bis > dahin zeigen Übersicht und Ereignisse, was auffällig ist. | Seite | Zustand | | --- | --- | | Übersicht | ✓ `GET /dashboard` | | Sicherungsaufträge | ✓ `GET /jobs` samt Assistent | | Wiederherstellungspunkte | ✓ `GET /backups` | | Wiederherstellungen | ✓ `GET /restores` | | Repositories | ✓ `GET /repositories` | | Agenten | ✓ `GET /agents` | | Ereignisse | ✓ `GET /audit-events` | | Benutzer | ✓ `GET /users` | | Rollen | ✓ `GET /roles` | | Geschützte Systeme | — kein System als eigener Gegenstand im Datenmodell | | Proxmox | — Provider gebaut, keine API, E2E-Nachweis offen (Phase 7) | | Meldungen | — kein Meldungswesen (Phase 14) | | Sicherheit | — keine Gesamtbewertung; Einzelangaben unter Benutzer/Rollen/Ereignisse | | Berichte | — nicht umgesetzt (Phase 15) | | Einstellungen | — Konfiguration läuft über Umgebungsvariablen | ## Die Übersicht Zehn Kennzahlen nach Plan §14, davon sieben mit Datengrundlage: | Kennzahl | Quelle | | --- | --- | | Geschützte Systeme | Quellen aktiver Aufträge, angemeldete Agenten | | Erfolgsquote (7 Tage) | `backup_job_runs` — **ein Teilfehler zählt nicht als Erfolg** | | Aufträge mit Befund | `last_outcome` je Auftrag | | Speicherbelegung | `capacity_bytes` / `used_bytes` der Repositories | | Nachgewiesen wiederherstellbar | Anteil mit `classification = recoverable` | | Repositories | Zustand, gehärtet, gemessener Löschschutz | | RPO eingehalten | letzter erfolgreicher Lauf gegen `rpo_seconds` | Ohne Datengrundlage: **Kritische Meldungen**, **Kapazitätsprognose**, **Security Score**. Sie erscheinen mit der Angabe, was fehlt. ### Sieben Tage, nicht einer und nicht dreißig Ein Tag zeigt bei täglicher Sicherung einen Lauf je Auftrag und schwankt zwischen 0 % und 100 %. Ein Monat verdeckt, dass seit gestern nichts mehr geht. ### Keine Läufe sind nicht 100 % Lief in sieben Tagen keine Sicherung, gibt es keine Quote — die Kennzahl meldet `warning` und sagt es. Ein Dashboard, das bei ausgefallener Sicherung grün zeigt, ist schlimmer als keines. ### Nicht bezifferbar ist nicht null Ist für kein Repository eine Kapazität hinterlegt, gibt es keinen Prozentsatz. Die Kachel zeigt „nicht bezifferbar" und nennt im Detailtext die belegte Menge. Einen Wert zu schätzen wäre eine erfundene Statistik. Umgekehrt gilt dasselbe nach unten: 0,0004 % belegter Speicher erscheint als `< 0,1 %`, nicht als `0 %` — „null Prozent" liest sich wie „nichts abgelegt". ## Wiederherstellungspunkte Die zentrale Seite. Sie beantwortet nicht „welche Backups gibt es", sondern „auf welche kann ich mich verlassen": Einstufung, Bewertung und Schutzlage stehen in jeder Zeile, nicht in einem Detailfenster. - **Ungeprüft ist eine Aussage, keine Lücke.** Ein Punkt ohne Einstufung erscheint gelb mit „ungeprüft" — er wurde nie zurückgeschrieben. - **Keine Bewertung heißt nicht null Prozent.** „nicht berechnet" und „0 %" sind zwei verschiedene Aussagen; die zweite ist ein Befund (Phase 10). - **Gelöschte Punkte erscheinen auf Nachfrage.** Die Frage „warum ist das Backup von vorletzter Woche weg?" ist die erste, die im Ernstfall gestellt wird — der Löschgrund steht am Eintrag. ## Technik ### Navigation ohne Router-Bibliothek Eine Anwendung mit einer Ebene flacher Seiten braucht kein Routing-Framework; sie braucht kopierbare Adressen und einen funktionierenden Zurück-Knopf. Beides leistet die History-API in rund fünfzig Zeilen (`useCurrentPage.ts`). Sobald verschachtelte Routen mit eigenen Unterseiten entstehen, kehrt sich die Rechnung um — dann ist diese Datei der Ort für den Wechsel. **Betriebsfolge:** Das ausgelieferte Bundle braucht einen SPA-Fallback. Ein Neuladen auf `/recovery-points` muss dieselbe `index.html` erhalten, sonst antwortet der Webserver mit 404. Der Vite-Entwicklungsserver tut das von selbst; für den Produktionsbetrieb ist es Sache des vorgelagerten Webservers (`try_files $uri /index.html` bei nginx). ### Ladezustände `useApiResource` hält Laden, Fehler und Ergebnis an einer Stelle. Der Ladezustand wird **abgeleitet**, nicht im Effekt gesetzt: Das Ergebnis trägt den Schlüssel, unter dem es entstanden ist; passt er nicht zum aktuellen, läuft die Anfrage noch. Ein `setState` im Effektkörper löste eine zweite Renderrunde aus, bevor überhaupt etwas geladen wurde — und der Linter weist es zu Recht ab. Nebeneffekt: Beim Filterwechsel bleiben die vorherigen Zeilen stehen, statt dass die Tabelle aufblitzt. ### Fehler tragen ihre Vorgangsnummer Jede Fehleranzeige nennt Fehlercode und `request_id`. Damit lässt sich ein Vorfall im Serverlog eindeutig wiederfinden — ohne sie bleibt „es hat nicht funktioniert". ### Berechtigungen sind Anzeige, keine Sicherung Seiten ohne die nötige Berechtigung erscheinen nicht im Menü. Das ist keine Sicherheitsmaßnahme — die liegt auf dem Server (PROMPT.md §42) — sondern verhindert eine Oberfläche voller Sackgassen. Wer die Adresse direkt aufruft, bekommt eine verständliche Auskunft statt einer Fehlermeldung. ### Farbe nur für Status Grün healthy, gelb warning, orange high, rot critical, blau information. Ein unbekannter Zustand bekommt **keine** Farbe — und schon gar nicht grün. ## Nachgewiesen Gegen den laufenden Dienst mit echten Daten: - Übersicht: 7 von 10 Kennzahlen mit Datengrundlage, drei mit Begründung. - Wiederherstellungspunkte: 9 Punkte, einer `recoverable` mit 80 %, die übrigen „ungeprüft" — keine erfundene Bewertung. - Filter geprüft: nur geschützte (1 Treffer), gelöschte einbeziehen, Einstufung. - Dev-Server liefert `/dashboard` und `/recovery-points` mit HTTP 200; die API läuft über den Proxy ohne CORS. - 60 Frontend-Tests grün, Bundle 246 kB (74,6 kB gzip). ## Bekannte Grenzen - **Keine Pagination in der Oberfläche.** Die API kann sie, die Seiten laden jeweils die ersten 50 Einträge. Bei mehr fehlt der Weg zur zweiten Seite. - **Benutzer und Rollen sind reine Anzeige.** Anlegen und Ändern gehen über die API. Eine Maske müsste die Sonderfälle beherrschen — letzter Administrator, mitgelieferte unveränderliche Rollen — und die gehören geprüft, nicht nebenbei gebaut. - **Kein automatisches Aktualisieren.** Die Seiten laden beim Öffnen. Ein Live-Strom über `/events/stream` ist vorgesehen, aber nicht gebaut. - **Keine Detailansicht je Wiederherstellungspunkt.** Prüfung auslösen, Legal Hold setzen und Wiederherstellung starten gehen über die API.