Leer el resultado
safeParse te devuelve success, data e issues. Así los usas en tu formulario.
safeParse no lanza un error si el dato es malo. Te devuelve un objeto para que tú decidas qué mostrar.
const result = await UserSemantic.safeParse(input); if (!result.success) { return Response.json(result, { status: 400 });} // result.data está tipado como la salida de tu schema ZodsaveUser(result.data);Las tres piezas
| Campo | Qué significa |
|---|---|
success | false solo si algún issue tiene severity: "error". |
data | Los datos ya validados por Zod. Existe si la forma pasó, aunque una regla semántica haya fallado. |
issues | Todos los problemas, en un solo array. Primero Zod, después EDcheck. |
Si Zod rechaza la forma, data no viene. Si Zod pasó y EDcheck puso un warning, data sí viene y success puede ser true.
Cómo se ve un issue
{ path: ["fullName"], code: "semantic", severity: "error", message: "Semantic rule \"fullName\" failed", outcome: "fail", ruleId: "fullName", probability: 0.18, thresholds: { pass: 0.7, fail: 0.7 },}| Campo | Para qué |
|---|---|
path | En qué campo poner el error. Úsalo para pintar el input en rojo. |
code | semantic si falló el sentido. semantic_unavailable si la IA no contestó. |
severity | error, warning o info. |
message | Texto para el usuario o para tu log. |
ruleId | Qué regla disparó esto. Sirve para no duplicar errores. |
probability | Qué tan segura estaba la IA (reglas sí/no). |
Mostrar errores en el formulario
Agrupa los issues por el primer valor de path. Así cada input muestra su mensaje.
function messagesByField(issues: { path: Array<string | number>; message: string }[]) { const map = new Map<string, string[]>(); for (const issue of issues) { const key = String(issue.path[0] ?? ""); const list = map.get(key) ?? []; list.push(issue.message); map.set(key, list); } return map;}Los umbrales (qué tan estricta es la IA)
La IA no dice sí o no seco. Dice un número entre 0 y 1. EDcheck lo corta así:
p >= pass→ pasa (no hay issue)fail <= p < pass→ avisop < fail→ falla
Por defecto pass y fail son 0.7. Eso significa: 70% o más pasa, menos de 70% falla. No hay zona de aviso a menos que tú la abras.
const edcheck = createEDcheck({ provider, thresholds: { pass: 0.8, fail: 0.4 },});Con eso: 0.8 o más pasa, entre 0.4 y 0.8 es aviso, menos de 0.4 falla.
Puedes poner umbrales en la instancia, en el schema o en una regla. Gana el más específico: regla > schema > instancia > el default.