From f9a5ad2daac6da56472b8afbff5389ce6185345c Mon Sep 17 00:00:00 2001 From: Florian Wilde Date: Thu, 17 Sep 2026 21:02:44 +0200 Subject: [PATCH] feat(kunden): Kundenverwaltung, Hostzuweisung und Token-Verwaltung (#006) Kunden und Standorte pflegen, nicht zugeordnete Hosts in einem Schritt zuweisen, Enrollment- und Host-Tokens verwalten, Audit-Log. Dashboard, Kundenseiten und globale Suche laufen jetzt auf der Datenbank. 45 Tests. Co-Authored-By: Claude Opus 5 (1M context) --- CHANGELOG.md | 14 + DEVLOG.md | 16 +- docs/anleitung/bilder/dashboard.png | Bin 267729 -> 270353 bytes docs/anleitung/bilder/kunde-detail.png | Bin 225808 -> 240783 bytes docs/anleitung/bilder/kunde-neu.png | Bin 0 -> 79658 bytes docs/anleitung/bilder/kunden.png | Bin 0 -> 108347 bytes docs/anleitung/bilder/nicht-zugeordnet.png | Bin 109528 -> 108476 bytes docs/anleitung/bilder/tokens.png | Bin 0 -> 120842 bytes docs/issues/006-kunden-hostzuweisung.md | 31 ++- docs/issues/README.md | 6 +- package.json | 2 +- .../(dashboard)/einstellungen/tokens/page.tsx | 173 ++++++++++-- src/app/(dashboard)/hosts/[id]/page.tsx | 6 +- .../hosts/nicht-zugeordnet/page.tsx | 129 ++++----- .../kunden/[id]/bearbeiten/page.tsx | 65 +++++ src/app/(dashboard)/kunden/[id]/page.tsx | 229 +++++++++------- src/app/(dashboard)/kunden/neu/page.tsx | 27 ++ src/app/(dashboard)/kunden/page.tsx | 61 +++-- src/app/(dashboard)/layout.tsx | 30 ++- src/app/(dashboard)/page.tsx | 248 +++++++++--------- src/components/hosts/ZuweisungsFormular.tsx | 146 +++++++++++ src/components/kunden/KundeFormular.tsx | 125 +++++++++ src/components/kunden/StandortVerwaltung.tsx | 94 +++++++ src/components/layout/Footer.tsx | 2 +- src/components/layout/Header.tsx | 22 +- src/components/layout/SearchDialog.tsx | 10 +- src/components/tokens/TokenFormular.tsx | 101 +++++++ src/components/ui/Badges.tsx | 11 +- src/lib/anzeige.ts | 31 +++ src/lib/db.ts | 23 +- src/server/actions/hosts.ts | 44 ++++ src/server/actions/kunden.ts | 126 +++++++++ src/server/actions/tokens.ts | 79 ++++++ src/server/agent/http.ts | 6 +- src/server/audit.ts | 21 ++ src/server/queries/dashboard.ts | 106 ++++++++ src/server/queries/hosts.ts | 136 ++++++++++ src/server/queries/kunden.ts | 138 ++++++++++ src/server/services/zuweisung.ts | 52 ++++ tests/kunden-zuweisung.test.ts | 165 ++++++++++++ 40 files changed, 2060 insertions(+), 415 deletions(-) create mode 100644 docs/anleitung/bilder/kunde-neu.png create mode 100644 docs/anleitung/bilder/kunden.png create mode 100644 docs/anleitung/bilder/tokens.png create mode 100644 src/app/(dashboard)/kunden/[id]/bearbeiten/page.tsx create mode 100644 src/app/(dashboard)/kunden/neu/page.tsx create mode 100644 src/components/hosts/ZuweisungsFormular.tsx create mode 100644 src/components/kunden/KundeFormular.tsx create mode 100644 src/components/kunden/StandortVerwaltung.tsx create mode 100644 src/components/tokens/TokenFormular.tsx create mode 100644 src/lib/anzeige.ts create mode 100644 src/server/actions/hosts.ts create mode 100644 src/server/actions/kunden.ts create mode 100644 src/server/actions/tokens.ts create mode 100644 src/server/audit.ts create mode 100644 src/server/queries/dashboard.ts create mode 100644 src/server/queries/hosts.ts create mode 100644 src/server/queries/kunden.ts create mode 100644 src/server/services/zuweisung.ts create mode 100644 tests/kunden-zuweisung.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 997f880..141a85f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,20 @@ und dieses Projekt folgt [Semantic Versioning](https://semver.org/lang/de/). ### Sicherheit +## [0.3.0] – 2026-09-17 + +### Hinzugefügt +- Kunden anlegen, bearbeiten und löschen; Standorte je Kunde verwalten (#006) +- Seite „Nicht zugeordnete Hosts“ mit Mehrfachauswahl und Zuweisung in einem Schritt (#006) +- Enrollment-Tokens erzeugen (mit Gültigkeit, Nutzungsgrenze und optionaler Kundenbindung), anzeigen und widerrufen; Host-Tokens widerrufen (#006) +- Audit-Log-Einträge für alle Änderungen an Kunden, Standorten, Zuweisungen und Tokens (#006) + +### Geändert +- Dashboard, Kundenübersicht, Kunden-Detail und globale Suche arbeiten mit echten Daten statt Beispieldaten (#006) + +### Behoben +- Prisma-Client öffnete in der Produktionsumgebung bei jedem Zugriff einen neuen Verbindungspool (#006) + ## [0.2.0] – 2026-09-17 ### Hinzugefügt diff --git a/DEVLOG.md b/DEVLOG.md index a392487..4a192d6 100644 --- a/DEVLOG.md +++ b/DEVLOG.md @@ -2,7 +2,7 @@ ## Zeitübersicht -**Gesamt:** 1 h 38 min +**Gesamt:** 2 h 13 min | Issue | Zeit | |---|---| @@ -11,17 +11,19 @@ | #003 Datenmodell und Migrationen | 0 h 25 min | | #004 Agent-API | 0 h 20 min | | #005 Agent-Skript | 0 h 25 min | +| #006 Kunden und Hostzuweisung | 0 h 35 min | | Meilenstein | Zeit | |---|---| | v0.1.0 | 1 h 13 min | **abgeschlossen** | v0.2.0 | 0 h 25 min | **abgeschlossen** +| v0.3.0 | 0 h 35 min | **abgeschlossen** --- ## 2026-09-17 · Sitzung 1 · 19:36–laufend -**Issue:** #001–#005 (Meilensteine v0.1.0 und v0.2.0) -**Version:** 0.2.0 +**Issue:** #001–#006 (Meilensteine v0.1.0 bis v0.3.0) +**Version:** 0.3.0 ### Erledigt - Auftrag gelesen, Rückfragen gestellt @@ -36,6 +38,9 @@ - Meilenstein v0.1.0 abgeschlossen und getaggt - #005 abgeschlossen: Bash-Agent mit Produkterkennung, JSON ohne jq, Retry mit Backoff, Spool, systemd-Timer, Installer, Uninstall und Update; Dashboard liefert `/install.sh` und `/agent.sh` aus - Meilenstein v0.2.0 abgeschlossen und getaggt; 38 Tests +- #006 abgeschlossen: Kunden und Standorte pflegen, Mehrfachzuweisung nicht zugeordneter Hosts, Enrollment- und Host-Tokens verwalten, Audit-Log; Dashboard, Kundenseiten und globale Suche laufen auf der Datenbank +- Durchlauf gegen den laufenden Server geprüft: Token anlegen → `enroll` → Agent-Report → Laufzeit-Vorschlag → Host erscheint als „nicht zugeordnet“ → `ping` +- Meilenstein v0.3.0 abgeschlossen und getaggt; 45 Tests ### Entscheidungen - **Screenshots mit Firefox headless** statt Playwright: Firefox ist vorhanden, es muss kein Browser samt Systembibliotheken nachinstalliert werden (dafür wäre root nötig). @@ -51,12 +56,15 @@ - **Prisma-Client wird lazy erzeugt** (Proxy), damit `next build` ohne gesetzte `DATABASE_URL` durchläuft. - **Report-Idempotenz über eine vom Agent erzeugte `reportId`**: nachgesendete Reports aus dem Spool dürfen beliebig oft ankommen. - **Unbekannte Subscription-Status werden zu `UNKNOWN`** statt abgelehnt – ein Report darf nie an einem neuen Statuswort scheitern. +- **Dashboard gleich mit auf die Datenbank umgestellt** (eigentlich #009): Eine frisch zugewiesene Zuordnung hätte dort sonst weiter als „nicht zugeordnet“ gestanden. +- **Server Actions rufen Services auf**, damit die Regeln ohne Next.js-Laufzeit testbar bleiben. ### Probleme / offene Fragen +- Prisma-Client erzeugte in der Produktionsumgebung bei jedem Zugriff einen neuen Verbindungspool → „too many clients“. Behoben: Client wird im Modul festgehalten. - Docker wurde von Florian installiert; die Entwicklungsdatenbank läuft auf Port 5433 (5432 bleibt für lokale Instanzen frei). - Favicon-Dateien (.ico/PNG) fehlen noch, weil kein SVG-Konverter installiert ist. - Der Agent wurde noch auf keinem echten Proxmox-Host installiert; die Tests arbeiten mit nachgebauten Befehlen. - Offen: Rolle „readonly“ zusätzlich zu Admin? (vorläufig vorgesehen) ### Nächster Schritt -- #006 Kunden, Standorte und Hostzuweisung (erste Oberfläche mit echten Daten) +- #007 Host-Tabelle mit Filtern, globale Suche auf Datenbankbasis und Host-Detailansicht diff --git a/docs/anleitung/bilder/dashboard.png b/docs/anleitung/bilder/dashboard.png index edf657b61730d734278a39115faa6d8572ff8c7f..04138a6ee5b04c100f291797c43acf604a748f21 100644 GIT binary patch delta 191558 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