feat: integrate Prisma for database management
This commit is contained in:
184
prisma/schema.prisma
Normal file
184
prisma/schema.prisma
Normal file
@@ -0,0 +1,184 @@
|
||||
// This is your Prisma schema file,
|
||||
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
||||
|
||||
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
|
||||
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
|
||||
|
||||
generator client {
|
||||
provider = "prisma-client"
|
||||
output = "../generated/prisma"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
}
|
||||
|
||||
model Category {
|
||||
id BigInt @id @default(autoincrement())
|
||||
name String @unique @db.VarChar(100)
|
||||
description String?
|
||||
|
||||
tickets Ticket[]
|
||||
|
||||
@@map("categories")
|
||||
}
|
||||
|
||||
model Role {
|
||||
id BigInt @id @default(autoincrement())
|
||||
name String @unique @db.VarChar(50)
|
||||
description String?
|
||||
|
||||
users User[]
|
||||
|
||||
@@map("roles")
|
||||
}
|
||||
|
||||
model User {
|
||||
id BigInt @id @default(autoincrement())
|
||||
external_uid String @unique @db.VarChar(255)
|
||||
role_id BigInt
|
||||
is_active Boolean @default(true)
|
||||
created_at DateTime @default(now()) @db.Timestamptz
|
||||
|
||||
role Role @relation(fields: [role_id], references: [id])
|
||||
tickets_created Ticket[] @relation("CreatedBy")
|
||||
tickets_assigned Ticket[] @relation("AssignedTo")
|
||||
messages TicketMessage[]
|
||||
attachments_uploaded TicketAttachment[]
|
||||
invitations_sent TicketInvitation[] @relation("Inviter")
|
||||
invitations_received TicketInvitation[] @relation("Invitee")
|
||||
participants TicketParticipant[] @relation("Participant")
|
||||
participants_added TicketParticipant[] @relation("AddedBy")
|
||||
status_history_changed TicketStatusHistory[]
|
||||
|
||||
@@index([external_uid], name: "idx_users_external_uid")
|
||||
@@map("users")
|
||||
}
|
||||
|
||||
model Ticket {
|
||||
id BigInt @id @default(autoincrement())
|
||||
title String @db.VarChar(255)
|
||||
description String?
|
||||
status String @db.VarChar(30)
|
||||
priority String? @db.VarChar(30)
|
||||
category_id BigInt?
|
||||
created_by_user_id BigInt
|
||||
assigned_to_user_id BigInt?
|
||||
created_at DateTime @default(now()) @db.Timestamptz
|
||||
updated_at DateTime @default(now()) @db.Timestamptz
|
||||
closed_at DateTime? @db.Timestamptz
|
||||
/// Número de ticket legible para usuarios y APIs públicas (formato: TCK-YYYY-NNNNN). Este identificador se usa en lugar del ID interno en todas las comunicaciones externas.
|
||||
ticket_number String @unique @db.VarChar(30)
|
||||
|
||||
category Category? @relation(fields: [category_id], references: [id])
|
||||
created_by User @relation("CreatedBy", fields: [created_by_user_id], references: [id])
|
||||
assigned_to User? @relation("AssignedTo", fields: [assigned_to_user_id], references: [id])
|
||||
messages TicketMessage[]
|
||||
attachments TicketAttachment[]
|
||||
invitations TicketInvitation[]
|
||||
participants TicketParticipant[]
|
||||
status_history TicketStatusHistory[]
|
||||
|
||||
@@index([assigned_to_user_id], name: "idx_tickets_assigned_to")
|
||||
@@index([created_at], name: "idx_tickets_created_at")
|
||||
@@index([created_by_user_id], name: "idx_tickets_created_by")
|
||||
@@index([status], name: "idx_tickets_status")
|
||||
@@index([ticket_number], name: "idx_tickets_ticket_number")
|
||||
@@map("tickets")
|
||||
}
|
||||
|
||||
model TicketMessage {
|
||||
id BigInt @id @default(autoincrement())
|
||||
ticket_id BigInt
|
||||
author_id BigInt
|
||||
message String
|
||||
is_internal Boolean @default(false)
|
||||
created_at DateTime @default(now()) @db.Timestamptz
|
||||
|
||||
ticket Ticket @relation(fields: [ticket_id], references: [id], onDelete: Cascade)
|
||||
author User @relation(fields: [author_id], references: [id])
|
||||
attachments TicketAttachment[]
|
||||
|
||||
@@index([ticket_id], name: "idx_messages_ticket_id")
|
||||
@@map("ticket_messages")
|
||||
}
|
||||
|
||||
model TicketAttachment {
|
||||
id BigInt @id @default(autoincrement())
|
||||
ticket_id BigInt
|
||||
message_id BigInt?
|
||||
uploaded_by BigInt
|
||||
file_name String? @db.VarChar(255)
|
||||
file_url String
|
||||
file_size BigInt?
|
||||
created_at DateTime @default(now()) @db.Timestamptz
|
||||
|
||||
ticket Ticket @relation(fields: [ticket_id], references: [id], onDelete: Cascade)
|
||||
message TicketMessage? @relation(fields: [message_id], references: [id])
|
||||
uploader User @relation(fields: [uploaded_by], references: [id])
|
||||
|
||||
@@map("ticket_attachments")
|
||||
}
|
||||
|
||||
/// Invitaciones pendientes, aceptadas o rechazadas para unirse a un ticket
|
||||
model TicketInvitation {
|
||||
id BigInt @id @default(autoincrement())
|
||||
ticket_id BigInt
|
||||
inviter_id BigInt
|
||||
invitee_id BigInt
|
||||
/// Estado de la invitación: pending, accepted, rejected, cancelled
|
||||
status String @default("pending") @db.VarChar(20)
|
||||
message String?
|
||||
created_at DateTime @default(now()) @db.Timestamptz
|
||||
responded_at DateTime? @db.Timestamptz
|
||||
|
||||
ticket Ticket @relation(fields: [ticket_id], references: [id], onDelete: Cascade)
|
||||
inviter User @relation("Inviter", fields: [inviter_id], references: [id])
|
||||
invitee User @relation("Invitee", fields: [invitee_id], references: [id])
|
||||
|
||||
@@unique([ticket_id, invitee_id, status], name: "unique_pending_invitation")
|
||||
@@index([created_at], name: "idx_invitations_created_at")
|
||||
@@index([invitee_id], name: "idx_invitations_invitee_id")
|
||||
@@index([inviter_id], name: "idx_invitations_inviter_id")
|
||||
@@index([status], name: "idx_invitations_status")
|
||||
@@index([ticket_id], name: "idx_invitations_ticket_id")
|
||||
@@map("ticket_invitations")
|
||||
}
|
||||
|
||||
/// Usuarios que tienen acceso a un ticket específico
|
||||
model TicketParticipant {
|
||||
id BigInt @id @default(autoincrement())
|
||||
ticket_id BigInt
|
||||
user_id BigInt
|
||||
added_by BigInt
|
||||
/// Método de adición: creator, invitation, direct_add, assignment, staff_access
|
||||
added_via String @db.VarChar(20)
|
||||
can_edit Boolean @default(false)
|
||||
can_comment Boolean @default(true)
|
||||
joined_at DateTime @default(now()) @db.Timestamptz
|
||||
|
||||
ticket Ticket @relation(fields: [ticket_id], references: [id], onDelete: Cascade)
|
||||
user User @relation("Participant", fields: [user_id], references: [id])
|
||||
added_by_user User @relation("AddedBy", fields: [added_by], references: [id])
|
||||
|
||||
@@unique([ticket_id, user_id])
|
||||
@@index([added_by], name: "idx_participants_added_by")
|
||||
@@index([ticket_id], name: "idx_participants_ticket_id")
|
||||
@@index([user_id], name: "idx_participants_user_id")
|
||||
@@map("ticket_participants")
|
||||
}
|
||||
|
||||
model TicketStatusHistory {
|
||||
id BigInt @id @default(autoincrement())
|
||||
ticket_id BigInt
|
||||
old_status String? @db.VarChar(30)
|
||||
new_status String @db.VarChar(30)
|
||||
changed_by BigInt
|
||||
changed_at DateTime @default(now()) @db.Timestamptz
|
||||
|
||||
ticket Ticket @relation(fields: [ticket_id], references: [id], onDelete: Cascade)
|
||||
changed_by_user User @relation(fields: [changed_by], references: [id])
|
||||
|
||||
@@index([ticket_id], name: "idx_history_ticket_id")
|
||||
@@map("ticket_status_history")
|
||||
}
|
||||
Reference in New Issue
Block a user