mirror of
https://github.com/KLogicHQ/nats-console.git
synced 2026-10-08 06:01:05 +00:00
460 lines
15 KiB
Plaintext
460 lines
15 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
// ==================== Enums ====================
|
|
|
|
enum OrganizationPlan {
|
|
free
|
|
pro
|
|
enterprise
|
|
}
|
|
|
|
enum UserStatus {
|
|
active
|
|
inactive
|
|
suspended
|
|
}
|
|
|
|
enum MemberRole {
|
|
owner
|
|
admin
|
|
member
|
|
viewer
|
|
}
|
|
|
|
enum ClusterEnvironment {
|
|
development
|
|
staging
|
|
production
|
|
}
|
|
|
|
enum ClusterStatus {
|
|
connected
|
|
disconnected
|
|
degraded
|
|
}
|
|
|
|
enum HealthStatus {
|
|
healthy
|
|
unhealthy
|
|
unknown
|
|
}
|
|
|
|
enum AlertSeverity {
|
|
info
|
|
warning
|
|
critical
|
|
}
|
|
|
|
// ==================== User & Organization ====================
|
|
|
|
model User {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
email String @unique @db.VarChar(255)
|
|
passwordHash String @map("password_hash") @db.VarChar(255)
|
|
firstName String? @map("first_name") @db.VarChar(100)
|
|
lastName String? @map("last_name") @db.VarChar(100)
|
|
avatarUrl String? @map("avatar_url") @db.VarChar(500)
|
|
status UserStatus @default(active)
|
|
emailVerified Boolean @default(false) @map("email_verified")
|
|
mfaEnabled Boolean @default(false) @map("mfa_enabled")
|
|
mfaSecret String? @map("mfa_secret") @db.VarChar(255)
|
|
lastLoginAt DateTime? @map("last_login_at")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
// Relations
|
|
organizationMemberships OrganizationMember[]
|
|
teamMemberships TeamMember[]
|
|
sessions Session[]
|
|
apiKeys ApiKey[]
|
|
streamConfigs StreamConfig[] @relation("CreatedBy")
|
|
consumerConfigs ConsumerConfig[] @relation("CreatedBy")
|
|
dashboards Dashboard[]
|
|
savedQueries SavedQuery[]
|
|
invitedMembers OrganizationMember[] @relation("InvitedBy")
|
|
invitesSent Invite[]
|
|
|
|
@@map("users")
|
|
}
|
|
|
|
model Organization {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
name String @db.VarChar(100)
|
|
slug String @unique @db.VarChar(50)
|
|
plan OrganizationPlan @default(free)
|
|
settings Json @default("{}")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
// Relations
|
|
members OrganizationMember[]
|
|
teams Team[]
|
|
clusters NatsCluster[]
|
|
roles Role[]
|
|
apiKeys ApiKey[]
|
|
dashboards Dashboard[]
|
|
savedQueries SavedQuery[]
|
|
alertRules AlertRule[]
|
|
invites Invite[]
|
|
notificationChannels NotificationChannel[]
|
|
|
|
@@map("organizations")
|
|
}
|
|
|
|
model OrganizationMember {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
orgId String @map("org_id") @db.Uuid
|
|
userId String @map("user_id") @db.Uuid
|
|
role MemberRole @default(member)
|
|
invitedBy String? @map("invited_by") @db.Uuid
|
|
joinedAt DateTime @default(now()) @map("joined_at")
|
|
|
|
// Relations
|
|
organization Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
inviter User? @relation("InvitedBy", fields: [invitedBy], references: [id])
|
|
|
|
@@unique([orgId, userId])
|
|
@@map("organization_members")
|
|
}
|
|
|
|
// ==================== Teams ====================
|
|
|
|
model Team {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
orgId String @map("org_id") @db.Uuid
|
|
name String @db.VarChar(100)
|
|
description String? @db.Text
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
// Relations
|
|
organization Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
members TeamMember[]
|
|
|
|
@@map("teams")
|
|
}
|
|
|
|
model TeamMember {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
teamId String @map("team_id") @db.Uuid
|
|
userId String @map("user_id") @db.Uuid
|
|
role MemberRole @default(member)
|
|
addedAt DateTime @default(now()) @map("added_at")
|
|
|
|
// Relations
|
|
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([teamId, userId])
|
|
@@map("team_members")
|
|
}
|
|
|
|
// ==================== NATS Clusters ====================
|
|
|
|
model NatsCluster {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
orgId String @map("org_id") @db.Uuid
|
|
name String @db.VarChar(100)
|
|
description String? @db.Text
|
|
environment ClusterEnvironment @default(development)
|
|
status ClusterStatus @default(disconnected)
|
|
version String? @db.VarChar(50)
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
// Relations
|
|
organization Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
connections ClusterConnection[]
|
|
streams StreamConfig[]
|
|
alertRules AlertRule[]
|
|
|
|
@@map("nats_clusters")
|
|
}
|
|
|
|
model ClusterConnection {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
clusterId String @map("cluster_id") @db.Uuid
|
|
serverUrl String @map("server_url") @db.VarChar(500)
|
|
credentials Json? @db.JsonB // Encrypted
|
|
tlsConfig Json? @map("tls_config") @db.JsonB
|
|
isPrimary Boolean @default(false) @map("is_primary")
|
|
healthStatus HealthStatus @default(unknown) @map("health_status")
|
|
lastHealthCheck DateTime? @map("last_health_check")
|
|
|
|
// Relations
|
|
cluster NatsCluster @relation(fields: [clusterId], references: [id], onDelete: Cascade)
|
|
|
|
@@map("cluster_connections")
|
|
}
|
|
|
|
// ==================== Streams & Consumers ====================
|
|
|
|
model StreamConfig {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
clusterId String @map("cluster_id") @db.Uuid
|
|
streamName String @map("stream_name") @db.VarChar(256)
|
|
configSnapshot Json @map("config_snapshot") @db.JsonB
|
|
createdBy String @map("created_by") @db.Uuid
|
|
isManaged Boolean @default(true) @map("is_managed")
|
|
tags Json @default("[]") @db.JsonB
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
// Relations
|
|
cluster NatsCluster @relation(fields: [clusterId], references: [id], onDelete: Cascade)
|
|
creator User @relation("CreatedBy", fields: [createdBy], references: [id])
|
|
consumers ConsumerConfig[]
|
|
|
|
@@unique([clusterId, streamName])
|
|
@@map("stream_configs")
|
|
}
|
|
|
|
model ConsumerConfig {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
streamConfigId String @map("stream_config_id") @db.Uuid
|
|
consumerName String @map("consumer_name") @db.VarChar(256)
|
|
configSnapshot Json @map("config_snapshot") @db.JsonB
|
|
createdBy String @map("created_by") @db.Uuid
|
|
isManaged Boolean @default(true) @map("is_managed")
|
|
tags Json @default("[]") @db.JsonB
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
// Relations
|
|
streamConfig StreamConfig @relation(fields: [streamConfigId], references: [id], onDelete: Cascade)
|
|
creator User @relation("CreatedBy", fields: [createdBy], references: [id])
|
|
|
|
@@unique([streamConfigId, consumerName])
|
|
@@map("consumer_configs")
|
|
}
|
|
|
|
// ==================== Roles & Permissions ====================
|
|
|
|
model Role {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
orgId String @map("org_id") @db.Uuid
|
|
name String @db.VarChar(100)
|
|
description String? @db.Text
|
|
isSystem Boolean @default(false) @map("is_system")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
// Relations
|
|
organization Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
permissions Permission[]
|
|
|
|
@@unique([orgId, name])
|
|
@@map("roles")
|
|
}
|
|
|
|
model Permission {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
roleId String @map("role_id") @db.Uuid
|
|
resource String @db.VarChar(100)
|
|
action String @db.VarChar(100)
|
|
conditions Json? @db.JsonB
|
|
|
|
// Relations
|
|
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
|
|
|
|
@@map("permissions")
|
|
}
|
|
|
|
// ==================== Sessions & API Keys ====================
|
|
|
|
model Session {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
userId String @map("user_id") @db.Uuid
|
|
tokenHash String @map("token_hash") @db.VarChar(255)
|
|
ipAddress String? @map("ip_address") @db.Inet
|
|
userAgent String? @map("user_agent") @db.Text
|
|
expiresAt DateTime @map("expires_at")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
// Relations
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@map("sessions")
|
|
}
|
|
|
|
model ApiKey {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
orgId String @map("org_id") @db.Uuid
|
|
userId String @map("user_id") @db.Uuid
|
|
name String @db.VarChar(100)
|
|
keyHash String @map("key_hash") @db.VarChar(255)
|
|
prefix String @db.VarChar(10)
|
|
permissions Json @default("[]") @db.JsonB
|
|
lastUsedAt DateTime? @map("last_used_at")
|
|
expiresAt DateTime? @map("expires_at")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
// Relations
|
|
organization Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@map("api_keys")
|
|
}
|
|
|
|
// ==================== Dashboards & Saved Queries ====================
|
|
|
|
model Dashboard {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
orgId String @map("org_id") @db.Uuid
|
|
userId String @map("user_id") @db.Uuid
|
|
name String @db.VarChar(100)
|
|
layout Json @default("{\"columns\": 12, \"rowHeight\": 80}") @db.JsonB
|
|
widgets Json @default("[]") @db.JsonB
|
|
isShared Boolean @default(false) @map("is_shared")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
// Relations
|
|
organization Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@map("dashboards")
|
|
}
|
|
|
|
model SavedQuery {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
orgId String @map("org_id") @db.Uuid
|
|
userId String @map("user_id") @db.Uuid
|
|
name String @db.VarChar(100)
|
|
query String @db.Text
|
|
description String? @db.Text
|
|
isShared Boolean @default(false) @map("is_shared")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
// Relations
|
|
organization Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@map("saved_queries")
|
|
}
|
|
|
|
// ==================== Alerts ====================
|
|
|
|
enum NotificationChannelType {
|
|
slack
|
|
email
|
|
teams
|
|
pagerduty
|
|
google_chat
|
|
webhook
|
|
}
|
|
|
|
enum IncidentStatus {
|
|
open
|
|
acknowledged
|
|
resolved
|
|
closed
|
|
}
|
|
|
|
model NotificationChannel {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
orgId String @map("org_id") @db.Uuid
|
|
name String @db.VarChar(100)
|
|
type NotificationChannelType
|
|
config Json @db.JsonB // webhookUrl, apiKey, email, etc.
|
|
isEnabled Boolean @default(true) @map("is_enabled")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
// Relations
|
|
organization Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
alertRules AlertRuleNotificationChannel[]
|
|
|
|
@@map("notification_channels")
|
|
}
|
|
|
|
model AlertRule {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
orgId String @map("org_id") @db.Uuid
|
|
clusterId String? @map("cluster_id") @db.Uuid
|
|
name String @db.VarChar(100)
|
|
condition Json @db.JsonB
|
|
threshold Json @db.JsonB
|
|
severity AlertSeverity @default(warning)
|
|
isEnabled Boolean @default(true) @map("is_enabled")
|
|
cooldownMins Int @default(5) @map("cooldown_mins")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
// Relations
|
|
organization Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
cluster NatsCluster? @relation(fields: [clusterId], references: [id], onDelete: SetNull)
|
|
notificationChannels AlertRuleNotificationChannel[]
|
|
incidents AlertIncident[]
|
|
|
|
@@map("alert_rules")
|
|
}
|
|
|
|
model AlertRuleNotificationChannel {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
ruleId String @map("rule_id") @db.Uuid
|
|
channelId String @map("channel_id") @db.Uuid
|
|
|
|
// Relations
|
|
rule AlertRule @relation(fields: [ruleId], references: [id], onDelete: Cascade)
|
|
channel NotificationChannel @relation(fields: [channelId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([ruleId, channelId])
|
|
@@map("alert_rule_notification_channels")
|
|
}
|
|
|
|
model AlertIncident {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
ruleId String @map("rule_id") @db.Uuid
|
|
status IncidentStatus @default(open)
|
|
triggeredAt DateTime @default(now()) @map("triggered_at")
|
|
acknowledgedAt DateTime? @map("acknowledged_at")
|
|
resolvedAt DateTime? @map("resolved_at")
|
|
closedAt DateTime? @map("closed_at")
|
|
metadata Json @default("{}") @db.JsonB // stores trigger values, context
|
|
notifiedAt DateTime? @map("notified_at")
|
|
|
|
// Relations
|
|
rule AlertRule @relation(fields: [ruleId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([ruleId, status])
|
|
@@map("alert_incidents")
|
|
}
|
|
|
|
// ==================== Invites ====================
|
|
|
|
enum InviteStatus {
|
|
pending
|
|
accepted
|
|
expired
|
|
revoked
|
|
}
|
|
|
|
model Invite {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
orgId String @map("org_id") @db.Uuid
|
|
email String @db.VarChar(255)
|
|
role MemberRole @default(member)
|
|
token String @unique @db.VarChar(255)
|
|
status InviteStatus @default(pending)
|
|
invitedBy String @map("invited_by") @db.Uuid
|
|
expiresAt DateTime @map("expires_at")
|
|
acceptedAt DateTime? @map("accepted_at")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
// Relations
|
|
organization Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
inviter User @relation(fields: [invitedBy], references: [id])
|
|
|
|
@@map("invites")
|
|
}
|