- Adiciona rota API para arquivar tickets por ID - Atualiza configuracao do Prisma para PostgreSQL - Simplifica workflow CI/CD - Adiciona src/generated ao gitignore - Atualiza documentacao e dependencias 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
477 lines
13 KiB
Text
477 lines
13 KiB
Text
generator client {
|
|
provider = "prisma-client"
|
|
output = "../src/generated/prisma"
|
|
runtime = "nodejs"
|
|
moduleFormat = "esm"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
}
|
|
|
|
enum UserRole {
|
|
ADMIN
|
|
MANAGER
|
|
AGENT
|
|
COLLABORATOR
|
|
}
|
|
|
|
enum TicketStatus {
|
|
PENDING
|
|
AWAITING_ATTENDANCE
|
|
PAUSED
|
|
RESOLVED
|
|
}
|
|
|
|
enum TicketPriority {
|
|
LOW
|
|
MEDIUM
|
|
HIGH
|
|
URGENT
|
|
}
|
|
|
|
enum TicketChannel {
|
|
EMAIL
|
|
WHATSAPP
|
|
CHAT
|
|
PHONE
|
|
API
|
|
MANUAL
|
|
}
|
|
|
|
enum CommentVisibility {
|
|
PUBLIC
|
|
INTERNAL
|
|
}
|
|
|
|
enum CompanyStateRegistrationType {
|
|
STANDARD
|
|
EXEMPT
|
|
SIMPLES
|
|
}
|
|
|
|
model Team {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
name String
|
|
description String?
|
|
members TeamMember[]
|
|
queues Queue[]
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([tenantId, name])
|
|
}
|
|
|
|
model TeamMember {
|
|
teamId String
|
|
userId String
|
|
isLead Boolean @default(false)
|
|
assignedAt DateTime @default(now())
|
|
|
|
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@id([teamId, userId])
|
|
}
|
|
|
|
model Company {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
name String
|
|
slug String
|
|
provisioningCode String @unique
|
|
isAvulso Boolean @default(false)
|
|
contractedHoursPerMonth Float?
|
|
cnpj String?
|
|
domain String?
|
|
phone String?
|
|
description String?
|
|
address String?
|
|
legalName String?
|
|
tradeName String?
|
|
stateRegistration String?
|
|
stateRegistrationType CompanyStateRegistrationType?
|
|
primaryCnae String?
|
|
timezone String?
|
|
businessHours Json?
|
|
supportEmail String?
|
|
billingEmail String?
|
|
contactPreferences Json?
|
|
clientDomains Json?
|
|
communicationChannels Json?
|
|
fiscalAddress Json?
|
|
hasBranches Boolean @default(false)
|
|
regulatedEnvironments Json?
|
|
privacyPolicyAccepted Boolean @default(false)
|
|
privacyPolicyReference String?
|
|
privacyPolicyMetadata Json?
|
|
contacts Json?
|
|
locations Json?
|
|
contracts Json?
|
|
sla Json?
|
|
tags Json?
|
|
customFields Json?
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
users User[]
|
|
tickets Ticket[]
|
|
|
|
@@unique([tenantId, slug])
|
|
@@index([tenantId, name])
|
|
}
|
|
|
|
model User {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
name String
|
|
email String @unique
|
|
role UserRole
|
|
jobTitle String?
|
|
managerId String?
|
|
timezone String @default("America/Sao_Paulo")
|
|
avatarUrl String?
|
|
companyId String?
|
|
teams TeamMember[]
|
|
requestedTickets Ticket[] @relation("TicketRequester")
|
|
assignedTickets Ticket[] @relation("TicketAssignee")
|
|
comments TicketComment[]
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
manager User? @relation("UserManager", fields: [managerId], references: [id])
|
|
reports User[] @relation("UserManager")
|
|
company Company? @relation(fields: [companyId], references: [id])
|
|
|
|
// Relações do sistema de notificações
|
|
ticketRatings TicketRating[]
|
|
ticketAccessTokens TicketAccessToken[]
|
|
notificationPreferences NotificationPreferences?
|
|
|
|
@@index([tenantId, role])
|
|
@@index([tenantId, companyId])
|
|
@@index([tenantId, managerId])
|
|
}
|
|
|
|
model Queue {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
name String
|
|
slug String
|
|
teamId String?
|
|
tickets Ticket[]
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
team Team? @relation(fields: [teamId], references: [id])
|
|
|
|
@@unique([tenantId, slug])
|
|
}
|
|
|
|
model Ticket {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
reference Int @default(0)
|
|
subject String
|
|
summary String?
|
|
status TicketStatus @default(PENDING)
|
|
priority TicketPriority @default(MEDIUM)
|
|
channel TicketChannel @default(EMAIL)
|
|
queueId String?
|
|
requesterId String
|
|
assigneeId String?
|
|
slaPolicyId String?
|
|
companyId String?
|
|
slaSnapshot Json?
|
|
slaResponseDueAt DateTime?
|
|
slaSolutionDueAt DateTime?
|
|
slaResponseStatus String?
|
|
slaSolutionStatus String?
|
|
slaPausedAt DateTime?
|
|
slaPausedBy String?
|
|
slaPausedMs Int?
|
|
dueAt DateTime?
|
|
firstResponseAt DateTime?
|
|
resolvedAt DateTime?
|
|
closedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
requester User @relation("TicketRequester", fields: [requesterId], references: [id])
|
|
assignee User? @relation("TicketAssignee", fields: [assigneeId], references: [id])
|
|
queue Queue? @relation(fields: [queueId], references: [id])
|
|
slaPolicy SlaPolicy? @relation(fields: [slaPolicyId], references: [id])
|
|
company Company? @relation(fields: [companyId], references: [id])
|
|
events TicketEvent[]
|
|
comments TicketComment[]
|
|
|
|
// Relações do sistema de notificações
|
|
rating TicketRating?
|
|
accessTokens TicketAccessToken[]
|
|
|
|
@@index([tenantId, status])
|
|
@@index([tenantId, queueId])
|
|
@@index([tenantId, assigneeId])
|
|
@@index([tenantId, companyId])
|
|
}
|
|
|
|
model ReportExportSchedule {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
name String
|
|
reportKeys Json
|
|
range String @default("30d")
|
|
companyId String?
|
|
companyName String?
|
|
format String @default("xlsx")
|
|
frequency String
|
|
dayOfWeek Int?
|
|
dayOfMonth Int?
|
|
hour Int @default(8)
|
|
minute Int @default(0)
|
|
timezone String @default("America/Sao_Paulo")
|
|
recipients Json
|
|
status String @default("ACTIVE")
|
|
lastRunAt DateTime?
|
|
nextRunAt DateTime?
|
|
createdBy String
|
|
updatedBy String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
runs ReportExportRun[]
|
|
|
|
@@index([tenantId, status])
|
|
@@index([tenantId, nextRunAt])
|
|
}
|
|
|
|
model ReportExportRun {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
scheduleId String
|
|
status String @default("PENDING")
|
|
startedAt DateTime @default(now())
|
|
completedAt DateTime?
|
|
error String?
|
|
artifacts Json?
|
|
|
|
schedule ReportExportSchedule @relation(fields: [scheduleId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([tenantId, status])
|
|
@@index([tenantId, scheduleId])
|
|
}
|
|
|
|
model TicketEvent {
|
|
id String @id @default(cuid())
|
|
ticketId String
|
|
type String
|
|
payload Json
|
|
createdAt DateTime @default(now())
|
|
|
|
ticket Ticket @relation(fields: [ticketId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([ticketId, createdAt])
|
|
}
|
|
|
|
model TicketComment {
|
|
id String @id @default(cuid())
|
|
ticketId String
|
|
authorId String
|
|
visibility CommentVisibility @default(INTERNAL)
|
|
body String
|
|
attachments Json?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
ticket Ticket @relation(fields: [ticketId], references: [id], onDelete: Cascade)
|
|
author User @relation(fields: [authorId], references: [id])
|
|
|
|
@@index([ticketId, visibility])
|
|
}
|
|
|
|
model SlaPolicy {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
name String
|
|
description String?
|
|
timeToFirstResponse Int?
|
|
timeToResolution Int?
|
|
calendar Json?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tickets Ticket[]
|
|
|
|
@@unique([tenantId, name])
|
|
}
|
|
|
|
model AuthUser {
|
|
id String @id @default(cuid())
|
|
name String?
|
|
email String @unique
|
|
emailVerified Boolean @default(false)
|
|
image String?
|
|
role String @default("agent")
|
|
tenantId String?
|
|
avatarUrl String?
|
|
machinePersona String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
sessions AuthSession[]
|
|
accounts AuthAccount[]
|
|
}
|
|
|
|
model AuthSession {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
token String @unique
|
|
expiresAt DateTime
|
|
ipAddress String?
|
|
userAgent String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
user AuthUser @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([userId])
|
|
@@index([token])
|
|
}
|
|
|
|
model AuthAccount {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
accountId String
|
|
providerId String
|
|
accessToken String?
|
|
refreshToken String?
|
|
accessTokenExpiresAt DateTime?
|
|
refreshTokenExpiresAt DateTime?
|
|
scope String?
|
|
idToken String?
|
|
password String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
user AuthUser @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([providerId, accountId])
|
|
@@index([userId])
|
|
}
|
|
|
|
model AuthInvite {
|
|
id String @id @default(cuid())
|
|
email String
|
|
name String?
|
|
role String @default("agent")
|
|
tenantId String
|
|
token String @unique
|
|
status String @default("pending")
|
|
expiresAt DateTime
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
createdById String?
|
|
acceptedAt DateTime?
|
|
acceptedById String?
|
|
revokedAt DateTime?
|
|
revokedById String?
|
|
revokedReason String?
|
|
|
|
events AuthInviteEvent[]
|
|
|
|
@@index([tenantId, status])
|
|
@@index([tenantId, email])
|
|
}
|
|
|
|
model AuthInviteEvent {
|
|
id String @id @default(cuid())
|
|
inviteId String
|
|
type String
|
|
payload Json?
|
|
actorId String?
|
|
createdAt DateTime @default(now())
|
|
|
|
invite AuthInvite @relation(fields: [inviteId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([inviteId, createdAt])
|
|
}
|
|
|
|
model AuthVerification {
|
|
id String @id @default(cuid())
|
|
identifier String
|
|
value String
|
|
expiresAt DateTime
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([identifier])
|
|
}
|
|
|
|
// ============================================
|
|
// Sistema de Notificações por E-mail
|
|
// ============================================
|
|
|
|
model TicketRating {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
ticketId String @unique
|
|
userId String
|
|
rating Int // 1-5 estrelas
|
|
comment String? // Feedback opcional do usuário
|
|
createdAt DateTime @default(now())
|
|
|
|
ticket Ticket @relation(fields: [ticketId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id])
|
|
|
|
@@index([tenantId, rating])
|
|
@@index([tenantId, createdAt])
|
|
}
|
|
|
|
model TicketAccessToken {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
token String @unique
|
|
ticketId String
|
|
userId String
|
|
machineId String? // Máquina esperada (opcional)
|
|
scope String @default("view") // view, interact, rate
|
|
expiresAt DateTime
|
|
usedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
|
|
ticket Ticket @relation(fields: [ticketId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id])
|
|
|
|
@@index([tenantId, ticketId])
|
|
@@index([tenantId, userId])
|
|
@@index([expiresAt])
|
|
}
|
|
|
|
model NotificationPreferences {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
userId String @unique
|
|
|
|
// Preferências globais
|
|
emailEnabled Boolean @default(true)
|
|
quietHoursStart String? // "22:00"
|
|
quietHoursEnd String? // "08:00"
|
|
timezone String @default("America/Sao_Paulo")
|
|
digestFrequency String @default("immediate") // immediate, daily, weekly
|
|
|
|
// Preferências por tipo de notificação (JSON)
|
|
// Ex: { "ticket_created": true, "ticket_resolved": true, "comment_public": false }
|
|
typePreferences String @default("{}")
|
|
|
|
// Preferências por categoria de ticket (JSON)
|
|
// Ex: { "category_id_1": true, "category_id_2": false }
|
|
categoryPreferences String @default("{}")
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([tenantId])
|
|
}
|