479a8de858
- agent/websocket.go: expose sendMessage() + notifyUI() pour broadcaster les résultats d'activation à tous les clients UI connectés - agent/ui.go: supprime forwardActivation(), utilise sendMessage() sur la connexion WS principale au lieu d'une connexion temporaire - agent/activation.go: ajoute os.MkdirAll avant l'écriture d'activation.json - server/prisma/schema.prisma: onDelete Cascade sur Node→Student - server/app/dashboard/students/page.tsx: nom cliquable vers fiche détail - server/app/dashboard/students/[id]/actions.ts: deleteMany → delete
98 lines
2.9 KiB
Plaintext
98 lines
2.9 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
model Establishment {
|
|
id String @id @default(cuid())
|
|
name String
|
|
slug String @unique
|
|
createdAt DateTime @default(now())
|
|
subscription Subscription?
|
|
users User[]
|
|
classes Class[]
|
|
templates Template[]
|
|
}
|
|
|
|
model Subscription {
|
|
id String @id @default(cuid())
|
|
establishmentId String @unique
|
|
establishment Establishment @relation(fields: [establishmentId], references: [id], onDelete: Cascade)
|
|
plan String @default("trial")
|
|
status String @default("active")
|
|
expiresAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
}
|
|
|
|
model User {
|
|
id String @id @default(cuid())
|
|
email String @unique
|
|
password String
|
|
role String
|
|
establishmentId String?
|
|
establishment Establishment? @relation(fields: [establishmentId], references: [id], onDelete: SetNull)
|
|
createdAt DateTime @default(now())
|
|
}
|
|
|
|
model Class {
|
|
id String @id @default(cuid())
|
|
establishmentId String
|
|
establishment Establishment @relation(fields: [establishmentId], references: [id], onDelete: Cascade)
|
|
name String
|
|
level String
|
|
createdAt DateTime @default(now())
|
|
students Student[]
|
|
}
|
|
|
|
model Student {
|
|
id String @id @default(cuid())
|
|
classId String
|
|
class Class @relation(fields: [classId], references: [id], onDelete: Cascade)
|
|
firstName String
|
|
lastName String
|
|
email String
|
|
activationCode String? @unique
|
|
createdAt DateTime @default(now())
|
|
nodes Node[]
|
|
}
|
|
|
|
model Node {
|
|
id String @id
|
|
studentId String?
|
|
student Student? @relation(fields: [studentId], references: [id], onDelete: Cascade)
|
|
tailscaleIp String?
|
|
status String @default("offline")
|
|
lastSeen DateTime?
|
|
createdAt DateTime @default(now())
|
|
instances Instance[]
|
|
}
|
|
|
|
model Instance {
|
|
id String @id @default(cuid())
|
|
nodeId String
|
|
node Node @relation(fields: [nodeId], references: [id], onDelete: Cascade)
|
|
templateId String
|
|
template Template @relation(fields: [templateId], references: [id], onDelete: Restrict)
|
|
status String @default("stopped")
|
|
port Int
|
|
createdAt DateTime @default(now())
|
|
}
|
|
|
|
model Template {
|
|
id String @id @default(cuid())
|
|
name String
|
|
type String
|
|
dockerImage String
|
|
composeConfig String
|
|
isPublic Boolean @default(true)
|
|
establishmentId String?
|
|
establishment Establishment? @relation(fields: [establishmentId], references: [id], onDelete: Cascade)
|
|
createdBy String
|
|
createdAt DateTime @default(now())
|
|
instances Instance[]
|
|
}
|