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:
@@ -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";
|
||||
}
|
||||
+14
-9
@@ -3,28 +3,33 @@ import { PrismaClient } from "@/generated/prisma/client";
|
||||
|
||||
/**
|
||||
* Prisma-Client als Singleton, der erst beim ersten Zugriff verbindet.
|
||||
* Das ist wichtig, weil Next.js beim Bauen Module lädt, ohne dass `DATABASE_URL` gesetzt sein muss.
|
||||
* Im Entwicklungsmodus verhindert der globale Zwischenspeicher, dass jeder Hot-Reload
|
||||
* einen neuen Verbindungspool öffnet.
|
||||
* Verzögert, weil Next.js beim Bauen Module lädt, ohne dass `DATABASE_URL` gesetzt sein muss.
|
||||
* Der Client wird im Modul festgehalten – sonst entstünde bei jedem Zugriff ein neuer
|
||||
* Verbindungspool – und im Entwicklungsmodus zusätzlich global, damit Hot-Reloads ihn wiederverwenden.
|
||||
*/
|
||||
declare global {
|
||||
var proxledgerPrisma: PrismaClient | undefined;
|
||||
}
|
||||
|
||||
function erzeugeClient(): PrismaClient {
|
||||
let client: PrismaClient | undefined;
|
||||
|
||||
export function getPrisma(): PrismaClient {
|
||||
if (client) return client;
|
||||
if (globalThis.proxledgerPrisma) {
|
||||
client = globalThis.proxledgerPrisma;
|
||||
return client;
|
||||
}
|
||||
|
||||
const connectionString = process.env.DATABASE_URL;
|
||||
if (!connectionString) {
|
||||
throw new Error("DATABASE_URL ist nicht gesetzt. Beispielwerte stehen in .env.example.");
|
||||
}
|
||||
const client = new PrismaClient({ adapter: new PrismaPg({ connectionString }) });
|
||||
|
||||
client = new PrismaClient({ adapter: new PrismaPg({ connectionString, max: 10 }) });
|
||||
if (process.env.NODE_ENV !== "production") globalThis.proxledgerPrisma = client;
|
||||
return client;
|
||||
}
|
||||
|
||||
export function getPrisma(): PrismaClient {
|
||||
return globalThis.proxledgerPrisma ?? erzeugeClient();
|
||||
}
|
||||
|
||||
export const prisma: PrismaClient = new Proxy({} as PrismaClient, {
|
||||
get(_ziel, eigenschaft, empfaenger) {
|
||||
return Reflect.get(getPrisma(), eigenschaft, empfaenger);
|
||||
|
||||
Reference in New Issue
Block a user