docs/web-ui.md beschrieb die Oberflaeche aus Phase 12 — eine, die es nicht mehr gibt. Eine Anleitung, die auf Bereiche verweist, die anders heissen und anders funktionieren, ist schlimmer als keine: Der Leser sucht den Fehler bei sich. Neu geschrieben. Eine Aussage darin habe ich beim Nachpruefen korrigiert: `/api/v1/events/stream` steht zwar in SYNCOVA_API.md, ist aber **auch serverseitig** nicht umgesetzt. "Nicht angebunden" haette den Mangel der Oberflaeche zugeschoben. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
182 lines
8.5 KiB
Markdown
182 lines
8.5 KiB
Markdown
# Weboberfläche
|
|
|
|
Die Konsole, über die man die Anlage bedient — und der Ort, an dem sich am
|
|
leichtesten etwas vortäuschen ließe.
|
|
|
|
Sie erreicht **89 von 95 fachlichen Endpunkten**. Die sechs offenen sind
|
|
Detail-Abrufe (`GET /alerts/{id}`, `GET /agents/{id}`, `GET /proxmox/vms/{id}`,
|
|
`GET /security/findings`, `GET /verification/{id}` und dessen Ergebnisse), deren
|
|
Daten die jeweiligen Listen bereits enthalten.
|
|
|
|
## Die eine Entscheidung, die alles trägt
|
|
|
|
**Semantische Farben ausschließlich für Zustände** (PROMPT §106). Die Konsole ist
|
|
neutral gehalten; wo Farbe erscheint, bedeutet sie etwas. Eine bunte Oberfläche
|
|
verschleiert, welche Information wirklich dringend ist — und in einer
|
|
Backup-Konsole ist genau das die einzige Frage, die zählt.
|
|
|
|
Daraus folgt der Zuschnitt: kein Markenblau als Fläche, der Akzent nur für
|
|
Bedienelemente. Der Schweregrad einer Kennzahl färbt die **Randlinie**, nicht die
|
|
Kachel; zehn farbige Flächen nebeneinander ergeben ein Mosaik, in dem die eine
|
|
kritische Zahl untergeht.
|
|
|
|
### Die Statuszuordnung steht an genau einer Stelle
|
|
|
|
`components/ui/StatusBadge.tsx` bildet jeden Fachbegriff der API auf einen der
|
|
fünf Töne ab. Wäre diese Abbildung über die Seiten verteilt, erschiene früher
|
|
oder später irgendwo `partial_failure` grün — und ein Betreiber hält einen
|
|
Teilfehler dann für einen Erfolg.
|
|
|
|
Vier Zuordnungen sind keine Geschmacksfrage:
|
|
|
|
| Wert | Ton | Warum |
|
|
| --- | --- | --- |
|
|
| `partial_failure` | Warnung | Entwicklungsregel 1: nie `SUCCESS` |
|
|
| `successful` (Einstufung) | **neutral** | Heißt „der Lauf ist durchgelaufen", nicht „wiederherstellbar" |
|
|
| `corrupted` | kritisch | Nicht zu 70 % wiederherstellbar, sondern gar nicht |
|
|
| `advisory` (Löschschutz) | Warnung | Der Schutz ist eine Software-Regel, kein Schutz des Dateisystems |
|
|
|
|
**Ein unbekannter Wert wird neutral dargestellt, niemals grün.** Ein neuer
|
|
Serverzustand, den die Tabelle nicht kennt, darf nicht als „in Ordnung"
|
|
durchgehen. `StatusBadge.test.tsx` hält alle fünf Punkte fest; jeder wurde durch
|
|
Mutation als fangend bestätigt.
|
|
|
|
## Was nicht da ist, wird benannt
|
|
|
|
Der Grundsatz aus PROMPT §139 gilt unverändert: Ein Menü, das nur die fertigen
|
|
Bereiche zeigt, verschweigt den Ausbaustand; eines mit leeren Masken täuscht ihn
|
|
vor. Jeder Eintrag erscheint, und ein noch nicht verfügbarer nennt, was fehlt.
|
|
|
|
Konkret sichtbar an vier Stellen:
|
|
|
|
- **Kennzahlen ohne Datengrundlage** erscheinen mit Begründung statt mit einer
|
|
Null. „0 kritische Meldungen" hieße „keine Probleme" und bedeutete „es wird
|
|
nicht geprüft".
|
|
- **Ungemessene Eingangsgrößen der Bewertung** stehen als „ungemessen" da, nicht
|
|
als null Punkte. Als 0 zu zeigen bestrafte das Unbekannte.
|
|
- **Nicht ausgewertete Meldungsregeln** werden als solche gekennzeichnet. Eine
|
|
Regel, die dauerhaft schweigt, ist gefährlicher als keine.
|
|
- **Ungeprüfte Bereiche im Security Center** gehen weder positiv noch negativ in
|
|
die Rechnung ein; ab drei sagt die Seite, dass die Zahl eine Vermutung ist.
|
|
|
|
## Die achtzehn Seiten
|
|
|
|
| Bereich | Seiten |
|
|
| --- | --- |
|
|
| **Betrieb** | Übersicht · Sicherungsaufträge · Wiederherstellung · Meldungen |
|
|
| **Daten** | Wiederherstellungspunkte · Prüfung · Repositories · Aufbewahrung |
|
|
| **Infrastruktur** | Agenten · Proxmox · Geschützte Systeme |
|
|
| **Analyse** | Kennzahlen · Berichte · Security Center |
|
|
| **Verwaltung** | Benutzer · Rollen · Ereignisprotokoll · Einstellungen |
|
|
|
|
Die Gliederung folgt dem Weg durch die Anlage: Was täglich beobachtet wird, steht
|
|
oben; was einmal eingerichtet und dann selten angefasst wird, unten.
|
|
|
|
## Handlungen, die etwas verändern
|
|
|
|
### Die drei Hürden vor dem Überschreiben
|
|
|
|
Der Wiederherstellungs-Assistent setzt sie sichtbar um:
|
|
|
|
1. Das Kennzeichen `overwrite_existing` muss gesetzt werden.
|
|
2. Die Berechtigung `restores.overwrite` prüft der Server — sie steckt bewusst
|
|
**nicht** in `restores.execute`.
|
|
3. `confirm_overwrite` verlangt den **wörtlich wiederholten Zielpfad**.
|
|
|
|
Läuft die dritte ins Leere, weil das Ziel leer ist, entfällt sie. Ein Ritual ohne
|
|
Anlass gewöhnt das Wegklicken an — und dann wirkt es dort nicht mehr, wo es
|
|
zählt. Dieselbe Überlegung trägt die wörtliche Bestätigung beim Löschen eines
|
|
Wiederherstellungspunkts, eines Auftrags und beim Anwenden einer
|
|
Aufbewahrungsregel.
|
|
|
|
### Die Vorabprüfung ist ein eigener Schritt
|
|
|
|
Sie schreibt nichts und stellt fest, ob **jeder benötigte Block noch da ist**.
|
|
Ein Manifest allein belegt nur, dass jemand einmal etwas gesichert hat. Fehlende
|
|
Blöcke stehen ganz oben und in Rot; sie sind der einzige Befund, bei dem
|
|
feststeht, dass die Wiederherstellung nicht vollständig gelingen kann.
|
|
|
|
### Ein 409 ist eine Auskunft, kein Fehler
|
|
|
|
Ein zweiter Anstoß bei laufendem Auftrag erscheint als Hinweis, nicht als
|
|
Fehlschlag. Der Auftrag läuft ja — und genau das wollte der Betreiber wissen.
|
|
|
|
### Was Löschen wirklich bewirkt, steht dabei
|
|
|
|
- Ein gelöschter **Auftrag** nimmt seine Wiederherstellungspunkte nicht mit. Sie
|
|
gehören zum Repository. Ohne diesen Hinweis löscht jemand einen Auftrag in der
|
|
Annahme, Platz zu schaffen.
|
|
- Wird beim Löschen **kein Speicher frei**, ist das kein Fehler, sondern
|
|
Deduplizierung: Die Blöcke werden von einem anderen Backup gebraucht.
|
|
|
|
### Geheimnisse gehen nur hinein
|
|
|
|
Das Aufnahme-Token eines Agenten erscheint **genau einmal**, mit
|
|
ausdrücklichem Hinweis und ohne Weg, den Dialog versehentlich zu schließen. Das
|
|
API-Token eines Proxmox-Verbunds wird nach dem Anlegen nie wieder ausgeliefert —
|
|
das ist kein Mangel, sondern der Grund, warum ein Lesezugriff auf die
|
|
Konfiguration ungefährlich ist.
|
|
|
|
## Technik
|
|
|
|
- **Tailwind v4 und Radix-Primitive** nach shadcn-Muster. Alles gebündelt; die
|
|
CSP der Auslieferung lässt externe Ressourcen ohnehin nicht zu.
|
|
- **Farben als CSS-Variablen**, damit dieselbe Komponente in beiden Themen
|
|
funktioniert, ohne dass jede Klasse eine `dark:`-Variante braucht.
|
|
- **Dark Mode über ein Attribut am Wurzelelement**, nicht allein über die
|
|
Medienabfrage: Eine Konsole, die nachts während einer Störung von selbst
|
|
umschaltet, ist lästig. Das Attribut sitzt am Wurzelelement, weil ein Dialog im
|
|
Portal sonst im falschen Thema erschiene.
|
|
- **Navigation über die History-API**, keine Router-Bibliothek. Zwei Ebenen —
|
|
Seite und optional ein Objekt darauf — reichen für diese Konsole.
|
|
- **`useMutation` für schreibende Aufrufe:** Doppelklickschutz, Vorgangsnummer
|
|
bis in die Meldung, kein `setState` nach dem Aushängen.
|
|
- **`Idempotency-Key`** an allen anlegenden und zerstörenden Aufrufen. Ohne ihn
|
|
erzeugt ein Doppelklick zwei Aufträge — und bei einer Wiederherstellung zwei
|
|
gleichzeitige Läufe in dasselbe Ziel.
|
|
- **Die Servermeldung hat Vorrang** vor der allgemeinen Erklärung zum
|
|
Fehlercode. Sie kennt den Einzelfall, und diese Genauigkeit ist mehr wert.
|
|
- **Berechtigungen im Menü sind Anzeige, keine Sicherung.** Sie verhindern
|
|
Sackgassen; geprüft wird auf dem Server.
|
|
- **Jede Fehleranzeige nennt `request_id`**, kopierbar. Ohne sie bleibt „es hat
|
|
nicht funktioniert".
|
|
|
|
### Betriebsfolge
|
|
|
|
Das Bundle braucht einen SPA-Fallback (`try_files $uri /index.html`), sonst
|
|
ergibt ein Neuladen auf `/recovery-points` einen 404. `setup.sh` richtet das mit
|
|
ein.
|
|
|
|
## Nachgewiesen
|
|
|
|
Gegen Debian 12 mit echtem PostgreSQL und nginx, über genau die Aufrufe, die die
|
|
Konsole macht:
|
|
|
|
- Repository übernommen, Durchsetzungsstufe **gemessen** (`advisory` — auf
|
|
overlayfs richtig)
|
|
- Auftrag angelegt, Lauf `202`, zweiter Anstoß `409`
|
|
- Sicherung erfolgreich: 2 Objekte, 3.000.006 Byte, 0 übergangen
|
|
- Blockprüfung `clean`, 5 Blöcke
|
|
- Vorabprüfung: „wiederherstellbar, 2 Dateien, 2,9 MiB"
|
|
- Wiederherstellung nach `/etc` abgewiesen
|
|
- Alle 18 Seiten liefern über HTTPS `200`; das Design-System steckt samt
|
|
Dark-Mode-Regeln im ausgelieferten CSS
|
|
|
|
76 Tests, `tsc` sauber, `eslint` ohne Warnung. Bundle 466 KB (136 KB gzip), CSS
|
|
30 KB (6 KB gzip).
|
|
|
|
## Bekannte Grenzen
|
|
|
|
- **Sechs Detail-Endpunkte** haben keine eigene Ansicht; ihre Daten stehen in den
|
|
Listen.
|
|
- **Die Suche im Ereignisprotokoll filtert im Browser** über die letzten 100
|
|
Einträge. Bei größeren Beständen gehört sie auf den Server.
|
|
- **Kein Live-Fortschritt.** `/api/v1/events/stream` steht in `SYNCOVA_API.md`,
|
|
ist aber **auch serverseitig nicht umgesetzt** — es fehlt nicht nur die
|
|
Anbindung. Laufende Sicherungen und Wiederherstellungen aktualisieren sich
|
|
beim Neuladen, nicht von selbst.
|
|
- **Kein Simple Mode.** Der Plan trennt Simple und Advanced Mode; umgesetzt ist
|
|
eine Ansicht.
|
|
- **Proxmox ist nicht auf echter Hardware freigegeben.** Die Seite sagt das
|
|
ausdrücklich.
|