generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } enum Role { ADMIN AGENT USER } enum TicketStatus { OPEN IN_PROGRESS RESOLVED CLOSED } model User { id String @id @default(cuid()) username String @unique email String @unique passwordHash String displayName String role Role @default(AGENT) apiKey String? @unique notificationPrefs Json? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt assignedTickets Ticket[] @relation("AssignedTickets") createdTickets Ticket[] @relation("CreatedTickets") comments Comment[] auditLogs AuditLog[] attachments Attachment[] notifications Notification[] savedViews SavedView[] } model Category { id String @id @default(cuid()) name String @unique types Type[] tickets Ticket[] } model Type { id String @id @default(cuid()) name String categoryId String category Category @relation(fields: [categoryId], references: [id], onDelete: Cascade) items Item[] tickets Ticket[] @@unique([categoryId, name]) } model Item { id String @id @default(cuid()) name String typeId String type Type @relation(fields: [typeId], references: [id], onDelete: Cascade) tickets Ticket[] @@unique([typeId, name]) } model Ticket { id String @id @default(cuid()) displayId String @unique @default(dbgenerated("concat('V', (floor(random() * 900000000) + 100000000)::bigint::text)")) title String overview String severity Int status TicketStatus @default(OPEN) categoryId String typeId String itemId String assigneeId String? createdById String resolvedAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt category Category @relation(fields: [categoryId], references: [id]) type Type @relation(fields: [typeId], references: [id]) item Item @relation(fields: [itemId], references: [id]) assignee User? @relation("AssignedTickets", fields: [assigneeId], references: [id]) createdBy User @relation("CreatedTickets", fields: [createdById], references: [id]) comments Comment[] auditLogs AuditLog[] attachments Attachment[] notifications Notification[] @@index([status]) @@index([severity]) @@index([assigneeId]) @@index([createdById]) @@index([createdAt]) } model Comment { id String @id @default(cuid()) body String ticketId String authorId String createdAt DateTime @default(now()) ticket Ticket @relation(fields: [ticketId], references: [id], onDelete: Cascade) author User @relation(fields: [authorId], references: [id]) attachments Attachment[] notifications Notification[] @@index([ticketId]) } model Attachment { id String @id @default(cuid()) filename String mimetype String size Int storagePath String ticketId String? commentId String? uploadedById String createdAt DateTime @default(now()) ticket Ticket? @relation(fields: [ticketId], references: [id], onDelete: Cascade) comment Comment? @relation(fields: [commentId], references: [id], onDelete: Cascade) uploadedBy User @relation(fields: [uploadedById], references: [id]) @@index([ticketId]) @@index([commentId]) } model Webhook { id String @id @default(cuid()) name String url String events String[] secret String active Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model Notification { id String @id @default(cuid()) userId String kind String ticketId String? commentId String? data Json? readAt DateTime? createdAt DateTime @default(now()) user User @relation(fields: [userId], references: [id], onDelete: Cascade) ticket Ticket? @relation(fields: [ticketId], references: [id], onDelete: Cascade) comment Comment? @relation(fields: [commentId], references: [id], onDelete: Cascade) @@index([userId, readAt]) @@index([userId, createdAt]) } model SavedView { id String @id @default(cuid()) userId String name String filters Json createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@unique([userId, name]) } model AuditLog { id String @id @default(cuid()) ticketId String userId String action String detail String? createdAt DateTime @default(now()) ticket Ticket @relation(fields: [ticketId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id]) }