import { z } from "zod" export const ticketStatusSchema = z.enum([ "PENDING", "AWAITING_ATTENDANCE", "PAUSED", "RESOLVED", ]) export type TicketStatus = z.infer const slaStatusSchema = z.enum(["pending", "met", "breached", "n/a"]) const slaTimeModeSchema = z.enum(["business", "calendar"]) export const ticketSlaSnapshotSchema = z.object({ categoryId: z.string().optional(), categoryName: z.string().optional(), priority: z.string(), responseTargetMinutes: z.number().nullable().optional(), responseMode: slaTimeModeSchema.optional(), solutionTargetMinutes: z.number().nullable().optional(), solutionMode: slaTimeModeSchema.optional(), alertThreshold: z.number().optional(), pauseStatuses: z.array(z.string()).default([]), }) export type TicketSlaSnapshot = z.infer export const ticketPrioritySchema = z.enum(["LOW", "MEDIUM", "HIGH", "URGENT"]) export type TicketPriority = z.infer export const ticketChannelSchema = z.enum([ "EMAIL", "WHATSAPP", "CHAT", "PHONE", "API", "MANUAL", ]) export type TicketChannel = z.infer export const commentVisibilitySchema = z.enum(["PUBLIC", "INTERNAL"]) export type CommentVisibility = z.infer export const userSummarySchema = z.object({ id: z.string(), name: z.string(), email: z.string().email(), avatarUrl: z.string().url().optional(), teams: z.array(z.string()).default([]), }) export type UserSummary = z.infer export const ticketCompanySummarySchema = z.object({ id: z.string(), name: z.string(), isAvulso: z.boolean().optional(), }) export type TicketCompanySummary = z.infer export const ticketMachineSummarySchema = z.object({ id: z.string().nullable(), hostname: z.string().nullable().optional(), persona: z.string().nullable().optional(), assignedUserName: z.string().nullable().optional(), assignedUserEmail: z.string().nullable().optional(), status: z.string().nullable().optional(), }) export type TicketMachineSummary = z.infer export const ticketCategorySummarySchema = z.object({ id: z.string(), name: z.string(), }) export type TicketCategorySummary = z.infer export const ticketSubcategorySummarySchema = z.object({ id: z.string(), name: z.string(), categoryId: z.string().optional(), }) export type TicketSubcategorySummary = z.infer export const ticketAgentWorkTotalSchema = z.object({ agentId: z.string(), agentName: z.string().nullable().optional(), agentEmail: z.string().nullable().optional(), avatarUrl: z.string().nullable().optional(), totalWorkedMs: z.number(), internalWorkedMs: z.number().optional().default(0), externalWorkedMs: z.number().optional().default(0), }) export type TicketAgentWorkTotal = z.infer export const ticketCommentSchema = z.object({ id: z.string(), author: userSummarySchema, visibility: commentVisibilitySchema, body: z.string(), attachments: z .array( z.object({ id: z.string(), name: z.string(), size: z.number().optional(), type: z.string().optional(), url: z.string().url().optional(), }) ) .default([]), createdAt: z.coerce.date(), updatedAt: z.coerce.date(), }) export type TicketComment = z.infer export const ticketEventSchema = z.object({ id: z.string(), type: z.string(), payload: z.record(z.string(), z.any()).optional(), createdAt: z.coerce.date(), }) export type TicketEvent = z.infer export const ticketFieldTypeSchema = z.enum(["text", "number", "select", "date", "boolean"]) export type TicketFieldType = z.infer export const ticketCustomFieldValueSchema = z.object({ label: z.string(), type: ticketFieldTypeSchema, value: z.union([z.string(), z.number(), z.boolean(), z.coerce.date()]).optional(), displayValue: z.string().optional(), }) export type TicketCustomFieldValue = z.infer export const ticketSchema = z.object({ id: z.string(), reference: z.number(), tenantId: z.string(), subject: z.string(), summary: z.string().optional(), status: ticketStatusSchema, priority: ticketPrioritySchema, channel: ticketChannelSchema, queue: z.string().nullable(), requester: userSummarySchema, assignee: userSummarySchema.nullable(), company: ticketCompanySummarySchema.optional().nullable(), machine: ticketMachineSummarySchema.nullable().optional(), slaPolicy: z .object({ id: z.string(), name: z.string(), targetMinutesToFirstResponse: z.number().nullable(), targetMinutesToResolution: z.number().nullable(), }) .nullable(), slaSnapshot: ticketSlaSnapshotSchema.nullable().optional(), slaResponseDueAt: z.coerce.date().nullable().optional(), slaSolutionDueAt: z.coerce.date().nullable().optional(), slaResponseStatus: slaStatusSchema.nullable().optional(), slaSolutionStatus: slaStatusSchema.nullable().optional(), slaPausedAt: z.coerce.date().nullable().optional(), slaPausedBy: z.string().nullable().optional(), slaPausedMs: z.number().nullable().optional(), dueAt: z.coerce.date().nullable(), firstResponseAt: z.coerce.date().nullable(), resolvedAt: z.coerce.date().nullable(), closedAt: z.coerce.date().nullable().optional(), updatedAt: z.coerce.date(), createdAt: z.coerce.date(), tags: z.array(z.string()).default([]), lastTimelineEntry: z.string().nullable().optional(), metrics: z .object({ timeWaitingMinutes: z.number().nullable(), timeOpenedMinutes: z.number().nullable(), }) .nullable(), relatedTicketIds: z.array(z.string()).optional(), resolvedWithTicketId: z.string().nullable().optional(), reopenDeadline: z.number().nullable().optional(), reopenWindowDays: z.number().nullable().optional(), reopenedAt: z.number().nullable().optional(), reopenedBy: z.string().nullable().optional(), chatEnabled: z.boolean().optional(), formTemplate: z.string().nullable().optional(), formTemplateLabel: z.string().nullable().optional(), csatScore: z.number().nullable().optional(), csatMaxScore: z.number().nullable().optional(), csatComment: z.string().nullable().optional(), csatRatedAt: z.coerce.date().nullable().optional(), csatRatedBy: z.string().nullable().optional(), category: ticketCategorySummarySchema.nullable().optional(), subcategory: ticketSubcategorySummarySchema.nullable().optional(), workSummary: z .object({ totalWorkedMs: z.number(), internalWorkedMs: z.number().optional().default(0), externalWorkedMs: z.number().optional().default(0), serverNow: z.number().optional(), activeSession: z .object({ id: z.string(), agentId: z.string(), startedAt: z.coerce.date(), workType: z.string().optional(), }) .nullable(), perAgentTotals: z.array(ticketAgentWorkTotalSchema).optional(), }) .nullable() .optional(), }) export type Ticket = z.infer export const ticketWithDetailsSchema = ticketSchema.extend({ description: z.string().optional(), customFields: z.record(z.string(), ticketCustomFieldValueSchema).optional(), timeline: z.array(ticketEventSchema), comments: z.array(ticketCommentSchema), }) export type TicketWithDetails = z.infer export const ticketQueueSummarySchema = z.object({ id: z.string(), name: z.string(), pending: z.number(), inProgress: z.number(), paused: z.number(), breached: z.number(), }) export type TicketQueueSummary = z.infer export const ticketPlayContextSchema = z.object({ queue: ticketQueueSummarySchema, nextTicket: ticketSchema.nullable(), }) export type TicketPlayContext = z.infer