/** * interactions.schema.ts * * Schemas Zod para o módulo de interações: * - Atualização de status de um ticket * - Atribuição de agente * - Adição de comentários / notas internas */ import { z } from 'zod'; import { TICKET_STATUSES, TICKET_PRIORITIES } from '@/db/schema.js'; // ─── Parâmetros de rota compartilhados ─────────────────────────────────────── export const ticketIdParamsSchema = z.object({ ticketId: z.coerce.number().int().positive(), }); export const commentIdParamsSchema = z.object({ ticketId: z.coerce.number().int().positive(), commentId: z.coerce.number().int().positive(), }); export type TicketIdParams = z.infer; export type CommentIdParams = z.infer; // ─── Atualização de status ──────────────────────────────────────────────────── export const updateTicketStatusBodySchema = z.object({ status: z.enum(TICKET_STATUSES, { errorMap: () => ({ message: `Status deve ser um de: ${TICKET_STATUSES.join(', ')}`, }), }), // Motivo da mudança — obrigatório ao fechar ou resolver um chamado reason: z.string().trim().max(500).optional(), }); export type UpdateTicketStatusBody = z.infer; // ─── Atribuição de agente ───────────────────────────────────────────────────── export const assignTicketBodySchema = z.object({ assigneeId: z .number({ required_error: 'assigneeId é obrigatório' }) .int() .positive(), }); export type AssignTicketBody = z.infer; // ─── Atualização de prioridade ──────────────────────────────────────────────── export const updateTicketPriorityBodySchema = z.object({ priority: z.enum(TICKET_PRIORITIES, { errorMap: () => ({ message: `Prioridade deve ser uma de: ${TICKET_PRIORITIES.join(', ')}`, }), }), }); export type UpdateTicketPriorityBody = z.infer; // ─── Adição de comentário / nota interna ───────────────────────────────────── export const addCommentBodySchema = z.object({ content: z .string({ required_error: 'Conteúdo é obrigatório' }) .min(1, 'Comentário não pode ser vazio') .max(5000, 'Comentário muito longo') .trim(), /** * true → nota interna (só agentes/admins veem) * false → resposta pública (solicitante recebe notificação) */ isInternal: z.boolean().default(false), // Em produção viria do JWT; por ora, aceito no body authorId: z .number({ required_error: 'authorId é obrigatório' }) .int() .positive(), }); export type AddCommentBody = z.infer; // ─── Shape de resposta dos comentários ─────────────────────────────────────── export const commentResponseSchema = z.object({ id: z.number(), content: z.string(), isInternal: z.boolean(), ticketId: z.number(), authorId: z.number(), createdAt: z.string(), updatedAt: z.string(), }); export type CommentResponse = z.infer;