> ## Documentation Index
> Fetch the complete documentation index at: https://docs.jelou.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Validação

> Schemas Zod para validar entradas e saídas das suas funções: tipos, coerção em GET, formato de erros e comportamento de saída.

## Validação de entrada

Quando você define um schema `input`, cada requisição é validada antes de executar o handler. Se a validação falhar, o handler **não é executado** e um `400` é retornado:

```json theme={null}
{
  "error": "Validation failed",
  "details": [
    {
      "path": ["email"],
      "message": "Invalid email",
      "code": "invalid_string"
    }
  ]
}
```

### Exemplo com schema completo

```typescript index.ts theme={null}
import { define, z } from "@jelou/functions";

export default define({
  name: "create-ticket",
  description: "Creates a support ticket from WhatsApp",
  input: z.object({
    name: z.string().min(1).describe("Customer name"),
    email: z.string().email().describe("Contact email"),
    subject: z.string().max(200).describe("Ticket subject"),
    priority: z.enum(["low", "medium", "high"]).default("medium"),
  }),
  output: z.object({
    ticketId: z.string(),
    status: z.string(),
  }),
  handler: async (input, ctx) => {
    ctx.log("Creating ticket", { customer: input.name, priority: input.priority });
    return { ticketId: "TKT-2024-0042", status: "open" };
  },
});
```

### Tipos suportados

Você pode usar qualquer tipo Zod dentro de `z.object()`:

```typescript theme={null}
input: z.object({
  name: z.string().min(1),
  age: z.number().int().positive(),
  email: z.string().email(),
  active: z.boolean().default(true),
  role: z.enum(["admin", "user", "guest"]),
  tags: z.array(z.string()).optional(),
  metadata: z.record(z.string(), z.unknown()).optional(),
})
```

### Coerção em requisições GET

Para requisições GET, os parâmetros de query são strings. Use `z.coerce` para converter tipos automaticamente:

```typescript index.ts theme={null}
import { define, z } from "@jelou/functions";

export default define({
  name: "search-orders",
  description: "Search orders by status",
  input: z.object({
    q: z.string(),
    limit: z.coerce.number().default(10),
    page: z.coerce.number().default(1),
    active: z.coerce.boolean().default(true),
  }),
  handler: async (input, ctx) => {
    ctx.log("Searching", { q: input.q, limit: input.limit });
    return { results: [], total: 0 };
  },
});
```

```bash theme={null}
curl "https://search-orders.fn.jelou.ai/?q=pending&limit=5&page=2"
```

### Anotações `.describe()`

Use `.describe()` em cada campo para documentar os parâmetros. Essas descrições aparecem automaticamente no schema MCP, ajudando os agentes de IA a entender como usar sua função:

```typescript theme={null}
input: z.object({
  phone: z.string().min(10).describe("Phone number with country code, e.g.: 593987654321"),
  includeHistory: z.boolean().default(false).describe("Whether to include the conversation history"),
})
```

## Validação de saída

Quando você define um schema `output`, o valor retornado pelo handler é validado **após** a execução. Se não corresponder:

* Um aviso é registrado no log
* A resposta é enviada normalmente com status `200`

<Note>
  A validação de saída nunca bloqueia a resposta. É uma ferramenta de desenvolvimento para detectar inconsistências.
</Note>

```typescript theme={null}
output: z.object({
  name: z.string(),
  balance: z.number(),
})
```

Se o handler retornar `{ name: "Maria", balance: "150" }` (balance como string), você verá um aviso nos logs, mas o cliente recebe a resposta sem alterações.

## Formato de erros de validação

Cada erro no array `details` contém:

| Campo     | Tipo       | Descrição                                                                     |
| --------- | ---------- | ----------------------------------------------------------------------------- |
| `path`    | `string[]` | Caminho até o campo com o erro, ex.: `["email"]` ou `["address", "city"]`     |
| `message` | `string`   | Mensagem de erro legível por humanos                                          |
| `code`    | `string`   | Código de erro Zod (ex.: `invalid_string`, `too_small`, `invalid_enum_value`) |

```json theme={null}
{
  "error": "Validation failed",
  "details": [
    {
      "path": ["name"],
      "message": "String must contain at least 1 character(s)",
      "code": "too_small"
    },
    {
      "path": ["priority"],
      "message": "Invalid enum value. Expected 'low' | 'medium' | 'high', received 'urgent'",
      "code": "invalid_enum_value"
    }
  ]
}
```
