--- phase: quick plan: 260923-ku6 subsystem: ui tags: [nestjs, next.js, proxmox, class-validator, vitest, next-intl, biome] requires: - phase: 260923-dhh provides: Proxmox-Modul (PVE/PBS/PMG anbinden, Verbindungstest, Modulseite) provides: - Verbindungstest prueft Formularwerte statt gespeicherten Stand (neue Route POST servers/test, TestProxmoxServerDto, resolveEffectiveTestServer-Merge) - Ruhiger "noch nicht abgefragt"-Zustand auf der Modulseite statt Sammelfehlermeldung - uppercase-Klasse nur noch auf dem Produktkuerzel, nicht mehr auf der Adresse affects: [proxmox] actuals: tokens: 9700 tasks: 3 commits: 2 tech-stack: added: [] patterns: - "Formular-vs-gespeichert-Merge fuer Verbindungstests: normale Felder folgen dem Formular (auch geleert), Geheimnisfelder folgen der 'leer -> gespeicherten Wert behalten'-Regel, weil das Formular Geheimnisse beim Laden nie vorbefuellt" key-files: created: [] modified: - apps/api/src/proxmox/dto/proxmox-server.dto.ts - apps/api/src/proxmox/proxmox.controller.ts - apps/api/src/proxmox/proxmox.service.ts - apps/api/src/proxmox/proxmox.service.spec.ts - apps/web/src/lib/proxmox-api.ts - "apps/web/src/app/(portal)/modules/proxmox/settings/components/ServerForm.tsx" - "apps/web/src/app/(portal)/modules/proxmox/settings/components/ServerForm.test.tsx" - "apps/web/src/app/(portal)/modules/proxmox/components/ServerCard.tsx" - "apps/web/src/app/(portal)/modules/proxmox/components/ServerCard.test.tsx" - apps/web/src/messages/de.json - apps/web/src/messages/en.json key-decisions: - "Verbindungstest-Route POST servers/:id/test nimmt jetzt einen optionalen Body (TestProxmoxServerDto) entgegen; neue Route POST servers/test (ohne :id) deckt die Neuanlage ab, ueberschneidet sich nicht mit servers/:id/test (unterschiedliche Segmentzahl)" - "Geheimnisfelder behalten beim Test die 'leer -> gespeicherten Wert' Sonderregel, alle anderen Felder folgen strikt dem gesendeten Formularstand (auch wenn absichtlich geleert)" - "Befund 2+3 in einem Commit, weil beide Aenderungen in derselben Datei (ServerCard.tsx) liegen" requirements-completed: [] coverage: - id: D1 description: "Verbindungstest prueft Formularwerte (Zertifikatspruefung, neues Geheimnis) statt des gespeicherten Stands; leer gelassenes Geheimnisfeld nutzt weiterhin den gespeicherten Wert; Test funktioniert auch bei der Neuanlage ohne gespeicherten Server" verification: - kind: unit ref: "apps/api/src/proxmox/proxmox.service.spec.ts#Nachbesserung Befund 1: testConnection prueft die im Formular abgeschaltete Zertifikatspruefung..." status: pass - kind: unit ref: "apps/api/src/proxmox/proxmox.service.spec.ts#Nachbesserung Befund 1: ein im Formular NEU eingetipptes Token-Geheimnis wird getestet..." status: pass - kind: unit ref: "apps/api/src/proxmox/proxmox.service.spec.ts#Nachbesserung Befund 1: leer gelassenes Geheimnisfeld im Formular nutzt weiterhin das gespeicherte Token-Geheimnis" status: pass - kind: unit ref: "apps/api/src/proxmox/proxmox.service.spec.ts#Nachbesserung Befund 1: testDraftConnection testet einen noch nicht gespeicherten Server..." status: pass - kind: unit ref: "apps/web/src/app/(portal)/modules/proxmox/settings/components/ServerForm.test.tsx#Nachbesserung Befund 1: bei der Neuanlage ... steht der Testen-Knopf zur Verfuegung..." status: pass - kind: unit ref: "apps/web/src/app/(portal)/modules/proxmox/settings/components/ServerForm.test.tsx#Nachbesserung Befund 1: der Test prueft die im Formular abgeschaltete Zertifikatspruefung..." status: pass human_judgment: true rationale: "Browser-Pruefung des tatsaechlichen Verhaltens macht der Orchestrator danach (per Auftrag ausgeschlossen aus diesem Lauf)" - id: D2 description: "Frisch angelegter, noch nie abgefragter Server zeigt einen ruhigen Hinweis statt der Sammelfehlermeldung 'Ein unerwarteter Fehler ist aufgetreten'" verification: - kind: unit ref: "apps/web/src/app/(portal)/modules/proxmox/components/ServerCard.test.tsx#Nachbesserung Befund 2: ein frisch angelegter, noch nie abgefragter Server..." status: pass human_judgment: true rationale: "Browser-Pruefung des tatsaechlichen Verhaltens macht der Orchestrator danach (per Auftrag ausgeschlossen aus diesem Lauf)" - id: D3 description: "Adresse in der Modulseiten-Zeile nicht mehr grossgeschrieben, nur noch das Produktkuerzel" verification: - kind: unit ref: "apps/web/src/app/(portal)/modules/proxmox/components/ServerCard.test.tsx#Nachbesserung Befund 3: die Adresse bleibt unveraendert dargestellt..." status: pass human_judgment: false duration: 45min completed: 2026-09-23 status: complete --- # Quick Task 260923-ku6: Drei Nachbesserungen aus dem Browser-Rundgang (Proxmox-Modul) Summary **Verbindungstest folgt jetzt dem Formular statt dem gespeicherten Server, ein frisch angelegter Server zeigt einen ruhigen "noch nicht abgefragt"-Hinweis statt einer falschen Fehlermeldung, und die Adresse in der Modulseiten-Zeile ist nicht mehr grossgeschrieben.** ## Performance - **Duration:** ~45 min - **Tasks:** 3 - **Files modified:** 11 ## Accomplishments - **Befund 1:** `POST servers/:id/test` prueft jetzt den aktuellen Formularstand (Zertifikatspruefung, Token-/Passwort-Geheimnis, Adresse, Zugangsart) statt blind des gespeicherten Servers; neue Route `POST servers/test` deckt denselben Test waehrend der Neuanlage ab, wo es noch keinen gespeicherten Server gibt. Geheimnisfelder behalten die Sonderregel "leer gelassen -> gespeicherten Wert weiterverwenden", weil `ServerForm` sie beim Laden nie aus der Datenbank vorbefuellt. - **Befund 2:** Ein frisch angelegter, noch nie abgefragter Server (`status.lastPolledAt === null`) zeigt einen ruhigen Hinweistext, der auf "Jetzt aktualisieren" verweist, statt der Sammelmeldung "Ein unerwarteter Fehler ist aufgetreten". Echte Fehlermeldungen bleiben fuer bereits abgefragte, aber nicht erreichbare Server unveraendert. - **Befund 3:** Die `uppercase`-Klasse sitzt jetzt nur noch auf dem Produktkuerzel (``), nicht mehr auf der ganzen Statuszeile — die Adresse erscheint wieder wie eingegeben. ## Task Commits 1. **Task 1: Verbindungstest prueft Formularwerte statt gespeicherten Stand (Befund 1)** - `710034c` (fix) 2. **Task 2+3: Ruhiger "noch nicht abgefragt"-Zustand und Adresse ohne Grossschreibung (Befund 2+3)** - `f1bb7f7` (fix) _Beide Aufgaben von Befund 2 und 3 liegen in derselben Datei (`ServerCard.tsx`) und wurden deshalb in einem Commit zusammengefasst — Begruendung steht in der Commit-Nachricht._ ## Files Created/Modified - `apps/api/src/proxmox/dto/proxmox-server.dto.ts` - neues `TestProxmoxServerDto` - `apps/api/src/proxmox/proxmox.controller.ts` - `test` nimmt jetzt einen Body entgegen, neue Route `testDraft` (`POST servers/test`) - `apps/api/src/proxmox/proxmox.service.ts` - `resolveEffectiveTestServer`-Merge, `testConnection` mit `dto`-Parameter, neue `testDraftConnection` - `apps/api/src/proxmox/proxmox.service.spec.ts` - 5 neue Tests fuer Befund 1 - `apps/web/src/lib/proxmox-api.ts` - `testServer` nimmt jetzt ein Payload, neue `testDraftServer` - `apps/web/src/app/(portal)/modules/proxmox/settings/components/ServerForm.tsx` - Testen-Knopf immer sichtbar, sendet immer den Formularstand - `apps/web/src/app/(portal)/modules/proxmox/settings/components/ServerForm.test.tsx` - alte "kein Knopf vor dem Speichern"-Erwartung durch das neue, gewuenschte Verhalten ersetzt, 2 neue Tests - `apps/web/src/app/(portal)/modules/proxmox/components/ServerCard.tsx` - ruhiger "noch nicht abgefragt"-Zustand, `uppercase` nur auf dem Produktkuerzel - `apps/web/src/app/(portal)/modules/proxmox/components/ServerCard.test.tsx` - 2 neue Tests - `apps/web/src/messages/de.json`, `apps/web/src/messages/en.json` - neuer Schluessel `proxmox.card.notPolledYet` ## Decisions Made - Geheimnisfelder (`tokenSecret`/`password`) folgen beim Testen weiterhin der bestehenden "leer -> gespeicherten Wert behalten"-Regel aus `updateServer`, weil `ServerForm` sie beim Laden absichtlich nie vorbefuellt (kein Klartext-Leak). Alle anderen Felder (`tokenId`, `username`, `baseUrl`, `authMethod`, `productType`, `tlsRejectUnauthorized`) folgen strikt dem gesendeten Formularwert, auch wenn er absichtlich geleert wurde — diese Felder sind beim Laden immer vorbefuellt, ein leeres Feld ist dort also eine bewusste Nutzeraktion. - Neue Route `POST servers/test` statt eines Sonderwerts fuer `:id` (z. B. `new`), weil sie sich mit `servers/:id/test` nicht ueberschneidet (zwei vs. drei Segmente) und dadurch keine Routen-Reihenfolge-Abhaengigkeit entsteht. - `buildTestPayload()` in `ServerForm.tsx` sendet bewusst kein `name`-Feld, weil `TestProxmoxServerDto` `@IsNotEmpty()` auf `name` erbt und ein waehrend der Neuanlage noch leeres Namensfeld sonst jeden Testklick mit 400 blockiert hätte. ## Deviations from Plan None - plan executed exactly as written (PLAN.md `.planning/quick/260923-ku6-drei-nachbesserungen-aus-dem-browser-run/260923-ku6-PLAN.md`). ## Issues Encountered - Die Aenderung an `ServerCard.tsx` (`status && status.lastPolledAt && !status.reachable`) loeste eine neue Biome-Warnung (`lint/complexity/useOptionalChain`) aus, die die geforderte exakte Warnungszahl (53) auf 54 angehoben haette. Behoben durch Umformulierung zu `status?.lastPolledAt && !status.reachable` (TypeScript narrowt `status` fuer den Rest des Ausdrucks korrekt nach) — Warnungszahl danach wieder exakt 53. - Der bestehende Test "ohne gespeicherten Server (Neuanlage) gibt es keinen Verbindung-testen-Knopf" widersprach direkt der geforderten Korrektur aus Befund 1 (Testen soll bei der Neuanlage funktionieren) und wurde durch einen Test mit dem neuen, gewuenschten Verhalten ersetzt. ## User Setup Required None - keine externe Konfiguration noetig. ## Next Phase Readiness Alle drei Befunde behoben, alle Tore gruen (api 1316/1316, web 712/712, type-check 4/4, lint 5/5, Biome `apps/web` exakt 53 Warnungen). Browser-Pruefung der tatsaechlichen UI macht der Orchestrator im Anschluss, wie im Auftrag verlangt. --- *Phase: quick-260923-ku6* *Completed: 2026-09-23*