184 lines
6.9 KiB
Plaintext
184 lines
6.9 KiB
Plaintext
// 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")
|
|
} |