Qadam Roadmap
проектdocs/Agents/rules/api-validation.md

api-validation.md

Обновлён 1 апр. 2026 г., 12:41 · 0 комментариев


title: Validate All Input with Zod Schemas impact: HIGH impactDescription: Prevents invalid data from entering the system tags: api, validation, zod, security

Паспорт документа

  • Статус документа: living standard
  • Актуально на: 28 марта 2026 года
  • Владелец: backend/platform-команда
  • Пересмотр: при изменении инженерной практики, CI/CD, архитектурных правил или локального workflow
  • Область применения: внутренние rule/reference-card документы для инженерной команды
  • Связанные документы:

Validate All Input with Zod Schemas

Impact: HIGH

All user input must be validated before processing. Use Zod schemas from packages/shared so validation rules are shared between frontend and backend.

Shared Schema (packages/shared)

// packages/shared/src/schemas/item.ts
import { z } from 'zod';

export const CreateItemSchema = z.object({
  name: z.string().min(3, 'Name must be at least 3 characters').max(200),
  description: z.string().min(10).max(5000).optional(),
  shortDescription: z.string().max(300).optional(),
  priceFrom: z.number().nonnegative().optional(),
  priceTo: z.number().nonnegative().optional(),
  subjectId: z.string().uuid().optional(),
  locationId: z.string().uuid().optional(),
  studyFormat: z.enum(['ONLINE', 'OFFLINE', 'HYBRID']),
  studyType: z.enum(['GROUP', 'MINI_GROUP', 'ONE_ON_ONE']).optional(),
  language: z.enum(['RU', 'UZ_LATIN', 'UZ_CYRILLIC', 'EN', 'KK', 'TG', 'ANY']).default('ANY'),
});

export type CreateItemDTO = z.infer<typeof CreateItemSchema>;

Backend Validation (NestJS Pipe)

// common/pipes/zod-validation.pipe.ts
import { PipeTransform, BadRequestException } from '@nestjs/common';
import type { ZodSchema } from 'zod';

export class ZodValidationPipe implements PipeTransform {
  constructor(private schema: ZodSchema) {}

  transform(value: unknown) {
    const result = this.schema.safeParse(value);
    if (!result.success) {
      throw new BadRequestException({
        message: 'Validation failed',
        errors: result.error.flatten().fieldErrors,
      });
    }
    return result.data;
  }
}

// Usage in controller
@Post()
async create(@Body(new ZodValidationPipe(CreateItemSchema)) dto: CreateItemDTO) {
  return this.itemService.create(dto);
}

Frontend Validation (React Hook Form + Zod)

// Using the same schema on the frontend
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { CreateItemSchema, type CreateItemDTO } from '@repo/shared';

function CreateItemForm() {
  const { register, handleSubmit, formState: { errors } } = useForm<CreateItemDTO>({
    resolver: zodResolver(CreateItemSchema),
  });

  return <form onSubmit={handleSubmit(onSubmit)}>...</form>;
}

Rules:

  • All input schemas live in packages/shared/src/schemas/
  • Backend validates via ZodValidationPipe in controllers
  • Frontend validates via zodResolver in forms
  • Never trust client-side validation alone — always validate on the backend