# Proxmox Multi-Tenant Console — Entwicklungsplan Plan zur Übergabe an einen ausführenden AI-Agenten. Jede Aufgabe ist so geschnitten, dass sie eigenständig umsetzbar, testbar und reviewbar ist. Arbeite die Epics in Reihenfolge ab; innerhalb eines Epics geben die `Abhängigkeiten` die Reihenfolge vor. --- ## 0. Stack-Entscheidungen (verbindlich) Diese Entscheidungen sind getroffen. Nicht abweichen, ohne Rückfrage. | Bereich | Entscheidung | |---|---| | Auth | Supabase Auth (E-Mail/Passwort, OAuth, TOTP/2FA) | | Datenbank | Supabase Postgres (direkter Postgres-Zugriff, **nicht** über PostgREST) | | Backend | **Go** (>= 1.22), HTTP-Framework: `chi`; DB-Zugriff: `pgx` + `sqlc` für typsichere Queries | | Migrations | `golang-migrate` (SQL-Files, versioniert) | | Worker / Queue | Eigener Go-Worker + `asynq` (Redis-basiert) | | Konsolen-Proxy | Eigener Go-Dienst (Websocket), `nhooyr.io/websocket` | | Proxmox-Client | Eigener dünner HTTP-Client (keine fertige Lib zwingend; falls Lib, dann nur als Referenz) | | Frontend | React + TypeScript, Vite, TanStack Query, Tailwind, shadcn/ui | | Konsole-Rendering | noVNC (VNC) bzw. xterm.js (Serial) | | Secrets | Master-Key aus ENV/Secret-Manager; Cluster-Tokens **verschlüsselt** in DB (AES-GCM, Envelope) | > Falls Python statt Go gewünscht ist: ersetze die Go-spezifischen Schritte sinngemäß (FastAPI + SQLAlchemy/asyncpg + Celery), die Architektur bleibt identisch. ### Architektur-Grundregeln (gelten für ALLE Aufgaben) 1. **Nur das Backend spricht mit Proxmox.** Kein Proxmox-Token, kein Proxmox-Hostname erreicht jemals das Frontend. 2. **Supabase liefert Identität, das Backend macht Autorisierung.** JWT wird gegen Supabase-JWKS validiert; Rollen/Rechte kommen aus eigenen Tabellen. 3. **Source of Truth ist die eigene DB.** Proxmox ist Ausführungsebene. Ein Reconciliation-Job gleicht Drift ab. 4. **Multi-Cluster von Anfang an.** Alle Proxmox-Zugriffe gehen über eine `cluster_id`. 5. **Jede tenant-bezogene Query trägt `WHERE tenant_id = $1`.** RLS bleibt zusätzlich aktiv (Defense in depth). 6. **Sensible Felder (Token, Secrets) niemals in DTOs/API-Responses mappen.** --- ## 1. Konventionen für den Agenten - **Sprache:** Code-Identifier und Commits auf Englisch; UI-Texte auf Deutsch. - **Branches:** ein Branch pro Aufgabe, Name = Task-ID (z.B. `E2-T03-schema-tenants`). - **Commits:** Conventional Commits (`feat:`, `fix:`, `chore:`, `test:`). - **Definition of Done pro Task:** Code + Tests grün + Lint sauber + kurze Notiz in `CHANGELOG.md`, was umgesetzt wurde und welche Annahmen getroffen wurden. - **Keine echten Credentials im Repo.** `.env.example` pflegen, echte `.env` in `.gitignore`, Secret-Scanner in CI. - **Tests:** Unit-Tests für Krypto/Auth/Autorisierung sind Pflicht. Für Proxmox-Calls einen Mock-Server bauen (kein Live-Cluster in CI). - **Bei Unklarheit:** Annahme dokumentieren und weiterarbeiten, nicht blockieren — außer es betrifft Sicherheit (dann stoppen und nachfragen). --- ## EPIC E0 — Projekt-Setup & Infrastruktur ### E0-T01 — Monorepo-Grundgerüst - **Ziel:** Repo-Struktur stehen. - **Schritte:** Ordner `backend/`, `worker/`, `console-proxy/`, `frontend/`, `migrations/`, `deploy/`. Root-`README.md`, `CHANGELOG.md`, `.gitignore`, `.env.example`. - **Akzeptanz:** Repo klont sich, `README` erklärt Setup in <10 Schritten. - **Abhängigkeiten:** keine. ### E0-T02 — Lokale Dev-Umgebung - **Ziel:** Alles lokal startbar. - **Schritte:** `docker-compose.yml` mit Supabase CLI Stack (Postgres + Auth + Studio) und Redis. Makefile-Targets: `make dev`, `make migrate`, `make test`, `make lint`. - **Akzeptanz:** `make dev` bringt Postgres, Auth, Redis hoch; Studio erreichbar. - **Abhängigkeiten:** E0-T01. ### E0-T03 — CI-Pipeline - **Ziel:** Automatische Qualitätssicherung. - **Schritte:** GitHub Actions (oder gewähltes CI): Build, Lint (`golangci-lint`, `eslint`), Tests, Secret-Scan (`gitleaks`). - **Akzeptanz:** PR ohne grüne CI ist nicht mergebar. - **Abhängigkeiten:** E0-T01. ### E0-T04 — Konfigurations- & Logging-Layer - **Ziel:** Saubere Config und strukturierte Logs. - **Schritte:** Config aus ENV (z.B. `envconfig`), validiert beim Start. Strukturiertes Logging (`slog`), Request-IDs, keine Secrets in Logs. - **Akzeptanz:** Fehlt eine Pflicht-ENV, bricht der Start mit klarer Meldung ab. - **Abhängigkeiten:** E0-T01. --- ## EPIC E1 — Auth & JWT-Middleware ### E1-T01 — Supabase-Projekt & Auth-Konfiguration - **Ziel:** Auth nutzbar. - **Schritte:** Supabase-Projekt anlegen (oder CLI lokal). E-Mail/Passwort aktivieren, mind. einen OAuth-Provider, TOTP/2FA aktivieren. JWKS-URL und Issuer notieren. - **Akzeptanz:** Test-User kann sich registrieren und JWT erhalten. - **Abhängigkeiten:** E0-T02. ### E1-T02 — JWT-Validierungs-Middleware (Backend) - **Ziel:** Eingehende Requests authentifizieren. - **Schritte:** Middleware, die `Authorization: Bearer ` liest, Signatur gegen Supabase-JWKS prüft (JWKS cachen + periodisch refreshen), Issuer/Expiry validiert. `sub`-Claim (= Supabase-User-ID) in den Request-Context legen. Bei ungültig: 401. - **Akzeptanz:** Unit-Test mit gültigem, abgelaufenem und manipuliertem Token (jeweils korrektes Verhalten). Geschützter Endpunkt ohne Token → 401. - **Abhängigkeiten:** E1-T01. ### E1-T03 — Profil-Sync (auth.users → public.profiles) - **Ziel:** Eigene Nutzer-Entität verknüpft mit Supabase. - **Schritte:** Beim ersten authentifizierten Request: falls kein `profiles`-Eintrag zur `sub`-ID existiert, anlegen (lazy provisioning). Alternativ Supabase DB-Trigger auf `auth.users`. Eine Variante wählen und dokumentieren. - **Akzeptanz:** Nach Erstlogin existiert genau ein `profiles`-Datensatz. - **Abhängigkeiten:** E1-T02, E2-T02. --- ## EPIC E2 — Datenmodell & Migrations > Alle Tabellen ins `public`-Schema. `profiles.id` referenziert `auth.users.id`. RLS auf allen tenant-bezogenen Tabellen aktivieren. ### E2-T01 — Migrations-Setup - **Ziel:** Versionierte Schema-Änderungen. - **Schritte:** `golang-migrate` einbinden, `make migrate` / `make migrate-down`. Namens-Schema `NNNN_beschreibung.up.sql` / `.down.sql`. - **Akzeptanz:** Up und Down laufen idempotent durch. - **Abhängigkeiten:** E0-T02. ### E2-T02 — Kern-Tabellen: profiles, tenants, memberships - **Ziel:** Mandanten- und Nutzergrundlage. - **Schritte:** - `profiles` (id = auth.users.id, email, display_name, created_at) - `tenants` (id, name, slug, status, created_at) - `memberships` (profile_id, tenant_id, role enum: owner|admin|member|viewer, UNIQUE(profile_id, tenant_id)) - **Akzeptanz:** Migration läuft; FKs und Indizes gesetzt; ein User kann mehreren Tenants angehören. - **Abhängigkeiten:** E2-T01. ### E2-T03 — Projekte & Quotas - **Ziel:** Projektebene wie bei Hetzner. - **Schritte:** - `projects` (id, tenant_id FK, name, created_at) - `project_quotas` (project_id FK, max_vcpu, max_ram_mb, max_disk_gb, max_vms) - **Akzeptanz:** Projekte gehören eindeutig zu einem Tenant; Quota-Defaults gesetzt. - **Abhängigkeiten:** E2-T02. ### E2-T04 — Clusters-Tabelle (verschlüsselte Credentials) - **Ziel:** Multi-Cluster-Zugriff sicher. - **Schritte:** - `clusters` (id, name, api_endpoint, tls_fingerprint, `encrypted_token` bytea, token_id text, status, created_at) - Klartext-Token **nie** speichern. Verschlüsselung kommt aus E3. - **Akzeptanz:** Spalte `encrypted_token` ist `bytea`; kein Klartext-Feld vorhanden. - **Abhängigkeiten:** E2-T01. ### E2-T05 — VMs & Ressourcen-Mapping - **Ziel:** Eigene Sicht auf VMs (Source of Truth). - **Schritte:** - `vms` (id, project_id FK, cluster_id FK, proxmox_vmid int, node text, name, status, vcpu, ram_mb, disk_gb, created_at) - `ssh_keys` (id, tenant_id FK, name, public_key, created_at) - Index auf (cluster_id, proxmox_vmid) UNIQUE. - **Akzeptanz:** VM ist eindeutig einem Projekt und einem Cluster zugeordnet. - **Abhängigkeiten:** E2-T03, E2-T04. ### E2-T06 — VMID-Allokator - **Ziel:** Race-freie, clusterweit eindeutige VMID-Vergabe. - **Schritte:** Tabelle oder Sequence pro Cluster; Vergabe in einer Transaktion mit `SELECT ... FOR UPDATE` oder Postgres-Sequence. Vergebene IDs reservieren, bevor Proxmox-Call startet. - **Akzeptanz:** Concurrency-Test mit 50 parallelen Anfragen erzeugt keine Doppel-VMID. - **Abhängigkeiten:** E2-T05. ### E2-T07 — Audit-Log-Tabelle - **Ziel:** Nachvollziehbarkeit. - **Schritte:** `audit_log` (id, tenant_id, profile_id, action, target_type, target_id, metadata jsonb, created_at). Append-only. - **Akzeptanz:** Tabelle vorhanden, indiziert auf (tenant_id, created_at). - **Abhängigkeiten:** E2-T02. ### E2-T08 — RLS-Policies - **Ziel:** DB-seitige Mandanten-Isolation als zweite Verteidigungslinie. - **Schritte:** RLS auf tenants/projects/vms/ssh_keys/audit_log aktivieren; Policies auf Basis der Mitgliedschaft. Service-Role des Backends ist dokumentiert ausgenommen (Backend macht eigene Filterung). - **Akzeptanz:** Direkter Query als Nicht-Mitglied liefert keine fremden Zeilen. - **Abhängigkeiten:** E2-T02 bis E2-T07. --- ## EPIC E3 — Proxmox-Zugriffsschicht ### E3-T01 — Krypto-Layer (Envelope-Encryption) - **Ziel:** Cluster-Tokens sicher ver-/entschlüsseln. - **Schritte:** AES-GCM mit 32-Byte-Master-Key aus ENV/Secret-Manager. Nonce wird dem Ciphertext vorangestellt. Funktionen `Encrypt(plaintext)` / `Decrypt(ciphertext)`. Key-Versionierung vorsehen (Prefix-Byte), um spätere Rotation zu ermöglichen. - **Akzeptanz:** Roundtrip-Unit-Test; falscher Key → Fehler statt Müll; Master-Key fehlt → Start bricht ab. - **Abhängigkeiten:** E0-T04. ### E3-T02 — Cluster-Repository - **Ziel:** Cluster-Credentials laden/speichern. - **Schritte:** `GetCluster(id)` lädt und entschlüsselt das Token im Speicher; `UpsertCluster` verschlüsselt vor dem Speichern. Token nie loggen, nie in DTO. - **Akzeptanz:** Test: gespeichertes Token kommt entschlüsselt korrekt zurück; DB enthält nur Ciphertext. - **Abhängigkeiten:** E3-T01, E2-T04. ### E3-T03 — Proxmox-HTTP-Client mit TLS-Pinning - **Ziel:** Sichere Verbindung zum Cluster. - **Schritte:** HTTP-Client, der pro Cluster den `tls_fingerprint` prüft (kein `InsecureSkipVerify`). Auth-Header `PVEAPIToken==`. Methoden: `Get/Post/Put/Delete` mit Retry + Timeout + Kontext. - **Akzeptanz:** Verbindung gegen Mock-Server mit korrektem/falschem Fingerprint (akzeptiert/abgelehnt). Kein Klartext-Secret in Logs. - **Abhängigkeiten:** E3-T02. ### E3-T04 — Admin-Endpunkt: Cluster verwalten - **Ziel:** Cluster anlegen/Token rotieren ohne Deployment. - **Schritte:** Interner Endpunkt (nur Operator-Rolle, **nicht** für Kunden): Cluster anlegen, Token aktualisieren, Status setzen. Response enthält nie das Token. - **Akzeptanz:** Token-Rotation per Request ändert nur `encrypted_token`; alter Wert nicht mehr lesbar. - **Abhängigkeiten:** E3-T03, E4-T02. --- ## EPIC E4 — Autorisierung (RBAC) ### E4-T01 — Mitgliedschafts-Resolver - **Ziel:** Vom JWT zur Berechtigung. - **Schritte:** Aus `sub` → `profiles` → `memberships` laden; aktuellen Tenant/Projekt aus Request ableiten; Rolle ermitteln. Im Context bereitstellen. - **Akzeptanz:** Nicht-Mitglied eines Tenants erhält bei tenant-Zugriff 403. - **Abhängigkeiten:** E1-T02, E2-T02. ### E4-T02 — Policy-/Permission-Funktion - **Ziel:** Zentrale `Can(role, action, resource)`-Prüfung. - **Schritte:** Rollen-Matrix (owner/admin/member/viewer × Aktionen wie vm.read, vm.power, vm.create, vm.delete, project.manage, cluster.manage[nur Operator]). Eine Funktion, überall aufgerufen. - **Akzeptanz:** Tabellengetriebener Unit-Test deckt alle Rollen×Aktionen ab. - **Abhängigkeiten:** E4-T01. ### E4-T03 — Autorisierungs-Middleware - **Ziel:** Deklarativer Schutz pro Route. - **Schritte:** Middleware/Helper, der vor Handler die nötige Permission prüft. Quota-Check als separater Helper für create-Aktionen. - **Akzeptanz:** Geschützte Route ohne Recht → 403; mit Recht → durch. - **Abhängigkeiten:** E4-T02. --- ## EPIC E5 — VM-Lifecycle (synchron lesend + Aktionen) ### E5-T01 — VM-Liste & Detail (read) - **Ziel:** Kunden sehen ihre VMs. - **Schritte:** Endpunkte `GET /projects/:id/vms` und `GET /vms/:id`. Daten aus eigener DB; Live-Status optional via Proxmox ergänzen. Immer tenant-/projektgefiltert. - **Akzeptanz:** Nutzer sieht nur VMs seiner Projekte. - **Abhängigkeiten:** E3-T03, E4-T03, E2-T05. ### E5-T02 — Power-Aktionen (start/stop/reboot) - **Ziel:** VM steuern. - **Schritte:** Endpunkte, die Permission `vm.power` prüfen, Proxmox-Call absetzen, die zurückgegebene UPID an den Worker übergeben (siehe E6), Audit-Log schreiben. - **Akzeptanz:** Start einer VM erzeugt Task; Status wird nach Abschluss in DB aktualisiert. - **Abhängigkeiten:** E5-T01, E6-T02, E2-T07. ### E5-T03 — Reconciliation-Job - **Ziel:** Drift zwischen DB und Proxmox erkennen. - **Schritte:** Periodischer Job, der pro Cluster den Ist-Zustand abruft und mit der DB abgleicht; Abweichungen markieren/loggen. Vorerst nur Reporting, kein Auto-Fix. - **Akzeptanz:** Manuell in Proxmox gestoppte VM wird im nächsten Lauf als abweichend erkannt. - **Abhängigkeiten:** E5-T01. --- ## EPIC E6 — Task-Worker (asynchron) ### E6-T01 — Worker-Grundgerüst - **Ziel:** Eigener Dienst für lange Jobs. - **Schritte:** Go-Worker mit `asynq`, Redis-Anbindung, Verbindung zur selben Supabase-DB über den **Connection Pooler (Supavisor)**. Graceful Shutdown. - **Akzeptanz:** Worker startet, verarbeitet einen Dummy-Job. - **Abhängigkeiten:** E0-T02, E2-T01. ### E6-T02 — UPID-Polling-Job - **Ziel:** Proxmox-Tasks zu Ende verfolgen. - **Schritte:** Job-Typ `proxmox.task.poll` (Input: cluster_id, node, UPID, ziel-Entität). Pollt Status bis Erfolg/Fehler, aktualisiert die betroffene Entität in der DB, schreibt Audit-Log. Timeout + max. Retries; bei Fehler Status `failed` + Fehlertext. - **Akzeptanz:** Mock-Proxmox liefert „running" dann „stopped/OK" → DB-Status wird final korrekt; bei „error" → `failed`. - **Abhängigkeiten:** E6-T01, E3-T03. ### E6-T03 — Cleanup bei Fehlschlag - **Ziel:** Keine Zombie-Ressourcen. - **Schritte:** Wenn ein Provisioning-Task scheitert, halbfertige VM in Proxmox entfernen oder als `failed` markieren und VMID freigeben. - **Akzeptanz:** Simulierter Fehlschlag hinterlässt keine reservierte VMID und keine verwaiste VM. - **Abhängigkeiten:** E6-T02, E2-T06. --- ## EPIC E7 — Provisioning (Clone + cloud-init) ### E7-T01 — SSH-Key-Verwaltung - **Ziel:** Kunden hinterlegen Keys. - **Schritte:** CRUD-Endpunkte für `ssh_keys` (tenant-gescoped), Validierung des Public-Key-Formats. - **Akzeptanz:** Ungültiger Key wird abgelehnt; Keys sind tenant-isoliert. - **Abhängigkeiten:** E4-T03, E2-T05. ### E7-T02 — Template-Vorbereitung (Doku + Skript) - **Ziel:** cloud-init-fähige Templates pro Node. - **Schritte:** Dokumentiertes Vorgehen + optionales Skript, um Cloud-Images (Ubuntu/Debian) als Proxmox-Templates anzulegen. In der DB eine `templates`-Referenz (id, cluster_id, name, proxmox_template_vmid). - **Akzeptanz:** Mind. ein Template pro Test-Cluster auswählbar. - **Abhängigkeiten:** E3-T03. ### E7-T03 — VM-Erstellung (Clone + cloud-init) - **Ziel:** Self-Service-VM wie bei Hetzner. - **Schritte:** `POST /projects/:id/vms`: Permission + Quota prüfen → VMID allokieren → Proxmox-Clone vom Template → cloud-init setzen (SSH-Key, Hostname, Netzwerk) → Start → UPID an Worker. DB-Eintrag mit Status `provisioning`. - **Akzeptanz:** End-to-End gegen Mock: VM-Datensatz entsteht, Worker schließt ab, Status `running`. Quota-Überschreitung → 409. - **Abhängigkeiten:** E7-T01, E7-T02, E6-T02, E2-T06, E4-T03. ### E7-T04 — VM löschen - **Ziel:** Aufräumen sauber. - **Schritte:** `DELETE /vms/:id` mit Permission `vm.delete`; Proxmox-Stop+Delete via Worker; DB-Eintrag und VMID freigeben; Audit-Log. - **Akzeptanz:** Nach Löschung keine VM in DB/Proxmox, VMID wieder vergebbar. - **Abhängigkeiten:** E7-T03. --- ## EPIC E8 — Konsolen-Proxy (noVNC) ### E8-T01 — Konsolen-Ticket-Endpunkt - **Ziel:** Kurzlebigen Zugang ausstellen. - **Schritte:** `POST /vms/:id/console`: Permission `vm.console` prüfen, von Proxmox VNC-Ticket holen, ein eigenes kurzlebiges, signiertes Proxy-Ticket an den Client geben (enthält keine Proxmox-Daten). - **Akzeptanz:** Nicht-berechtigter Nutzer → 403; Ticket hat kurze Gültigkeit. - **Abhängigkeiten:** E4-T03, E3-T03. ### E8-T02 — Websocket-Proxy-Dienst - **Ziel:** Browser ↔ Proxmox-Konsole ohne direkte Verbindung. - **Schritte:** Eigener Dienst, der das Proxy-Ticket validiert, **bei jedem Verbindungsaufbau** die Berechtigung erneut gegen die DB prüft, dann zur Proxmox-VNC-Websocket durchreicht. Kein Proxmox-Hostname zum Client. - **Akzeptanz:** Verbindung mit gültigem Ticket funktioniert; abgelaufenes/fremdes Ticket wird abgewiesen. - **Abhängigkeiten:** E8-T01. --- ## EPIC E9 — Audit-Log (Querschnitt) ### E9-T01 — Audit-Writer - **Ziel:** Einheitliches Logging sicherheitsrelevanter Aktionen. - **Schritte:** Helper `Audit(ctx, action, target, metadata)`. In allen state-ändernden Endpunkten aufrufen (power, create, delete, key-changes, cluster-admin). - **Akzeptanz:** Jede schreibende Aktion erzeugt genau einen Audit-Eintrag. - **Abhängigkeiten:** E2-T07. ### E9-T02 — Audit-Anzeige (read) - **Ziel:** Transparenz für Tenant-Admins. - **Schritte:** `GET /tenants/:id/audit` mit Paginierung, nur für admin/owner. - **Akzeptanz:** Viewer/Member sehen kein Audit-Log. - **Abhängigkeiten:** E9-T01, E4-T03. --- ## EPIC E10 — Frontend MVP ### E10-T01 — App-Grundgerüst & Auth - **Ziel:** Login funktioniert. - **Schritte:** Vite + React + TS, Supabase JS-Client nur für Auth (Login/Logout/2FA), JWT im Speicher halten, an Backend-Calls per `Authorization`-Header anhängen. API-Layer mit TanStack Query. - **Akzeptanz:** Nutzer kann sich einloggen, 2FA durchlaufen, Token wird an Backend gesendet. - **Abhängigkeiten:** E1-T01. ### E10-T02 — Tenant-/Projekt-Umschalter & Mitgliederverwaltung - **Ziel:** Multi-Tenant-Navigation. - **Schritte:** Tenant-Switcher, Projektliste, Einladen/Rollen-Zuweisung (admin/owner). Layout im Hetzner-Stil (clean, shadcn/ui). - **Akzeptanz:** Wechsel zwischen Tenants lädt jeweils nur eigene Projekte. - **Abhängigkeiten:** E10-T01, E4-T03. ### E10-T03 — VM-Übersicht & Detail - **Ziel:** Kern-UI. - **Schritte:** VM-Liste mit Status, Detailseite mit Basis-Metriken, Power-Buttons (start/stop/reboot), Live-Status via Polling/Refetch. - **Akzeptanz:** Power-Aktion spiegelt sich nach Task-Abschluss in der UI. - **Abhängigkeiten:** E10-T02, E5-T02. ### E10-T04 — VM-Erstellungs-Wizard - **Ziel:** Self-Service-Provisioning. - **Schritte:** Wizard (Template, Größe, SSH-Key, Name), Quota-Anzeige, Fortschritt während `provisioning`. - **Akzeptanz:** Erstellte VM erscheint und wechselt nach Abschluss auf `running`. - **Abhängigkeiten:** E10-T03, E7-T03. ### E10-T05 — Web-Konsole - **Ziel:** noVNC im Browser. - **Schritte:** noVNC-Komponente, holt Ticket vom Backend, verbindet sich mit dem Konsolen-Proxy. - **Akzeptanz:** Funktionierende Konsole für berechtigte Nutzer. - **Abhängigkeiten:** E10-T03, E8-T02. ### E10-T06 — SSH-Keys & Audit-Ansicht - **Ziel:** Restliche MVP-Verwaltung. - **Schritte:** Key-Verwaltung-UI; Audit-Log-Ansicht für Admins. - **Akzeptanz:** Keys verwaltbar; Audit nur für Admins sichtbar. - **Abhängigkeiten:** E7-T01, E9-T02. --- ## Phase 2 & 3 (Backlog, nach MVP) Grob umrissen — bei Bedarf nach demselben Schema (Ziel/Schritte/Akzeptanz/Abhängigkeiten) herunterbrechen. - **Phase 2:** Snapshots & Backups (Proxmox Backup Server), VM-Resize/Rebuild, Firewall-Regeln pro VM (Proxmox-Firewall-API), private Netzwerke via SDN/VNet pro Tenant, Floating IPs (eigener IP-Pool), feinere Quota-Durchsetzung. - **Phase 3:** Metriken-Dashboards (Proxmox-Metriken nach Prometheus/InfluxDB exportieren), Usage-Tracking als Abrechnungsgrundlage, öffentliche API mit Projekt-Tokens (Terraform-Support), E-Mail-Benachrichtigungen, ISO-Mounts, LXC-Container, Load Balancer. --- ## Empfohlene Bearbeitungsreihenfolge (kritischer Pfad) ``` E0 → E1 → E2 → E3 → E4 → E6 (Grundgerüst) → E5 → E7 → E8 → E9 → E10 ``` E9 (Audit) und E10 (Frontend) laufen teils parallel, sobald die jeweiligen Backend-Endpunkte stehen. E6-T01 sollte früh kommen, weil E5/E7 darauf aufbauen.