aboutsummaryrefslogtreecommitdiff
path: root/api/src/modules/tickets/tickets.schema.ts
diff options
context:
space:
mode:
authorzwlucas <lucas.fariamo08@gmail.com>2026-07-25 21:23:29 +0000
committerzwlucas <lucas.fariamo08@gmail.com>2026-07-25 21:23:29 +0000
commitef55d9bb24430610b60c1b77821307cd72c08c55 (patch)
treee6935a810b34370b0a4c821e55f6397aac50c832 /api/src/modules/tickets/tickets.schema.ts
downloadhelpdesk-ef55d9bb24430610b60c1b77821307cd72c08c55.tar.gz
helpdesk-ef55d9bb24430610b60c1b77821307cd72c08c55.zip
feat: upload of the projectHEADmaster
Signed-off-by: zwlucas <lucas.fariamo08@gmail.com>
Diffstat (limited to 'api/src/modules/tickets/tickets.schema.ts')
-rw-r--r--api/src/modules/tickets/tickets.schema.ts89
1 files changed, 89 insertions, 0 deletions
diff --git a/api/src/modules/tickets/tickets.schema.ts b/api/src/modules/tickets/tickets.schema.ts
new file mode 100644
index 0000000..43d94cf
--- /dev/null
+++ b/api/src/modules/tickets/tickets.schema.ts
@@ -0,0 +1,89 @@
+/**
+ * tickets.schema.ts
+ *
+ * Schemas Zod para validação de entrada e saída do módulo de tickets.
+ * Usados tanto pelo Fastify (validação automática de requests)
+ * quanto pelo TypeScript (inferência de tipos).
+ */
+
+import { z } from 'zod';
+import { TICKET_PRIORITIES, TICKET_STATUSES } from '@/db/schema.js';
+
+// ─── Criação de Ticket ────────────────────────────────────────────────────────
+
+export const createTicketBodySchema = z.object({
+ title: z
+ .string({ required_error: 'Título é obrigatório' })
+ .min(5, 'Título deve ter no mínimo 5 caracteres')
+ .max(150, 'Título deve ter no máximo 150 caracteres')
+ .trim(),
+
+ description: z
+ .string({ required_error: 'Descrição é obrigatória' })
+ .min(10, 'Descrição deve ter no mínimo 10 caracteres')
+ .trim(),
+
+ priority: z.enum(TICKET_PRIORITIES).default('medium'),
+
+ categoryId: z.number().int().positive().optional(),
+
+ // Em uma implementação real, o creatorId viria do token JWT.
+ // Por ora, aceita no body para facilitar o desenvolvimento iterativo.
+ creatorId: z
+ .number({ required_error: 'creatorId é obrigatório' })
+ .int()
+ .positive(),
+});
+
+export type CreateTicketBody = z.infer<typeof createTicketBodySchema>;
+
+// ─── Listagem de Tickets (filtros + paginação) ────────────────────────────────
+
+export const listTicketsQuerySchema = z.object({
+ status: z.enum(TICKET_STATUSES).optional(),
+ priority: z.enum(TICKET_PRIORITIES).optional(),
+ assigneeId: z.coerce.number().int().positive().optional(),
+ creatorId: z.coerce.number().int().positive().optional(),
+ categoryId: z.coerce.number().int().positive().optional(),
+
+ // Paginação
+ page: z.coerce.number().int().min(1).default(1),
+ limit: z.coerce.number().int().min(1).max(100).default(20),
+});
+
+export type ListTicketsQuery = z.infer<typeof listTicketsQuerySchema>;
+
+// ─── Parâmetros de rota ───────────────────────────────────────────────────────
+
+export const ticketParamsSchema = z.object({
+ id: z.coerce.number().int().positive(),
+});
+
+export type TicketParams = z.infer<typeof ticketParamsSchema>;
+
+// ─── Shape de resposta ────────────────────────────────────────────────────────
+
+export const ticketResponseSchema = z.object({
+ id: z.number(),
+ title: z.string(),
+ description: z.string(),
+ status: z.enum(TICKET_STATUSES),
+ priority: z.enum(TICKET_PRIORITIES),
+ creatorId: z.number(),
+ assigneeId: z.number().nullable(),
+ categoryId: z.number().nullable(),
+ dueAt: z.string().nullable(),
+ resolvedAt: z.string().nullable(),
+ createdAt: z.string(),
+ updatedAt: z.string(),
+});
+
+export const listTicketsResponseSchema = z.object({
+ data: z.array(ticketResponseSchema),
+ meta: z.object({
+ page: z.number(),
+ limit: z.number(),
+ total: z.number(),
+ totalPages: z.number(),
+ }),
+});