diff options
| author | zwlucas <lucas.fariamo08@gmail.com> | 2026-07-25 21:23:29 +0000 |
|---|---|---|
| committer | zwlucas <lucas.fariamo08@gmail.com> | 2026-07-25 21:23:29 +0000 |
| commit | ef55d9bb24430610b60c1b77821307cd72c08c55 (patch) | |
| tree | e6935a810b34370b0a4c821e55f6397aac50c832 /api/src/modules/categories/categories.schema.ts | |
| download | helpdesk-master.tar.gz helpdesk-master.zip | |
Signed-off-by: zwlucas <lucas.fariamo08@gmail.com>
Diffstat (limited to 'api/src/modules/categories/categories.schema.ts')
| -rw-r--r-- | api/src/modules/categories/categories.schema.ts | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/api/src/modules/categories/categories.schema.ts b/api/src/modules/categories/categories.schema.ts new file mode 100644 index 0000000..6e11d8c --- /dev/null +++ b/api/src/modules/categories/categories.schema.ts @@ -0,0 +1,76 @@ +/** + * categories.schema.ts + * Schemas Zod para o CRUD de categorias. + */ + +import { z } from 'zod'; + +// ─── Helper: gerador de slug ────────────────────────────────────────────────── +// Converte "Hardware e Periféricos" → "hardware-e-perifericos" +function toSlug(name: string): string { + return name + .toLowerCase() + .normalize('NFD') + .replace(/[\u0300-\u036f]/g, '') // remove acentos + .replace(/[^a-z0-9\s-]/g, '') // remove caracteres especiais + .trim() + .replace(/\s+/g, '-'); // espaços → hífens +} + +// ─── Criação ────────────────────────────────────────────────────────────────── + +export const createCategoryBodySchema = z.object({ + name: z + .string({ required_error: 'Nome é obrigatório' }) + .min(2, 'Nome deve ter no mínimo 2 caracteres') + .max(80) + .trim(), + + // Se não informado, será gerado automaticamente a partir do name + slug: z + .string() + .min(2) + .max(80) + .regex(/^[a-z0-9-]+$/, 'Slug deve conter apenas letras minúsculas, números e hífens') + .optional(), + + description: z.string().max(300).trim().optional(), +}).transform((data) => ({ + ...data, + // Garante que slug sempre exista — gerado do name se ausente + slug: data.slug ?? toSlug(data.name), +})); + +export type CreateCategoryBody = z.infer<typeof createCategoryBodySchema>; + +// ─── Atualização (PATCH parcial) ────────────────────────────────────────────── + +export const updateCategoryBodySchema = z.object({ + name: z.string().min(2).max(80).trim().optional(), + slug: z.string().min(2).max(80) + .regex(/^[a-z0-9-]+$/, 'Slug inválido').optional(), + description: z.string().max(300).trim().nullable().optional(), +}); + +export type UpdateCategoryBody = z.infer<typeof updateCategoryBodySchema>; + +// ─── Parâmetros de rota ─────────────────────────────────────────────────────── + +export const categoryParamsSchema = z.object({ + id: z.coerce.number().int().positive(), +}); + +export type CategoryParams = z.infer<typeof categoryParamsSchema>; + +// ─── Resposta ───────────────────────────────────────────────────────────────── + +export const categoryResponseSchema = z.object({ + id: z.number(), + name: z.string(), + slug: z.string(), + description: z.string().nullable(), + createdAt: z.string(), + updatedAt: z.string(), +}); + +export type CategoryResponse = z.infer<typeof categoryResponseSchema>; |