a414f03a59
- Configure tailscale serve automatically for each instance on Windows userspace networking. - Add local UI buttons: start/stop/reset/delete instances (stop/start preserve volumes). - Clean shutdown: stop tailscaled and instances, notify server with instance_stopped. - Restart tailscaled on agent boot using persisted state when pre-auth key is absent. - Sync instance stopped/deleted status to dashboard (server/lib/websocket.ts). - Security: include prior authz/scoping changes across API routes, ephemeral pre-auth keys, ACL policy, internal API key. - Update SUIVI_VPN_ONDEMAND.md and docs/ONBOARDING_CLIENT.md. - Bump agent version to 0.3.5.
101 lines
3.1 KiB
Plaintext
101 lines
3.1 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
|
|
domain String?
|
|
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
|
|
activationCodeExpiresAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
nodes Node[]
|
|
}
|
|
|
|
model Node {
|
|
id String @id
|
|
studentId String?
|
|
student Student? @relation(fields: [studentId], references: [id], onDelete: Cascade)
|
|
token String? @unique
|
|
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[]
|
|
}
|