Use Cases (अपडेट: 2/6/2026)

Claude Code और Zod Validation गाइड

Claude Code और Zod से forms, APIs, env variables, webhooks और tests के लिए type-safe validation बनाएं.

Claude Code और Zod Validation गाइड

Runtime validation क्यों जरूरी है

TypeScript code लिखते समय मदद करता है, लेकिन runtime में आने वाले external data को अपने आप check नहीं करता. Browser form, API body, Webhook payload, process.env, या database में save करने से ठीक पहले का object गलत shape में हो सकता है. Runtime validation का मतलब है कि business logic से पहले value की shape check की जाए. Zod में आप schema लिखते हैं, यानी data का नियम, और उसी schema से TypeScript type निकालते हैं.

Claude Code इस काम में अच्छा है क्योंकि validation structured काम है: fields, types, limits, error messages, entry points और tests. अगर आप सिर्फ “validation बना दो” लिखेंगे, तो generic code मिलेगा. अगर आप लिखेंगे “form, API request/response, environment variables, Webhook payload, DB insert से पहले validation और tests चाहिए”, तो output ज्यादा उपयोगी होगा. Detail check करने के लिए Zod official docs और Next.js Route Handlers docs देखें.

unknown input
  -> Zod schema
  -> safeParse
  -> typed data
  -> business logic
  -> response schema
  -> client

मुख्य नियम है: बाहरी input पहले unknown है. Zod pass होने के बाद ही उसे typed data मानें. as SomeType validation नहीं है.

Claude Code को कौन से use cases बताने हैं

हर boundary की जरूरत अलग होती है. Form में user-facing message चाहिए. API में 400 response चाहिए. Environment variables में startup पर fail होना चाहिए. Webhook में payload से पहले signature verify होना चाहिए.

Use caseEntryZod क्या बचाता है
FormBrowser inputEmpty string, email format, length, consent
API request/responserequest.json() और response JSONInvalid payload, response contract, status
Environment variablesprocess.envMissing secret, invalid URL, port range
Webhook payloadThird-party POSTEvent type, IDs, amount, signature flow
Before DB insertApp में mapped objectPersistable fields, enums, required IDs

यह table Claude Code prompt में डालें. एक schema को हर layer में reuse करने की कोशिश न करें. Form schema में checkbox या confirmation field हो सकता है, लेकिन DB insert schema को अलग contract चाहिए. छोटे pieces जैसे emailSchema या idSchema share करें. Form integration के लिए internal React Hook Form guide और API design के लिए tRPC guide भी देखें.

Basic Zod schema

नीचे contact form का schema है. Claude Code से बनवाते समय बताएं कि messages user-facing हों, कौन सा field required है, length limits क्या हैं, और DB fields जैसे id या createdAt न जोड़े जाएं.

// src/lib/schemas/contact.ts
import { z } from "zod";

export const contactFormSchema = z.object({
  name: z
    .string()
    .trim()
    .min(1, "Please enter your name")
    .max(80, "Name must be 80 characters or fewer"),
  email: z
    .string()
    .trim()
    .email("Please enter a valid email address"),
  plan: z.enum(["trial", "team", "enterprise"]),
  message: z
    .string()
    .trim()
    .min(10, "Message must be at least 10 characters")
    .max(2000, "Message must be 2000 characters or fewer"),
  agreedToPolicy: z
    .boolean()
    .refine((value) => value, "Privacy policy agreement is required"),
});

export type ContactFormInput = z.infer<typeof contactFormSchema>;

trim() सिर्फ spaces वाले input को रोकता है. z.enum string को known choices तक सीमित करता है. z.infer schema से type निकालता है, इसलिए अलग interface maintain करने की जरूरत कम होती है.

safeParse से API errors बनाना

parse fail होने पर exception throw करता है. यह startup config के लिए ठीक है. safeParse result object देता है, इसलिए form और API में 400 error बनाने के लिए बेहतर है.

// src/lib/validation.ts
import { z } from "zod";

export type ValidationProblem = {
  path: string;
  message: string;
};

export function validateInput<TSchema extends z.ZodTypeAny>(
  schema: TSchema,
  input: unknown,
):
  | { ok: true; data: z.infer<TSchema> }
  | { ok: false; status: 400; errors: ValidationProblem[] } {
  const result = schema.safeParse(input);

  if (!result.success) {
    return {
      ok: false,
      status: 400,
      errors: result.error.issues.map((issue) => ({
        path: issue.path.join(".") || "_root",
        message: issue.message,
      })),
    };
  }

  return { ok: true, data: result.data };
}

यह helper error format को common बनाता है. अगर product multi-language है, तो message के बजाय message key return कर सकते हैं.

Next.js Route Handler में request और response validation

API में input validate करना जरूरी है, लेकिन response schema भी useful है. इससे public contract गलती से बदलने पर जल्दी पता चलता है.

// app/api/contact/route.ts
import { NextResponse } from "next/server";
import { z } from "zod";
import {
  contactFormSchema,
  type ContactFormInput,
} from "@/lib/schemas/contact";
import { validateInput } from "@/lib/validation";

const contactResponseSchema = z.object({
  id: z.string().min(1),
  status: z.enum(["queued"]),
});

async function saveContact(input: ContactFormInput) {
  // Replace this with your database insert.
  return {
    id: `contact_${Date.now()}`,
    status: "queued" as const,
    email: input.email,
  };
}

export async function POST(request: Request) {
  const body: unknown = await request.json();
  const validated = validateInput(contactFormSchema, body);

  if (!validated.ok) {
    return NextResponse.json(
      { message: "Please check your input", errors: validated.errors },
      { status: validated.status },
    );
  }

  const saved = await saveContact(validated.data);
  const response = contactResponseSchema.parse(saved);

  return NextResponse.json(response, { status: 201 });
}

Webhook में order और भी जरूरी है: पहले signature verify करें, फिर payload schema, फिर business logic. Claude Code को बोलें कि verifySignature, webhookPayloadSchema और handleWebhookEvent अलग functions में रखे.

Environment variables startup पर validate करें

Environment variables strings या undefined होते हैं. अगर DATABASE_URL missing है, app startup पर fail होना चाहिए.

// src/env.ts
import { z } from "zod";

const envSchema = z.object({
  NODE_ENV: z
    .enum(["development", "test", "production"])
    .default("development"),
  DATABASE_URL: z.string().url("DATABASE_URL must be a valid URL"),
  NEXT_PUBLIC_APP_URL: z.string().url("NEXT_PUBLIC_APP_URL must be a valid URL"),
  WEBHOOK_SECRET: z.string().min(32, "WEBHOOK_SECRET must be at least 32 chars"),
  PORT: z.coerce.number().int().min(1).max(65535).default(3000),
});

const parsed = envSchema.safeParse(process.env);

if (!parsed.success) {
  console.error(
    "Invalid environment variables",
    parsed.error.flatten().fieldErrors,
  );
  throw new Error("Invalid environment variables");
}

export const env = parsed.data;

z.coerce.number() यहां ठीक है क्योंकि source string है. हर JSON body पर coerce मत लगाइए; इससे dirty input silently accept हो सकता है.

react-hook-form integration

Client validation user experience सुधारता है, लेकिन server validation को replace नहीं करता. Browser bypass हो सकता है.

// src/components/contact-form.tsx
"use client";

import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import {
  contactFormSchema,
  type ContactFormInput,
} from "@/lib/schemas/contact";

export function ContactForm() {
  const {
    register,
    handleSubmit,
    formState: { errors, isSubmitting },
  } = useForm<ContactFormInput>({
    resolver: zodResolver(contactFormSchema),
    defaultValues: {
      name: "",
      email: "",
      plan: "trial",
      message: "",
      agreedToPolicy: false,
    },
  });

  async function onSubmit(values: ContactFormInput) {
    const response = await fetch("/api/contact", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(values),
    });

    if (!response.ok) {
      throw new Error("Failed to send contact request");
    }
  }

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("name")} aria-invalid={Boolean(errors.name)} />
      {errors.name && <p>{errors.name.message}</p>}

      <input {...register("email")} aria-invalid={Boolean(errors.email)} />
      {errors.email && <p>{errors.email.message}</p>}

      <select {...register("plan")}>
        <option value="trial">Trial</option>
        <option value="team">Team</option>
        <option value="enterprise">Enterprise</option>
      </select>

      <textarea {...register("message")} />
      {errors.message && <p>{errors.message.message}</p>}

      <label>
        <input type="checkbox" {...register("agreedToPolicy")} />
        I agree to the privacy policy
      </label>
      {errors.agreedToPolicy && <p>{errors.agreedToPolicy.message}</p>}

      <button type="submit" disabled={isSubmitting}>
        Send
      </button>
    </form>
  );
}

Claude Code को साफ बोलें कि server-side schema check हटाना नहीं है. UI सुधारते समय API boundary कमजोर हो जाना common गलती है.

Claude Code review prompt

Implementation के बाद Claude Code से focused review करवाएं.

Review only the Zod validation design in these files.

Check:
1. Every external input is treated as unknown until safeParse or parse succeeds.
2. Route Handlers return 400 with field-level errors for invalid requests.
3. Environment variables fail fast at startup.
4. coerce and transform are used only where the input source is clear.
5. Form schemas, API schemas, and database insert schemas are not over-shared.
6. Error messages are user-facing and ready for localization.

Do not refactor unrelated business logic.
Return findings with file paths, risk level, and a minimal patch suggestion.

यह prompt मुख्य pitfalls पकड़ता है: TypeScript type पर भरोसा, parse और safeParse confusion, ज्यादा coerce, transform में side effect, localization plan की कमी, और schema over-reuse.

Tests से contract lock करें

Schema product contract है. एक valid case और कुछ invalid cases test में रखें.

// src/lib/schemas/contact.test.ts
import { describe, expect, it } from "vitest";
import { contactFormSchema } from "./contact";

describe("contactFormSchema", () => {
  it("accepts a valid contact request", () => {
    const result = contactFormSchema.safeParse({
      name: "Masa",
      email: "masa@example.com",
      plan: "team",
      message: "I want to introduce Claude Code to my team.",
      agreedToPolicy: true,
    });

    expect(result.success).toBe(true);
  });

  it("rejects invalid email and short message", () => {
    const result = contactFormSchema.safeParse({
      name: "Masa",
      email: "not-an-email",
      plan: "team",
      message: "short",
      agreedToPolicy: true,
    });

    expect(result.success).toBe(false);
    if (!result.success) {
      expect(result.error.issues.map((issue) => issue.path.join("."))).toEqual(
        expect.arrayContaining(["email", "message"]),
      );
    }
  });
});

DB insert से पहले final object को भी test करें. इससे field name, enum या mapping change जल्दी पकड़ में आता है.

Common pitfalls

पहला, TypeScript type runtime validation नहीं है. request.json() as ContactFormInput सिर्फ compiler को शांत करता है.

दूसरा, parse और safeParse अलग रखें. User input और API के लिए safeParse अच्छा है; env config fail होने पर process रोक सकता है.

तीसरा, coerce ज्यादा न इस्तेमाल करें. Query string और env में ठीक है, लेकिन unclear input पर dangerous है.

चौथा, transform में side effect न डालें. DB write, email और analytics validation के बाद होने चाहिए.

पांचवां, error messages और localization पहले सोचें. Multi-language product में message keys बेहतर हो सकते हैं.

छठा, schema को जरूरत से ज्यादा reuse न करें. Form, API, Webhook और DB insert अलग contracts हैं.

Consultation और verification note

अगर validation कई forms, webhooks, API routes और DB code में बिखरा है, Claude Code Lab schema layers, review prompts और tests व्यवस्थित करने में मदद कर सकता है. Project guidance के लिए English consulting and training page देखें.

इस article के examples 2026-06-02 को Zod और Next.js Route Handler docs के आधार पर review किए गए. Code examples TypeScript project मानते हैं जिसमें zod, react-hook-form, @hookform/resolvers और vitest installed हैं. Real projects में Masa authentication, CSRF या Webhook signature verification, DB constraints और हर external boundary के failing tests जोड़ता है.

#Claude Code #Zod #validation #TypeScript #type safety
मुफ़्त

मुफ़्त PDF: Claude Code cheatsheet

Email डालें और commands, review habits तथा safe workflow वाली एक-page PDF पाएँ.

हम आपका data सुरक्षित रखते हैं और spam नहीं भेजते.

Masa

लेखक के बारे में

Masa

Claude Code workflow और team adoption पर काम करने वाला engineer.