From c673faa40d42152df0b1f3ee2224f9fd909e1766 Mon Sep 17 00:00:00 2001 From: Schalli Date: Thu, 2 Jul 2026 08:23:17 +0200 Subject: [PATCH] wip: phase-09 paused after UAT blocker (docker rebuild needed) --- .planning/HANDOFF.json | 44 ++++++------ .../09-cert-manager-module/.continue-here.md | 70 +++++++++---------- .../phases/09-cert-manager-module/09-UAT.md | 67 ++++++++++++++++++ 3 files changed, 122 insertions(+), 59 deletions(-) create mode 100644 .planning/phases/09-cert-manager-module/09-UAT.md diff --git a/.planning/HANDOFF.json b/.planning/HANDOFF.json index f650d6b..6eb888b 100644 --- a/.planning/HANDOFF.json +++ b/.planning/HANDOFF.json @@ -1,6 +1,6 @@ { "version": "1.0", - "timestamp": "2026-07-01T13:42:33.474Z", + "timestamp": "2026-07-02T06:21:28.260Z", "phase": "09", "phase_name": "cert-manager-module", "phase_dir": ".planning/phases/09-cert-manager-module", @@ -9,37 +9,37 @@ "total_tasks": null, "status": "paused", "completed_tasks": [ - {"id": 1, "name": "Dashboard grid: widget-fix noCompactor deployed", "status": "done", "commit": "dashboard fix"}, - {"id": 2, "name": "Phase 9 added to ROADMAP.md", "status": "done", "commit": "a32f5f9"}, - {"id": 3, "name": "09-CONTEXT.md written with all decisions", "status": "done", "commit": "a32f5f9"} + {"id": 1, "name": "Phase 09 alle 6 Pläne ausgeführt (Waves 1–5)", "status": "done", "commit": "daff82e"}, + {"id": 2, "name": "09-UAT.md erstellt, Playwright-Check durchgeführt", "status": "done", "commit": "in_memory"} ], "remaining_tasks": [ - {"id": 4, "name": "Run /gsd-ui-phase 9 to generate UI-SPEC.md", "status": "not_started"}, - {"id": 5, "name": "Run /gsd-plan-phase 9 after UI-SPEC exists", "status": "not_started"}, - {"id": 6, "name": "Run /gsd-execute-phase 9", "status": "not_started"} + {"id": 3, "name": "API-Container neu bauen: docker compose build api && docker compose up -d api", "status": "not_started"}, + {"id": 4, "name": "Prüfen: 'Cert-Manager module seeded in registry' in docker logs", "status": "not_started"}, + {"id": 5, "name": "Cert-Manager im Marketplace aktivieren (Tenant: Default)", "status": "not_started"}, + {"id": 6, "name": "UAT fortsetzen: /gsd-verify-work 9", "status": "not_started"} ], "blockers": [ { - "description": "UI-SPEC.md missing — plan-phase UI safety gate blocks planning", - "type": "process", - "workaround": "Run /gsd-ui-phase 9 first, OR /gsd-plan-phase 9 --skip-ui" + "description": "Docker API-Container läuft alten Build — CertManagerModule nicht deployed. Keine cert-manager Routes, kein Seed. Marketplace zeigt nur dkv-fleet + domaincheck.", + "type": "human_action", + "workaround": "docker compose build api && docker compose up -d api" } ], "async_jobs": [], - "human_actions_pending": [], + "human_actions_pending": [ + { + "action": "docker compose build api && docker compose up -d api", + "context": "Phase-09-Code (CertManagerModule) nicht im laufenden Container. Rebuild erforderlich vor UAT.", + "blocking": true + } + ], "decisions": [ - {"decision": "Server-side processing via NestJS API", "rationale": "User specified", "phase": "09"}, - {"decision": "Ephemeral — no DB, no file storage", "rationale": "User specified", "phase": "09"}, - {"decision": "node-forge library for cert operations", "rationale": "Pure JS, handles PEM/DER/PFX/P7B, Docker-friendly", "phase": "09"}, - {"decision": "Operations: inspect, split (chain→individual), merge (certs→chain or PFX), convert between formats", "rationale": "User clarified 'teilen' = split not share", "phase": "09"}, - {"decision": "Password support for PFX/PKCS12 read+write", "rationale": "User requirement", "phase": "09"}, - {"decision": "Tab UI: Analysieren / Aufteilen / Zusammenführen / Konvertieren", "rationale": "Discussed in context", "phase": "09"}, - {"decision": "Module slug: cert-manager, category: security-tools", "rationale": "Context decision", "phase": "09"} + {"decision": "forge.pkcs12.toPkcs12Asn1(null, certs, password) funktioniert in node-forge 1.4.0 — null-key PFX liefert cert-only PKCS12", "rationale": "Open Question 1 resolved", "phase": "09"}, + {"decision": "DER-Encoding: bytesToHex → Buffer.from(hex,'hex') → base64", "rationale": "Pitfall 1 — nie utf-8 roundtrip für Binary", "phase": "09"}, + {"decision": "expect.extend(matchers) explizit in web vitest setup.ts", "rationale": "Vitest 4.x Bug — jest-dom extends nicht automatisch", "phase": "09"} ], "uncommitted_files": [ ".mcp.json", - ".planning/REQUIREMENTS.md", - ".planning/STATE.md", "apps/api/src/auth/auth.service.ts", "apps/api/src/user/user.controller.ts", "apps/web/src/components/dashboard/dashboard-grid.tsx", @@ -49,6 +49,6 @@ "apps/web/src/lib/auth-actions.ts", "apps/web/src/lib/stores/dashboard-store.ts" ], - "next_action": "Run /gsd-ui-phase 9 to generate UI-SPEC.md, then /gsd-plan-phase 9", - "context_notes": "Phase 9 (Cert Manager) fully discussed and context captured. Dashboard widget noCompactor fix deployed. plan-phase blocked by UI-SPEC gate." + "next_action": "docker compose build api && docker compose up -d api — dann /gsd-verify-work 9", + "context_notes": "Phase 09 vollständig implementiert (6/6 Pläne, alle Tests grün: 27 API + 19 Web). UAT gestartet aber geblockt durch alten Docker-Build. Uncommitted files aus früheren Sessions — NICHT Phase-09-spezifisch, nicht committen." } diff --git a/.planning/phases/09-cert-manager-module/.continue-here.md b/.planning/phases/09-cert-manager-module/.continue-here.md index f23e6ca..2df1d0c 100644 --- a/.planning/phases/09-cert-manager-module/.continue-here.md +++ b/.planning/phases/09-cert-manager-module/.continue-here.md @@ -3,71 +3,67 @@ context: phase phase: 09-cert-manager-module task: null total_tasks: null -status: in_progress -last_updated: 2026-07-01T21:27:15.045Z +status: paused +last_updated: 2026-07-02T06:21:28.260Z --- # BLOCKING CONSTRAINTS — Read Before Anything Else -_Keine blocking constraints identifiziert._ +_Keine blocking constraints aus der Implementierung._ -Phase 9 (cert-manager-module) Execution läuft. Wave 1 abgeschlossen (09-01 + 09-02 committed). Wave 2–5 noch ausstehend (09-03 bis 09-06). - -Letzter Commit: `76d1a31` — "docs(phase-09): update tracking after wave 1" +Phase 09 vollständig implementiert (6/6 Pläne, 27 API + 19 Web-Tests grün). +UAT gestartet (09-UAT.md) aber geblockt: +Docker API-Container läuft alten Build — CertManagerModule nicht deployed. +Keine cert-manager Routes, kein Seed. Marketplace zeigt nur 2 Module. -- Phase 9 geplant: 6 Pläne in 5 Waves (commit 812eb06) -- Wave 1 ausgeführt und gemerged: - - **09-01** (API Foundation): node-forge 1.4.0 + Vitest installiert, NestJS CertManagerModule scaffolded (Module/Controller/Service/Seed/DTOs), in app.module.ts registriert, 11 Tests grün - - **09-02** (Web Shell): Next.js Page mit 4 Tabs, DropZone, PasswordField, actions.ts (downloadBase64), i18n de/en, 7 Render-Tests grün -- Merge-Konflikte in Wave 1 manuell gelöst: - - `app.module.ts`: CertManagerModule + FavoritesModule beide behalten - - `de.json` / `en.json`: JSON-Merge via python (strukturell korrekt) -- STATE.md + ROADMAP.md aktualisiert (2/6 Pläne complete) +- Wave 1 (09-01+02): API Foundation + Web Shell 4-Tabs +- Wave 2 (09-03): parseCert PEM/DER/PFX/P7B + InspectTab (TDD RED→GREEN) +- Wave 3 (09-04): splitCerts fullchain+P7B + SplitTab +- Wave 4 (09-05): convertCert PEM↔DER↔P7B + ConvertTab +- Wave 5 (09-06): mergeCerts PEM-Kette + Passwort-PFX + MergeTab +- 09-UAT.md: 8 Tests definiert, status: partial -- **Wave 2**: Plan 09-03 — Inspect-Endpoint + InspectTab (CERT-01, CERT-05 read) — depends_on: [09-01, 09-02] -- **Wave 3**: Plan 09-04 — Split-Endpoint + SplitTab (CERT-02) — depends_on: [09-03] -- **Wave 4**: Plan 09-05 — Convert-Endpoint + ConvertTab PEM/DER/P7B (CERT-04) — depends_on: [09-04] -- **Wave 5**: Plan 09-06 — Merge + PFX-create + MergeTab + PFX-Convert (CERT-03, CERT-04, CERT-05) — depends_on: [09-05] -- Post-execution: Verifier spawnen, VERIFICATION.md, Phase complete +**Vor Resume (manuell):** +```bash +docker compose build api && docker compose up -d api +docker logs tessera-ctl-api-1 | grep "Cert-Manager" +``` +Dann: Marketplace → cert-manager aktivieren (Tenant: Default) +Dann: `/gsd-verify-work 9` -- **Module-Pfad**: `apps/api/src/cert-manager/` (nicht `apps/api/src/modules/cert-manager/` — kein modules/ Verzeichnis existiert) -- **Test-Runner**: Vitest in @tessera/api installiert (war noch nicht vorhanden) -- **Encoding**: `toForgeBuffer()` helper nutzt `toString('binary')` — nie 'utf-8' -- **Binary-Download**: `downloadBase64()` in actions.ts — POST → base64-JSON → Blob-URL -- **Merge-Konflikte**: Beide Worktrees branchen vom gleichen Base (88db54f) — app.module.ts und i18n-Dateien hatten parallele Änderungen +- forge.pkcs12.toPkcs12Asn1(null, certs, password) funktioniert — null-key PFX OK (Open Question 1 resolved) +- DER: bytesToHex → Buffer.from(hex,'hex') → base64 (Pitfall 1 — nie utf-8) +- expect.extend(matchers) explizit in web vitest setup.ts (Vitest 4.x Bug) -- Keine aktiven Blocker. -- **Hinweis**: Nach Wave 1 (09-01) muss ein Admin `cert-manager` im Marketplace aktivieren, da `isSystem:true` NICHT auto-aktiviert. ModuleGuard gibt 403 zurück bis zur manuellen Aktivierung. + +- Docker-Build veraltet: `docker compose build api && docker compose up -d api` nötig +- Uncommitted files aus alten Sessions (auth, dashboard etc.) — NICHT committen -## Required Reading (in order) -1. `.planning/phases/09-cert-manager-module/09-03-PLAN.md` — nächster Plan (Inspect-Endpoint) -2. `.planning/phases/09-cert-manager-module/09-RESEARCH.md` — Pitfalls (Encoding, Binary-Download) -3. `.planning/phases/09-cert-manager-module/09-01-SUMMARY.md` — was in Wave 1 gebaut wurde +## Required Reading +1. `.planning/phases/09-cert-manager-module/09-UAT.md` — 8 Tests, alle pending ## Infrastructure State -- Docker: alle Container laufen (web, api, db) -- git: branch `main`, HEAD `76d1a31` -- Uncommitted files (aus früheren Sessions, NICHT Phase 9): `.mcp.json`, `auth.service.ts`, `user.controller.ts`, `dashboard-grid.tsx`, `note-widget.tsx`, `widget-wrapper.tsx`, `account-settings-form.tsx`, `auth-actions.ts`, `dashboard-store.ts` — diese IGNORIEREN, nicht committen +- Docker: web (3000) OK; api (3001) läuft mit ALTEM Build (kein CertManagerModule) +- git: main, HEAD daff82e +- Uncommitted (ignorieren): .mcp.json, auth.service.ts, user.controller.ts, dashboard-*.tsx, widget-wrapper.tsx, account-settings-form.tsx, auth-actions.ts, dashboard-store.ts -Execution läuft Wave-by-Wave sequential (Wave 2–5 haben jeweils nur 1 Plan). Jeder Wave: einen gsd-executor spawnen, auf Completion warten, Worktree mergen, nächste Wave starten. Waves 2–5 sind sequential (depends_on chain), kein Parallel-Exec mehr. +Phase 09 code-seitig fertig. Einziger offener Punkt: Docker rebuild + UAT. -Start with: `/gsd-execute-phase 9 --wave 2` - -Wave 2 = Plan 09-03 (1 Agent, kein Parallel-Merge nötig, sequential auf main). +docker compose build api && docker compose up -d api — dann /gsd-verify-work 9 diff --git a/.planning/phases/09-cert-manager-module/09-UAT.md b/.planning/phases/09-cert-manager-module/09-UAT.md new file mode 100644 index 0000000..5dec638 --- /dev/null +++ b/.planning/phases/09-cert-manager-module/09-UAT.md @@ -0,0 +1,67 @@ +--- +status: partial +phase: 09-cert-manager-module +source: + - 09-03-SUMMARY.md + - 09-04-SUMMARY.md + - 09-05-SUMMARY.md + - 09-06-SUMMARY.md +started: 2026-07-02T07:59:00Z +updated: 2026-07-02T08:20:00Z +--- + +## Current Test + +number: 1 +name: Modul-Navigation & Tab-Struktur +expected: | + Im Portal unter Marketplace ist "Zertifikat-Manager" als Modul sichtbar. + Nach Aktivierung erscheint ein Eintrag in der Sidebar. + Klick darauf öffnet die Seite mit 4 Tabs: Analysieren / Aufteilen / Zusammenführen / Konvertieren. +awaiting: user response + +## Tests + +### 1. Modul-Navigation & Tab-Struktur +expected: Zertifikat-Manager-Modul im Marketplace aktivierbar; nach Aktivierung Sidebar-Eintrag; Seite zeigt 4 Tabs (Analysieren / Aufteilen / Zusammenführen / Konvertieren) +result: [pending] + +### 2. Analysieren — PEM-Zertifikat inspizieren +expected: PEM-Datei hochladen (oder Text einfügen) → Klick "Analysieren" → Ergebnis-Grid zeigt: Subject CN, Issuer, Gültigkeit (Von/Bis, abgelaufen?), SANs, Key-Typ/Bits, Serial, SHA-256-Fingerprint +result: [pending] + +### 3. Analysieren — falsches PFX-Passwort → 400-Fehler +expected: PFX-Datei hochladen + falsches Passwort → Fehlermeldung "Falsches Passwort" (kein 500-Crash, kein Stack-Trace) +result: [pending] + +### 4. Aufteilen — Fullchain-PEM aufteilen +expected: fullchain.pem (2+ Certs) hochladen → Klick "Aufteilen" → Liste mit je einem Download-Button pro Zertifikat; Klick lädt einzelne .pem-Datei herunter +result: [pending] + +### 5. Konvertieren — PEM → DER +expected: PEM-Datei hochladen, Zielformat "DER" wählen → Klick "Konvertieren" → Browser lädt .der-Datei herunter +result: [pending] + +### 6. Konvertieren — PFX-Option + Passwort-Feld +expected: Zielformat "PFX" wählen → Passwort-Feld wird sichtbar; Zertifikat + Passwort → .pfx-Download möglich +result: [pending] + +### 7. Zusammenführen — PEM-Kette +expected: 2 PEM-Dateien auswählen → "Zusammenführen"-Button ist erst ab 2 Dateien aktiv → Klick → chain.pem-Download (enthält 2 BEGIN CERTIFICATE Blöcke) +result: [pending] + +### 8. Zusammenführen — Passwort-PFX +expected: 2 Certs auswählen, Ausgabe "PFX", Passwort eingeben → bundle.pfx herunterladen; Datei lässt sich mit dem korrekten Passwort öffnen +result: [pending] + +## Summary + +total: 8 +passed: 0 +issues: 0 +pending: 8 +skipped: 0 + +## Gaps + +[none yet]