syncova-backup/docs/web-ui.md
Jerrit Fritzsche 610719c316
Some checks failed
CI / Backend (Go) (push) Failing after 3m7s
CI / Frontend (React/TypeScript) (push) Successful in 37s
CI / Sicherheitsprüfungen (push) Successful in 44s
Syncova Backups V1
Enterprise-Backup-, Recovery-, Verification-, Security- und
Monitoring-Plattform fuer Proxmox VE, Windows, Linux und Dateisysteme.

Der Leitsatz, der fast jede Entscheidung erklaert: Ein Backup gilt erst als
vertrauenswuerdig, wenn Integritaet geprueft und Wiederherstellbarkeit
nachgewiesen wurde. Deshalb steigt ein Wiederherstellungspunkt erst nach einem
tatsaechlich durchgefuehrten Restore-Test auf "recoverable", und Unbekanntes
geht in keine Bewertung als "gut" ein.

Umfang (Phasen 0-23):

- Repository Engine: inhaltsadressierte Bloecke, atomares Commit-Protokoll,
  Katalogaufbau allein aus den Manifesten — ohne Datenbank
- Backup Engine: inhaltsabhaengiges Chunking, Deduplizierung trotz
  Verschluesselung, zstd, AES-256-GCM, Streaming mit Gegendruck
- Agenten fuer Windows und Linux mit Auftragsabholung (Pull-Modell)
- Proxmox-Provider mit beiden Zugriffswegen auf die Sicherungsarchive
- Scheduler, Recovery Engine mit Pruefpunkt, Verification, Unveraenderlichkeit
- Weboberflaeche, Kennzahlen, Meldungen, Berichte, Security Center,
  Ransomware-Heuristik (meldet, handelt nie)
- Disaster Recovery, Haertung, Leistungsmessung, Chaos Testing
- Eingefrorene Vertraege fuer API, Migrationen, Backup-Format und Repository
- Auslieferungspaket fuer linux/amd64, linux/arm64 und windows/amd64

Nicht enthalten und als solches gekennzeichnet: Kapazitaetsprognose, Backup
Copy, Changed Block Tracking bei Proxmox, erweiterte Attribute und ACLs.

Gebaut, aber nie auf echter Hardware gefahren: der Windows-Dienst, die
systemd-Einheit und der verpflichtende Proxmox-Meilenstein — ob eine
wiederhergestellte VM startet, ist ungeprueft. Einzelheiten in CHANGELOG.md
und docs/release-candidate.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 09:10:54 +02:00

166 lines
7.5 KiB
Markdown

# 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.