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) <noreply@anthropic.com>
This commit is contained in:
2026-09-17 21:02:44 +02:00
co-authored by Claude Opus 5
parent f591b45aac
commit f9a5ad2daa
40 changed files with 2060 additions and 415 deletions
+31
View File
@@ -0,0 +1,31 @@
/** Einheitliche Beschriftungen für Produkt und Subscription-Status (Datenbank und Prototyp-Daten). */
export type AnzeigeStatus = "active" | "notfound" | "invalid" | "expired" | "suspended" | "unknown";
export const PRODUKT_TEXT: Record<string, string> = {
PVE: "Proxmox VE",
PBS: "Proxmox Backup Server",
PMG: "Proxmox Mail Gateway",
pve: "Proxmox VE",
pbs: "Proxmox Backup Server",
pmg: "Proxmox Mail Gateway",
};
export const STATUS_TEXT: Record<AnzeigeStatus, string> = {
active: "Aktiv",
notfound: "Keine Subscription",
invalid: "Ungültig",
expired: "Abgelaufen",
suspended: "Ausgesetzt",
unknown: "Unbekannt",
};
/** Nimmt sowohl die Datenbank-Schreibweise (ACTIVE) als auch die von Proxmox (active) entgegen. */
export function statusAusDatenbank(wert: string): AnzeigeStatus {
const klein = wert.toLowerCase();
return (["active", "notfound", "invalid", "expired", "suspended"] as const).includes(
klein as AnzeigeStatus & ("active" | "notfound" | "invalid" | "expired" | "suspended"),
)
? (klein as AnzeigeStatus)
: "unknown";
}