feat(05-03): TicketComment model and portal ticket service

- Add TicketComment model for conversation threads (append-only)
- Add paymentInstructions field to TenantSettings
- Add ticketComments relation to User model
- Create portal-ticket-service with ensurePortalUser shadow User pattern
- Implements createPortalTicket, listPortalTickets, getPortalTicket, addTicketComment
- Portal ticket creation delegates to existing createTicket with source=SUBSCRIBER

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
kevin-asprec
2026-03-05 17:33:13 +08:00
parent ab1e94480e
commit 2d5b9ca2aa
2 changed files with 308 additions and 0 deletions

View File

@@ -272,6 +272,8 @@ model TenantSettings {
autoSuspendDays Int @default(30)
/// Days before billing date to generate prepaid invoices (default 7)
prepaidLeadDays Int @default(7)
/// Freeform payment instructions shown on the portal "pay online" page (e.g., GCash, bank details)
paymentInstructions String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -448,6 +450,8 @@ model User {
createdExpenses Expense[] @relation("ExpenseCreatedBy")
/// Expenses approved by this user
approvedExpenses Expense[] @relation("ExpenseApprovedBy")
/// Ticket comments authored by this user
ticketComments TicketComment[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -695,6 +699,27 @@ model Ticket {
@@index([subscriberId])
jobOrders JobOrder[]
comments TicketComment[]
}
/// A TicketComment is a message in a ticket conversation thread.
/// Subscribers and staff can both add comments to open tickets.
/// Comments are append-only — no edits or deletes.
model TicketComment {
id String @id @default(uuid())
tenantId String
ticketId String
ticket Ticket @relation(fields: [ticketId], references: [id])
/// Who posted this comment — can be subscriber (CLIENT) or staff
authorId String
author User @relation(fields: [authorId], references: [id])
/// For portal comments, link to the subscriber directly
subscriberId String?
message String
createdAt DateTime @default(now())
@@index([tenantId])
@@index([ticketId])
}
/// A Collection records cash received from a subscriber by a field collector.