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
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
zodto 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 topackages/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
zodlibrary.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
This allows us to:
Acceptance Criteria
zodin the frontend if not already presentcore/types/schemas/[feature]/[entity].schema.tsExample:
core/types/schemas/user/user.schema.tsZodschemas that match the backend structure (from/api/user,/api/project, etc.)IUser,IProjectEUserStatusTUserResponse,TPagination<T>userSchema,projectSchema,organizationSchema, etc.schema.parse(data)at the point of entry (SWR/axios/fetch API)safeParse<T>()for fallback behaviorExample usage
Or with fallback:
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 schemasFuture Vision
In the long run, we can move validated and shared schemas to:
packages/ └── types/ └── schemas/and consume them as:
This improves cross-project consistency (web, mobile, SSR) and makes type/schema maintenance scalable.
Related Resources