Skip to main content

Overview

Data schemas are defined inside each API resource folder (e.g. apps/api/src/resources/users/users.schema.ts). They are auto-copied to packages/shared/src/schemas/ during codegen (pnpm --filter shared generate). Data schema — is a Zod 4 schema that defines shape of the entity. It extends dbSchema from resources/base.schema.ts which provides _id, createdOn, updatedOn, and deletedOn fields.
import { z } from 'zod';

import dbSchema from 'resources/base.schema';

const schema = dbSchema.extend({
  firstName: z.string(),
  lastName: z.string(),
  fullName: z.string(),

  email: z.email(),
  passwordHash: z.string().nullable().optional(),

  isEmailVerified: z.boolean().default(false),

  signupToken: z.string().nullable().optional(),
  resetPasswordToken: z.string().nullable().optional(),

  avatarUrl: z.string().nullable().optional(),
  oauth: z.object({
    google: z.boolean().default(false),
  }).optional(),

  lastRequest: z.date().optional(),
}).strict();

export default schema;
This repo uses Zod 4. Use z.email(), z.url(), z.uuid() instead of Zod 3’s z.string().email().

Validation

Zod schemas are used both server-side (in createEndpoint via the schema option) and client-side (via useApiForm or manual zodResolver):
import { z } from 'zod';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';

const schema = z.object({
  firstName: z.string().min(1, 'Please enter First name').max(100),
  lastName: z.string().min(1, 'Please enter Last name').max(100),
  email: z.email('Email format is incorrect.'),
  password: z.string().min(6, 'Password must be at least 6 characters'),
});

type SignUpParams = z.infer<typeof schema>

const SignUp = () => {
    const methods = useForm<SignUpParams>({
        resolver: zodResolver(schema),
    });

    return (
        //your code here
    )
}

export default SignUp;
Additionally, data can be validated using the safeParse method:
const parsed = zodSchema.safeParse(data);

if (!parsed.success) {
    throw new Error('Invalid data');
}
For more details on Zod, check the documentation.