diff --git a/packages/db/prisma/migrations/20260504080000_add_ticket_comments_and_attachments/migration.sql b/packages/db/prisma/migrations/20260504080000_add_ticket_comments_and_attachments/migration.sql new file mode 100644 index 0000000..cd151cd --- /dev/null +++ b/packages/db/prisma/migrations/20260504080000_add_ticket_comments_and_attachments/migration.sql @@ -0,0 +1,38 @@ +-- CreateTable +CREATE TABLE "ticket_comments" ( + "id" TEXT NOT NULL, + "tenantId" TEXT NOT NULL, + "ticketId" TEXT NOT NULL, + "userId" TEXT NOT NULL, + "content" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "ticket_comments_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "ticket_attachments" ( + "id" TEXT NOT NULL, + "commentId" TEXT NOT NULL, + "fileName" TEXT NOT NULL, + "filePath" TEXT NOT NULL, + "fileType" TEXT NOT NULL, + "fileSize" INTEGER NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "ticket_attachments_pkey" PRIMARY KEY ("id") +); + +-- AlterTable: add ticketId to notifications +ALTER TABLE "notifications" ADD COLUMN "ticketId" TEXT; + +-- CreateIndex +CREATE INDEX "ticket_comments_ticketId_idx" ON "ticket_comments"("ticketId"); +CREATE INDEX "ticket_comments_tenantId_idx" ON "ticket_comments"("tenantId"); + +-- AddForeignKey +ALTER TABLE "ticket_comments" ADD CONSTRAINT "ticket_comments_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "tenants"("id") ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE "ticket_comments" ADD CONSTRAINT "ticket_comments_ticketId_fkey" FOREIGN KEY ("ticketId") REFERENCES "tickets"("id") ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE "ticket_comments" ADD CONSTRAINT "ticket_comments_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE; +ALTER TABLE "ticket_attachments" ADD CONSTRAINT "ticket_attachments_commentId_fkey" FOREIGN KEY ("commentId") REFERENCES "ticket_comments"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/packages/db/prisma/schema.prisma b/packages/db/prisma/schema.prisma index ee96249..d4b12a6 100644 --- a/packages/db/prisma/schema.prisma +++ b/packages/db/prisma/schema.prisma @@ -43,8 +43,7 @@ model User { password String firstName String lastName String - isActive Boolean @default(true) - mustChangePassword Boolean @default(false) + isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deletedAt DateTime? @@ -54,6 +53,7 @@ model User { tenantRoles UserTenantRole[] assignedTickets Ticket[] @relation("TicketAssignee") createdTickets Ticket[] @relation("TicketCreator") + authoredComments TicketComment[] @relation("CommentAuthor") payments Payment[] remittances Remittance[] @relation("RemittanceCollector") confirmedRemittances Remittance[] @relation("RemittanceConfirmer") @@ -201,8 +201,6 @@ model Client { phone String? address String areaId String? - latitude Float? - longitude Float? status String @default("active") // active, inactive, suspended createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@ -364,6 +362,7 @@ model Ticket { client Client? @relation(fields: [clientId], references: [id]) createdBy User @relation("TicketCreator", fields: [createdById], references: [id]) assignee User? @relation("TicketAssignee", fields: [assigneeId], references: [id]) + comments TicketComment[] @@index([tenantId]) @@index([tenantId, type, status]) @@ -386,6 +385,7 @@ model Notification { message String isRead Boolean @default(false) sentAt DateTime? + ticketId String? createdAt DateTime @default(now()) tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade) @@ -395,6 +395,41 @@ model Notification { @@map("notifications") } +// ─── Ticket Comments ────────────────────────────────────────────────── + +model TicketComment { + id String @id @default(uuid()) + tenantId String + ticketId String + userId String + content String + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade) + ticket Ticket @relation(fields: [ticketId], references: [id], onDelete: Cascade) + author User @relation("CommentAuthor", fields: [userId], references: [id]) + attachments TicketAttachment[] + + @@index([ticketId]) + @@index([tenantId]) + @@map("ticket_comments") +} + +model TicketAttachment { + id String @id @default(uuid()) + commentId String + fileName String + filePath String + fileType String + fileSize Int + createdAt DateTime @default(now()) + + comment TicketComment @relation(fields: [commentId], references: [id], onDelete: Cascade) + + @@map("ticket_attachments") +} + // ─── Audit Log (append-only, no soft delete) ──────────────────────── model AuditLog {