Skip to content

[Task] Integrate Zod Schemas for API Data Validation and Centralization #3797

@NdekoCode

Description

@NdekoCode

In Ever Teams, we rely heavily on data returned from the Gauzy API (https://api.ever.team). However, data structures in the API often change unexpectedly, which causes runtime issues or silent bugs in the web application.

To address this, we will adopt zod to validate API responses at runtime. Zod schemas will act as runtime contracts between our frontend and backend, allowing us to immediately detect and handle shape mismatches.

This issue defines a clear plan to create, structure, and centralize Zod schemas used in apps/web/core/types/schema, and optionally prepare for a future migration to packages/types.

Goal

To improve robustness and early error detection in the frontend by validating all external API data (from Ever Gauzy) using zod.
So all data coming from the backend (Gauzy API) will validate and parse before use in the frontend, using the zod library.
This ensures that any structural mismatch or unexpected data in the response is caught immediately, avoiding silent bugs or runtime crashes.

Zod will act as a contract validation layer between the backend and our frontend logic.

Why This Matters

  • Gauzy API changes frequently and silently
  • Current implementation lacks a strong validation layer
  • TypeScript types alone don’t protect us at runtime
  • Unexpected structure changes are detected too late
  • Helps enforce data shape contracts before usage
  • Makes debugging and logging easier with precise validation errors

This allows us to:

  • Detect breaking changes in the API response early
  • Prevent runtime errors due to missing/renamed/invalid properties
  • Create a typed and parsed layer between external data and UI logic
  • Improve developer experience with autocompletion, parsing errors, and debugging

Acceptance Criteria

  • Install zod in the frontend if not already present
  • Create a new directory: core/types/schemas/[feature]/[entity].schema.ts
    Example: core/types/schemas/user/user.schema.ts
  • Define Zod schemas that match the backend structure (from /api/user, /api/project, etc.)
  • Ensure naming conventions:
    • Interface: IUser, IProject
    • Enum: EUserStatus
    • Type: TUserResponse, TPagination<T>
    • Schema: userSchema, projectSchema, organizationSchema, etc.
  • Use schema.parse(data) at the point of entry (SWR/axios/fetch API)
  • Raise exceptions clearly if data structure mismatches
  • Optional: Wrap parsing with helper function like safeParse<T>() for fallback behavior
  • Optional: Create a zodParse() utility wrapper for improved DX

Example usage

import { userSchema } from '@/core/types/schemas/user/user.schema';

const { data } = await axios.get('/api/user/me');

// Throws an error if structure does not match
const user = userSchema.parse(data);

Or with fallback:

const result = userSchema.safeParse(data);
if (!result.success) {
	console.error('User data invalid', result.error);
	throw new Error('Invalid user response from API');
}
const user = result.data;

Suggested File Structure

core/
└── types/
    └── schemas/
        ├── user/
        │   └── user.schema.ts         # z.object({...})
        ├── project/
        │   └── project.schema.ts
        ├── task/
        │   └── task.schema.ts
        ├── ...
        └── index.ts                   # Central export of all schemas

Future Vision

In the long run, we can move validated and shared schemas to:

packages/
└── types/
    └── schemas/

and consume them as:

import { userSchema } from '@ever-teams/types/schemas/user';

This improves cross-project consistency (web, mobile, SSR) and makes type/schema maintenance scalable.

Related Resources

Metadata

Metadata

Projects

Status

📋 Backlog

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions