Files
tessera-ctl/apps/api/prisma/schema.prisma
T
schalli 38dcfdfa6d feat(05-02): add SearchProvider backend with model, CRUD, and defaults
- Prisma model SearchProvider with userId/tenantId scoping
- Three default providers (Google/Bing/DuckDuckGo) as constants, always returned without DB seed
- GET/POST/DELETE search-providers endpoints on DashboardController
- Ownership verification on delete (T-05-07), default providers cannot be deleted
- CreateSearchProviderDto with class-validator: urlTemplate must contain {query} (T-05-08)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 11:34:45 +02:00

149 lines
3.9 KiB
Plaintext

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model Tenant {
id String @id @default(uuid())
name String
slug String @unique
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
users User[]
ldapConfig LdapConfig?
}
enum Role {
SUPER_ADMIN
ADMIN
USER
}
model User {
id String @id @default(uuid())
username String @unique
email String @unique
passwordHash String?
displayName String?
role Role @default(USER)
isActive Boolean @default(true)
mustChangePassword Boolean @default(false)
ldapDn String?
tenantId String
tenant Tenant @relation(fields: [tenantId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
lastLoginAt DateTime?
passwordResetTokens PasswordResetToken[]
@@index([tenantId])
@@index([username])
@@index([email])
}
model PasswordResetToken {
id String @id @default(uuid())
token String @unique
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
expiresAt DateTime
usedAt DateTime?
createdAt DateTime @default(now())
}
model LdapConfig {
id String @id @default(uuid())
tenantId String @unique
tenant Tenant @relation(fields: [tenantId], references: [id])
serverUrl String
baseDn String
bindDn String
bindPassword String
searchFilter String @default("(objectClass=person)")
syncIntervalMin Int @default(60)
isActive Boolean @default(true)
lastSyncAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
fieldMappings LdapFieldMapping[]
}
model LdapFieldMapping {
id String @id @default(uuid())
ldapConfigId String
ldapConfig LdapConfig @relation(fields: [ldapConfigId], references: [id], onDelete: Cascade)
ldapField String
tesseraField String
isDefault Boolean @default(false)
createdAt DateTime @default(now())
@@unique([ldapConfigId, ldapField])
}
model Module {
id String @id @default(uuid())
slug String @unique
name String
version String
category String
description Json
icon String?
isSystem Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
activations TenantModuleActivation[]
}
model TenantModuleActivation {
id String @id @default(uuid())
tenantId String
moduleId String
isActive Boolean @default(true)
activatedAt DateTime @default(now())
module Module @relation(fields: [moduleId], references: [id], onDelete: Cascade)
@@unique([tenantId, moduleId])
@@index([tenantId])
}
model DashboardLayout {
id String @id @default(uuid())
userId String @unique
tenantId String
layouts Json @default("{}")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([tenantId])
}
model WidgetInstance {
id String @id @default(uuid())
userId String
tenantId String
widgetType String
config Json @default("{}")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([userId])
@@index([tenantId])
}
model SearchProvider {
id String @id @default(uuid())
userId String?
tenantId String?
name String
urlTemplate String
isDefault Boolean @default(false)
createdAt DateTime @default(now())
@@index([userId])
}