Files
openmonetis/lib/schemas/common.ts
Felipe Coutinho ea0b8618e0 feat: adição de novos ícones SVG e configuração do ambiente
- Adicionados ícones SVG para ChatGPT, Claude, Gemini e OpenRouter
- Implementados ícones para modos claro e escuro do ChatGPT
- Criado script de inicialização para PostgreSQL com extensão pgcrypto
- Adicionado script de configuração de ambiente que faz backup do .env
- Configurado tsconfig.json para TypeScript com opções de compilação
2025-11-15 15:49:36 -03:00

135 lines
3.2 KiB
TypeScript

import { z } from "zod";
/**
* Common Zod schemas for reuse across the application
*/
/**
* UUID schema with custom error message
*/
export const uuidSchema = (entityName: string = "ID") =>
z.string({ message: `${entityName} inválido.` }).uuid(`${entityName} inválido.`);
/**
* Decimal string schema - parses string with comma/period to number
*/
export const decimalSchema = z
.string()
.trim()
.transform((value) => value.replace(/\s/g, "").replace(",", "."))
.refine(
(value) => !Number.isNaN(Number.parseFloat(value)),
"Informe um valor numérico válido."
)
.transform((value) => Number.parseFloat(value));
/**
* Optional/nullable decimal string schema
*/
export const optionalDecimalSchema = z
.string()
.trim()
.optional()
.transform((value) =>
value && value.length > 0 ? value.replace(",", ".") : null
)
.refine(
(value) => value === null || !Number.isNaN(Number.parseFloat(value)),
"Informe um valor numérico válido."
)
.transform((value) => (value === null ? null : Number.parseFloat(value)));
/**
* Day of month schema (1-31)
*/
export const dayOfMonthSchema = z
.string({ message: "Informe o dia." })
.trim()
.min(1, "Informe o dia.")
.refine((value) => {
const parsed = Number.parseInt(value, 10);
return !Number.isNaN(parsed) && parsed >= 1 && parsed <= 31;
}, "Informe um dia entre 1 e 31.");
/**
* Period schema (YYYY-MM format)
*/
export const periodSchema = z
.string({ message: "Informe o período." })
.trim()
.regex(/^\d{4}-(0[1-9]|1[0-2])$/, "Período inválido.");
/**
* Optional period schema
*/
export const optionalPeriodSchema = z
.string()
.trim()
.regex(/^(\d{4})-(\d{2})$/, {
message: "Selecione um período válido.",
})
.optional();
/**
* Date string schema
*/
export const dateStringSchema = z
.string({ message: "Informe a data." })
.trim()
.refine((value) => !Number.isNaN(new Date(value).getTime()), {
message: "Data inválida.",
});
/**
* Optional date string schema
*/
export const optionalDateStringSchema = z
.string()
.trim()
.refine((value) => !value || !Number.isNaN(new Date(value).getTime()), {
message: "Informe uma data válida.",
})
.optional();
/**
* Note/observation schema (max 500 chars, trimmed, nullable)
*/
export const noteSchema = z
.string()
.trim()
.max(500, "A anotação deve ter no máximo 500 caracteres.")
.optional()
.transform((value) => (value && value.length > 0 ? value : null));
/**
* Optional string that becomes null if empty
*/
export const optionalStringToNull = z
.string()
.trim()
.optional()
.transform((value) => (value && value.length > 0 ? value : null));
/**
* Required non-empty string schema
*/
export const requiredStringSchema = (fieldName: string) =>
z
.string({ message: `Informe ${fieldName}.` })
.trim()
.min(1, `Informe ${fieldName}.`);
/**
* Amount schema with minimum value validation
*/
export const amountSchema = z.coerce
.number({ message: "Informe o valor." })
.min(0, "Informe um valor maior ou igual a zero.");
/**
* Positive amount schema
*/
export const positiveAmountSchema = z.coerce
.number({ message: "Informe o valor." })
.positive("Informe um valor maior que zero.");