Server lassen sich anlegen, prüfen, bearbeiten und löschen. Proxmox liefert ab Werk ein selbst signiertes Zertifikat; der Admin sieht es vor dem Speichern und bestätigt den SHA-256-Fingerprint. Der Pin wird in einem eigenen undici-Connector geprüft, sodass eine fremde Gegenstelle das Token nie zu sehen bekommt. Weder Prüfung noch Pin ist im Schema, im Client und per CHECK ausgeschlossen. Fehler von Proxmox werden zu Ursache und Hinweis; bei 403 nennt der Hinweis das fehlende Recht samt Pfad. Getestet gegen einen HTTPS-Mock und im gebauten Stand auf Desktop und 390 px. Closes #002 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
103 lines
3.0 KiB
Plaintext
103 lines
3.0 KiB
Plaintext
// Datenmodell von ProxDeploy. Namensabbildung zur Vorgabe: siehe CLAUDE.md.
|
||
// Modelle kommen mit dem Issue dazu, das sie braucht – der Plan in docs/architektur.md
|
||
// zeigt das Zielbild.
|
||
|
||
generator client {
|
||
provider = "prisma-client"
|
||
output = "../src/generated/prisma"
|
||
}
|
||
|
||
datasource db {
|
||
provider = "postgresql"
|
||
}
|
||
|
||
enum Rolle {
|
||
ADMIN
|
||
OPERATOR
|
||
}
|
||
|
||
enum Quelle {
|
||
WEB
|
||
CLI
|
||
API
|
||
SYSTEM
|
||
}
|
||
|
||
model Benutzer {
|
||
id String @id @default(cuid())
|
||
benutzername String @unique
|
||
anzeigename String
|
||
email String?
|
||
/// argon2id; leer bei Benutzern, die sich nur per OIDC anmelden.
|
||
passwortHash String?
|
||
oidcSubjekt String? @unique
|
||
rolle Rolle @default(OPERATOR)
|
||
aktiv Boolean @default(true)
|
||
/// Persönliche Standardwerte im Assistenten.
|
||
standards Json?
|
||
erstelltAm DateTime @default(now())
|
||
geaendertAm DateTime @updatedAt
|
||
protokoll Protokoll[]
|
||
}
|
||
|
||
/// Audit-Log. Nur anhängen – ein Trigger verweigert UPDATE und DELETE.
|
||
model Protokoll {
|
||
id BigInt @id @default(autoincrement())
|
||
zeit DateTime @default(now())
|
||
benutzerId String?
|
||
benutzer Benutzer? @relation(fields: [benutzerId], references: [id], onDelete: SetNull)
|
||
quelle Quelle
|
||
aktion String
|
||
ziel String?
|
||
details Json?
|
||
ip String?
|
||
|
||
@@index([zeit])
|
||
@@index([benutzerId, zeit])
|
||
}
|
||
|
||
model Einstellung {
|
||
schluessel String @id
|
||
wert Json
|
||
geaendertAm DateTime @updatedAt
|
||
}
|
||
|
||
/// Ein Proxmox-VE-Einzelhost oder -Cluster. Geheimnisse liegen AES-256-GCM-verschlüsselt (v1.…).
|
||
model Server {
|
||
id String @id @default(cuid())
|
||
/// Kurzname, auch für die CLI (`--server rz1`).
|
||
name String @unique
|
||
/// Anzeigename, z. B. „Rechenzentrum 1“.
|
||
titel String
|
||
/// https://host:8006
|
||
url String
|
||
/// user@realm!tokenid
|
||
tokenId String
|
||
tokenGeheimnis String
|
||
/// Aus: nur ein gepinnter Fingerprint zählt. An: Systemvertrauen (+ optional Pin).
|
||
tlsPruefen Boolean @default(false)
|
||
/// SHA-256 des Serverzertifikats, Großbuchstaben mit Doppelpunkten.
|
||
fingerabdruck String?
|
||
sshAktiv Boolean @default(false)
|
||
sshBenutzer String @default("root")
|
||
sshPort Int @default(22)
|
||
sshPrivat String?
|
||
sshOeffentlich String?
|
||
/// Gepinnte Host-Keys je Node: { "pve01": "SHA256:…" }.
|
||
sshHostSchluessel Json?
|
||
templateVmidVon Int @default(9000)
|
||
templateVmidBis Int @default(9999)
|
||
gastVmidVon Int @default(100)
|
||
/// Statische Adresse für die Template-Vorbereitung ohne SSH: { bridge, vlan, ip, gateway }.
|
||
bauNetz Json?
|
||
/// Standard-Node, -Storage, -Bridge für den Assistenten.
|
||
standards Json?
|
||
/// Ergebnis der letzten Fähigkeitserkennung (#003).
|
||
faehigkeiten Json?
|
||
erreichbar Boolean?
|
||
pveVersion String?
|
||
geprueftAm DateTime?
|
||
erstelltAm DateTime @default(now())
|
||
geaendertAm DateTime @updatedAt
|
||
}
|