generator client { provider = "prisma-client-js" } datasource db { provider = "sqlite" url = env("DATABASE_URL") } model User { id String @id @default(cuid()) email String @unique passwordHash String displayName String? profileImageUrl String? role UserRole @default(USER) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt sessions Session[] favorites Favorite[] settings Settings? tabs DashboardTab[] widgets Widget[] notes NoteBoardItem[] calendarSources CalendarSource[] calendarWidgetSources CalendarWidgetSource[] } model Session { id String @id @default(cuid()) tokenHash String @unique userId String expiresAt DateTime createdAt DateTime @default(now()) user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@index([userId]) @@index([expiresAt]) } model DashboardTab { id String @id @default(cuid()) userId String title String @default("Dashboard") position Int @default(0) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) widgets Widget[] @@index([userId]) @@index([userId, position]) } model Favorite { id String @id @default(cuid()) userId String widgetId String? title String url String iconUrl String? position Int @default(0) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) widget Widget? @relation(fields: [widgetId], references: [id], onDelete: Cascade) @@index([userId]) @@index([widgetId]) @@index([userId, widgetId]) } model Settings { id String @id @default(cuid()) userId String @unique darkMode Boolean @default(false) calendarIcsUrl String? calendarMaxEvents Int @default(8) calendarLookaheadDays Int @default(60) dashboardTitle String @default("Personal Dashboard") dashboardSubtitle String? logoUrl String? @default("/logo.svg") faviconUrl String? @default("/favicon.ico") backgroundImageUrl String? backgroundImageOpacity Int @default(0) primaryColor String @default("#2563eb") secondaryColor String @default("#dbeafe") customCss String @default("") createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) } model Widget { id String @id @default(cuid()) userId String tabId String? type String title String position Int @default(0) x Int @default(0) y Int @default(0) w Int @default(4) h Int @default(4) opacity Int @default(100) viewMode String @default("list") fontSize Int @default(100) calendarNextEventsCount Int @default(3) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) tab DashboardTab? @relation(fields: [tabId], references: [id], onDelete: Cascade) favorites Favorite[] calendarWidgetSources CalendarWidgetSource[] @@index([userId]) @@index([tabId]) @@index([userId, tabId]) @@index([userId, position]) } model NoteBoardItem { id String @id @default(cuid()) userId String type String @default("note") title String content String @default("") x Int @default(0) y Int @default(0) w Int @default(3) h Int @default(3) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@index([userId]) } model CalendarSource { id String @id @default(cuid()) userId String widgetId String? type String @default("ICS") name String @default("Kalender") color String @default("#2563eb") nextEventsCount Int @default(3) icsUrl String? exchangeEwsUrl String? exchangeMailbox String? exchangeUsername String? exchangeDomain String? exchangePasswordEnc String? exchangePasswordIv String? exchangePasswordTag String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) widgetLinks CalendarWidgetSource[] @@index([userId]) @@index([widgetId]) } model CalendarWidgetSource { id String @id @default(cuid()) userId String widgetId String sourceId String position Int @default(0) createdAt DateTime @default(now()) user User @relation(fields: [userId], references: [id], onDelete: Cascade) widget Widget @relation(fields: [widgetId], references: [id], onDelete: Cascade) source CalendarSource @relation(fields: [sourceId], references: [id], onDelete: Cascade) @@unique([widgetId, sourceId]) @@index([userId]) @@index([widgetId]) @@index([sourceId]) } enum UserRole { ADMIN USER }