Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
16 KiB
phase, plan, subsystem, tags, dependency-graph, tech-stack, key-files, decisions, metrics, actuals, plan_head_before, status
| phase | plan | subsystem | tags | dependency-graph | tech-stack | key-files | decisions | metrics | actuals | plan_head_before | status | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| quick-260923-dhh | 01 | infrastructure |
|
|
|
|
|
|
|
ec9c779 |
complete |
Quick 260923-dhh: Proxmox-Modul (PVE/PBS/PMG) — nur beobachten Summary
Vollstaendiges Proxmox-Modul (Datenbank, Dienst, API, Hintergrundabfrage je Mandant, Einstellungsseite, Modulseite, Dokumentation) — PVE/PBS/PMG werden per API-Token (PVE/PBS) oder Ticket-Anmeldung (alle drei) nur gelesen, kein Weg im Modul veraendert je etwas bei Proxmox.
Gemessene Torzahlen
| Tor | Ausgangswert (23.09., vor Beginn) | Endstand (nach Aufgabe 7) |
|---|---|---|
pnpm --filter @tessera/api test |
1240 Tests, 77 Dateien | 1311 Tests, 82 Dateien |
pnpm --filter @tessera/web test |
693 Tests, 82 Dateien | 708 Tests, 84 Dateien |
rls-coverage.spec.ts / rls-access-inventory.spec.ts |
5 / 30 | 5 / 30 (unveraendert gruen) |
proxmox-nur-lesen.spec.ts |
(existierte nicht) | 2 Tests, gruen |
pnpm type-check |
4/4 | 4/4 |
pnpm lint |
5/5 | 5/5 |
Biome-Warnungen in apps/web |
53 | 53 (exakt unveraendert) |
Performance
- Duration: ~5h (inklusive einer Unterbrechung durch Nutzungslimit, an derselben Stelle fortgesetzt)
- Tasks: 7/7
- Files modified: 34 (18 neu, 16 geaendert)
Accomplishments
ProxmoxServer/ProxmoxServerStatusmit RLS (tenant_isolation_policyauf beiden,system_read_policyzusaetzlich aufProxmoxServerfuer den Planer-Startpfad)proxmox-auth.tsals einzige Stelle, die Kopfzeilen/Cookies baut: Token-Schema je Produkt (PVE=, PBS:, PMG lehnt ab) und Ticket-Anmeldung (die einzige nicht-lesende Anfrage des Moduls)proxmox-client.service.ts/proxmox-normalize.ts: nachsichtige Fehler-/Feldbehandlung, sieben stabile Fehlerschluessel, nie ein Wurf bei unerwarteter Formproxmox-scheduler.service.ts: ein Cron-Auftrag je Mandant (proxmox-poll:<tenantId>),onApplicationBootstrap, Abfrageintervall = kleinstespollIntervalMinder aktiven Server- Einstellungsseite (anlegen/bearbeiten/loeschen/testen) und Modulseite (Serverliste mit
produktabhaengiger Auslastung,
nullimmer als „unbekannt") - Anwenderhandbuch- und Entwicklungsanleitung-Abschnitte, Zugriffsklassifikation vollstaendig nachgezogen
Task Commits
Jede Aufgabe wurde einzeln committet:
- Aufgabe 1: PVE per Token, Ende-zu-Ende —
3a1bfd9(feat) - Aufgabe 2: Benutzer/Passwort, Fehlerklassen, Nur-Lesen-Riegel —
4f8a368(test) - Aufgabe 3: PBS und PMG auswerten —
998aba9(feat) - Aufgabe 4: Hintergrundabfrage je Mandant, Verbindungstest —
fccaf8d(feat) - Aufgabe 5: Einstellungsseite (anlegen, bearbeiten, loeschen, testen) —
723cf68(feat) - Aufgabe 6: Modulseite mit Auslastung —
06fcdc0(feat) - Aufgabe 7: Dokumentation und Nachmessung aller Tore —
3091b04(docs)
Kein separater Metadaten-Commit — STATE.md/SUMMARY.md werden laut Auftrag nicht committet.
Files Created/Modified
Siehe key-files im Frontmatter — vollstaendige Liste, hier die wichtigsten:
apps/api/prisma/migrations/20260923140000_proxmox_server/migration.sql— RLS-Migration, von Hand geschrieben (Vorbild20260923120000_dashboard_tabs)apps/api/src/proxmox/proxmox-client.service.ts—proxmoxGet,classifyFailure,parseJsonLenientapps/api/src/proxmox/proxmox-auth.ts—buildTokenAuthHeader,loginTicket,buildTicketCookieHeaderapps/api/src/proxmox/proxmox-normalize.ts—normalizePve/normalizePbs/normalizePmgplusreadNumber/readText/readBool/readListapps/api/src/proxmox/proxmox.service.ts— CRUD, Poll-Logik, Zehn-Sekunden-Sperre,loadActiveServersForScheduler(einzigerforSystem()-Aufruf)apps/api/src/proxmox/proxmox-scheduler.service.ts— Planer je Mandantapps/web/src/app/(portal)/modules/proxmox/components/ServerCard.tsx— einzige Stelle, die einen Messwert in Text verwandelt
Decisions Made
Siehe decisions im Frontmatter. Zusaetzlich zwei technische Entwurfsentscheidungen, die der
Plan nicht bis auf diese Ebene vorschrieb:
- Signatur
proxmoxGet(target, path):targettraegt fertige Kopfzeilen ({ baseUrl, tlsRejectUnauthorized, headers }), gebaut ausschliesslich vonproxmox-auth.ts— der Klient selbst kennt keine Anmeldeform, nur HTTP-Transport und Fehlerklassifikation. proxmox-nur-lesen.spec.tserkennt Aufrufformen ueber Klammertiefen-Bilanzierung (nicht per einfachem Zeilen-Regex), weil Proxmox-Pfade undproxmoxGet(/getWithRetry(- Aufrufe im Quelltext ueber mehrere Zeilen verteilt sind.
Deviations from Plan
Auto-fixed Issues
1. [Rule 3 - Blocking] docs/anwenderhandbuch.md existiert nicht im Repo
- Found during: Aufgabe 7
- Issue: Das Plan-Frontmatter nennt
docs/anwenderhandbuch.mdals zu aendernde Datei; diese Datei gibt es im Repository nicht. Der tatsaechliche Anwenderhandbuch-Dateiname istdocs/anleitung-anwender.md(bestaetigt pergit log --diff-filter=A). - Fix: Den Proxmox-Abschnitt in
docs/anleitung-anwender.mdeingefuegt statt eine neue, falsch benannte Datei anzulegen. - Files modified:
docs/anleitung-anwender.md - Verification: Datei existiert, Abschnitt „Proxmox" lesbar, Modulzahl „vier" auf „fuenf" korrigiert.
- Committed in:
3091b04(Aufgabe-7-Commit)
2. [Rule 3 - Blocking] Umlaut-Regressionswaechter (umlaut-guard.spec.ts) schlug fehl
- Found during: Aufgabe 5 und erneut Aufgabe 6
- Issue: Neue, bereits korrekte deutsche Woerter mit „ss" (
bewusst,gemessene,Messung,Prozessorlast) in den neuende.json-Texten wurden vom Waechter als moegliche ae/oe/ue/ss-Ersatzschreibung markiert, weil sie noch nicht auf der Positivliste standen. - Fix: Alle vier Woerter zu
UMLAUT_ALLOWLISTinapps/web/src/messages/umlaut-dictionary.tshinzugefuegt (kein Ersatzschreibung — bereits korrektes Deutsch). - Files modified:
apps/web/src/messages/umlaut-dictionary.ts - Verification:
umlaut-guard.spec.tsgruen,pnpm --filter @tessera/web testvollstaendig gruen. - Committed in:
723cf68(Aufgabe 5),06fcdc0(Aufgabe 6)
3. [Rule 3 - Blocking] proxmox-nur-lesen.spec.ts erkannte den getWithRetry-Umschlag nicht
- Found during: Aufgabe 3 (beim Einbau der PBS-Mehrfachabfrage)
- Issue: Der urspruengliche Riegel erkannte Proxmox-Pfade nur innerhalb direkter
proxmoxGet(...)-Aufrufe; nach der Extraktion der Ticket-Erneuerung in einen privaten UmschlaggetWithRetry()(Aufgabe 2/3) lagen alle Pfade jetzt in dessen Argumenten, nicht mehr direkt inproxmoxGet(...). - Fix: Die erlaubte Aufrufform-Liste um
getWithRetryerweitert (dokumentierte Ausnahme, selbst durch dieselbe erste Aussage des Riegels abgesichert:getWithRetryruft ausschliesslichproxmoxGet). - Files modified:
apps/api/src/proxmox/proxmox-nur-lesen.spec.ts - Verification: Beide Aussagen des Riegels gruen, bewusster Test bestaetigt weiterhin genau
eine
undiciFetch-Methodenstelle. - Committed in:
998aba9(Aufgabe 3)
Total deviations: 3 auto-fixed (alle Rule 3 — blockierende Fehler beim Ausfuehren, keine davon eine architektonische Entscheidung) Impact on plan: Keine Abweichung vom fachlichen Umfang des Plans; alle drei Korrekturen waren notwendig, damit die vom Plan selbst verlangten Tore (Aufgabe 7: alle Testsuiten gruen) ueberhaupt erreichbar waren.
Issues Encountered
Die Ausfuehrung wurde durch ein Nutzungslimit mitten in Aufgabe 4 unterbrochen (nach dem
Schreiben von proxmox-scheduler.service.ts und dem Wiring in proxmox.controller.ts/
proxmox.module.ts, vor dem Schreiben der zugehoerigen Testdatei). Nach Fortsetzung wurde der
Stand anhand von git status/git log verifiziert und exakt an der protokollierten Stelle
weitergearbeitet — keine Wiederholung bereits committeter Aufgaben.
User Setup Required
Es gibt in dieser Umgebung keinen echten PVE-/PBS-/PMG-Server. Alle Tests laufen gegen
erfundene Antworten in der von der Recherche dokumentierten Form (vi.mock('undici', …)).
Folgende Annahmen der Recherche sind vor dem ersten echten Test explizit zu bestaetigen bzw.
bei Abweichung an genau einer Stelle nachzuziehen:
- Annahme A2 — Ticket-Cookie-Namen fuer PBS/PMG:
PBSAuthCookie/PMGAuthCookiesind aus dem PVE-Muster ABGELEITET, nicht aus Primaerdoku bestaetigt. Nachzuziehende Stelle:TICKET_COOKIE_NAMEinapps/api/src/proxmox/proxmox-auth.ts. - Annahme A3 — PBS-Belegungs-/Snapshot-Feldnamen:
store/total/used/availundbackup-time/verificationsind aus Forenbelegen abgeleitet. Nachzuziehende Stelle:PBS_USAGE_FIELDS/PBS_SNAPSHOT_FIELDSinapps/api/src/proxmox/proxmox-normalize.ts(mehrere plausible Namen je Feld moeglich, der Leser nimmt den ersten vorhandenen). - Annahme A5 — PMG-Statistikfelder:
count_in/count_out/spamcount_in/spamcount_out/viruscount_in/viruscount_outsind auspmgsh-Community-Belegen abgeleitet. Nachzuziehende Stelle:PMG_STATS_FIELDSinapps/api/src/proxmox/proxmox-normalize.ts. - NUR-LESE-Rollen am Proxmox-Server selbst anlegen (aus dem Plan-Frontmatter
user_setup, unveraendert offen): PVEPVEAuditor, PBSAudit/DatastoreAudit, PMGAuditor— je Produkt fuer den Zugang, den Tessera nutzt.
Weicht die Wirklichkeit an einer dieser Stellen ab, zeigt die Modulseite dank der
nachsichtigen Leser „unbekannt" statt eines Absturzes, und die gekuerzte Rohantwort bleibt im
Zwischenlager erhalten (rawSample, bis 20 000 Zeichen) — der Nutzer sieht darin, wie das
Feld tatsaechlich heisst.
Known Stubs
Keine — jede in <must_haves> genannte Wahrheit ist durch mindestens einen automatisierten
Test belegt (siehe Aufgaben 1–6). Die drei oben genannten Annahmen sind keine Stubs, sondern
dokumentierte, noch nicht am echten Server bestaetigte Feldnamen — die Auswertung fuer sie ist
vollstaendig gebaut, nur ihre exakten externen Namen sind ungeprueft.
Next Phase Readiness
- Das Modul ist vollstaendig gebaut und alle automatisierten Tore sind gruen; die
Dashboard-Kachel (D-11) ist bewusst nicht Teil dieses Auftrags und folgt separat
(
WIDGET_TYPES/WIDGET_MODULE_SLUGS/registerWidget, siehedocs/anleitung-entwicklung.md, Abschnitt „Eine Kachel zum Modul"). - Blocker fuer den naechsten Schritt: keiner auf Code-Ebene. Der Nutzer muss das Modul gegen mindestens einen echten PVE-/PBS-/PMG-Server pruefen (siehe „User Setup Required"), bevor die drei Annahmen als bestaetigt gelten koennen.
- Container wurden in dieser Ausfuehrung bewusst NICHT neu gebaut/neu gestartet und es wurde keine Browser-Pruefung durchgefuehrt (Auftragsvorgabe) — das uebernimmt der Nutzer bzw. eine spaetere Sitzung.
Phase: quick-260923-dhh Completed: 2026-09-23
Self-Check: PASSED
All 24 files listed under key-files (created + modified) verified present on disk. All 7
task commits (3a1bfd9, 4f8a368, 998aba9, fccaf8d, 723cf68, 06fcdc0, 3091b04)
verified present in git log.
Nachbesserungen aus dem Rundgang
Drei Befunde aus dem menschlichen Browser-Rundgang zu diesem Modul wurden behoben — Details,
Tasks und Tests in einem eigenen Quick-Task:
260923-ku6-drei-nachbesserungen-aus-dem-browser-run
(Commits 710034c, f1bb7f7).
Befund 1 (wichtig): „Verbindung testen" pruefte den gespeicherten Stand, nicht das
Formular. Eine im Formular abgeschaltete Zertifikatspruefung oder ein neu eingetipptes
Token-/Passwort-Geheimnis wurden vom Test ignoriert und griffen erst nach „Speichern" — eine
Falle fuer den naheliegenden Ablauf (eintippen, testen, dann erst speichern). Behoben durch ein
neues TestProxmoxServerDto samt Merge-Baustein resolveEffectiveTestServer in
ProxmoxService: normale Formularfelder gewinnen immer (auch wenn absichtlich geleert),
Geheimnisfelder behalten die bestehende „leer gelassen -> gespeicherten Wert weiterverwenden"-
Regel aus updateServer, weil ServerForm sie beim Laden nie aus der Datenbank vorbefuellt.
Neue Route POST servers/test (ohne :id) deckt denselben Test waehrend der Neuanlage ab, wo
es noch keinen gespeicherten Server gibt; der Testen-Knopf steht jetzt immer zur Verfuegung,
nicht mehr erst nach dem ersten Speichern.
Befund 2 (wichtig): falsche Meldung fuer „noch nie abgefragt". Ein frisch angelegter
Server zeigte „Letzte Abfrage: unbekannt" UND faelschlich „Ein unerwarteter Fehler ist
aufgetreten" — die leere Zwischenlagerzeile aus createServer hat reachable: false und
errorKind: null, was bisher blind in die Fehleruebersetzung unbekannt lief. Behoben durch
einen eigenen, ruhigen Zustand fuer status.lastPolledAt === null, der auf „Jetzt
aktualisieren" verweist; die bestehenden Fehlermeldungen (inkl. unbekannt fuer echte
unbekannte Fehler) bleiben fuer bereits abgefragte, aber nicht erreichbare Server unveraendert.
Befund 3 (kosmetisch): die Adresse wurde in Grossbuchstaben angezeigt. Die Klasse
uppercase sass auf der ganzen Statuszeile statt nur auf dem Produktkuerzel und faerbte
dadurch auch die Adresse gross. Jetzt nur noch auf dem Produktkuerzel (<span>).
Zahlen nach der Nachbesserung: api 1311 → 1316 Tests, web 708 → 712 Tests, type-check
4/4, lint 5/5, Biome apps/web weiterhin exakt 53 Warnungen. Container wurden nicht neu
gebaut, keine Browser-Pruefung in diesem Lauf (macht der Orchestrator danach).