sistema-de-chamados/web/src/lib/schemas/ticket.ts

164 lines
4.8 KiB
TypeScript

import { z } from "zod"
export const ticketStatusSchema = z.enum([
"NEW",
"OPEN",
"PENDING",
"ON_HOLD",
"RESOLVED",
"CLOSED",
])
export type TicketStatus = z.infer<typeof ticketStatusSchema>
export const ticketPrioritySchema = z.enum(["LOW", "MEDIUM", "HIGH", "URGENT"])
export type TicketPriority = z.infer<typeof ticketPrioritySchema>
export const ticketChannelSchema = z.enum([
"EMAIL",
"WHATSAPP",
"CHAT",
"PHONE",
"API",
"MANUAL",
])
export type TicketChannel = z.infer<typeof ticketChannelSchema>
export const commentVisibilitySchema = z.enum(["PUBLIC", "INTERNAL"])
export type CommentVisibility = z.infer<typeof commentVisibilitySchema>
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<typeof userSummarySchema>
export const ticketCategorySummarySchema = z.object({
id: z.string(),
name: z.string(),
})
export type TicketCategorySummary = z.infer<typeof ticketCategorySummarySchema>
export const ticketSubcategorySummarySchema = z.object({
id: z.string(),
name: z.string(),
categoryId: z.string().optional(),
})
export type TicketSubcategorySummary = z.infer<typeof ticketSubcategorySummarySchema>
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<typeof ticketCommentSchema>
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<typeof ticketEventSchema>
export const ticketFieldTypeSchema = z.enum(["text", "number", "select", "date", "boolean"])
export type TicketFieldType = z.infer<typeof ticketFieldTypeSchema>
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<typeof ticketCustomFieldValueSchema>
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(),
slaPolicy: z
.object({
id: z.string(),
name: z.string(),
targetMinutesToFirstResponse: z.number().nullable(),
targetMinutesToResolution: z.number().nullable(),
})
.nullable(),
dueAt: z.coerce.date().nullable(),
firstResponseAt: z.coerce.date().nullable(),
resolvedAt: z.coerce.date().nullable(),
updatedAt: z.coerce.date(),
createdAt: z.coerce.date(),
tags: z.array(z.string()).default([]),
lastTimelineEntry: z.string().optional(),
metrics: z
.object({
timeWaitingMinutes: z.number().nullable(),
timeOpenedMinutes: z.number().nullable(),
})
.nullable(),
category: ticketCategorySummarySchema.nullable().optional(),
subcategory: ticketSubcategorySummarySchema.nullable().optional(),
workSummary: z
.object({
totalWorkedMs: z.number(),
activeSession: z
.object({
id: z.string(),
agentId: z.string(),
startedAt: z.coerce.date(),
})
.nullable(),
})
.nullable()
.optional(),
})
export type Ticket = z.infer<typeof ticketSchema>
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<typeof ticketWithDetailsSchema>
export const ticketQueueSummarySchema = z.object({
id: z.string(),
name: z.string(),
pending: z.number(),
waiting: z.number(),
breached: z.number(),
})
export type TicketQueueSummary = z.infer<typeof ticketQueueSummarySchema>
export const ticketPlayContextSchema = z.object({
queue: ticketQueueSummarySchema,
nextTicket: ticketSchema.nullable(),
})
export type TicketPlayContext = z.infer<typeof ticketPlayContextSchema>