Zod Contracts & OpenAPI
Relevant source files
The following files were used as context for generating this wiki page:
Zod contracts define the single source of truth for the Digital Healthcare Platform API. These contracts specify request bodies, query parameters, and response structures for every endpoint. The system generates OpenAPI 3.1 documentation and a typed fetch client directly from these shared Zod schemas.
Sources: packages/contracts/package.json:3-5, README.md:25-25
System Architecture
The @dhc/contracts package acts as the foundation for both the backend and frontend. The packages/contracts/src/openapi.ts file consolidates all module-specific schemas into a unified operation list. This list drives the automated generation of the API documentation and ensures consistency across the monorepo.
Contract Distribution Flow
The following diagram shows how Zod schemas propagate through the system to ensure end-to-end type safety and validation.
The diagram illustrates the central role of Zod contracts in driving validation, documentation, and client-side logic.
Sources: packages/contracts/src/openapi.ts:88-99, packages/api-client/src/client.ts:42-45, apps/api/src/modules/scheduling/routes.ts:35-40
OpenAPI Generation
The project generates its OpenAPI 3.1.0 specification programmatically. The buildOpenApiDocument function iterates through a defined list of Operation objects to construct the paths and components of the API.
Operation Interface
Every endpoint is described by an Operation object.
| Property | Description |
|---|---|
method | HTTP verb (get, post, put, patch, delete). |
path | The URL path, including placeholders for parameters. |
operationId | A unique identifier for the operation. |
public | Boolean flag; if true, the endpoint skips bearer token auth. |
body | Zod schema for the request body. |
query | Zod object defining allowed query string parameters. |
response | Zod schema for the successful response payload. |
status | The HTTP success status code (defaults to 200). |
Sources: packages/contracts/src/openapi.ts:88-103
Conversion Logic
The system converts Zod schemas into JSON Schema 2020-12 using the toSchema helper function. This function uses z.toJSONSchema while stripping the top-level $schema field to ensure compatibility with OpenAPI 3.1 requirements.
function toSchema(schema: z.ZodType, io: 'input' | 'output' = 'output') {
const { $schema: _schema, ...rest } = z.toJSONSchema(schema, { io, unrepresentable: 'any' });
return rest;
}
Sources: packages/contracts/src/openapi.ts:514-517
Integration and Validation
Backend Route Validation
The Fastify server uses Zod schemas to validate incoming data. In apps/api/src/modules/scheduling/routes.ts, the parse method on Zod schemas validates request.body, request.query, and request.params. If validation fails, the system throws a standard error that the API handles globally.
Sources: apps/api/src/modules/scheduling/routes.ts:35-50
Client-Side Parsing
The @dhc/api-client uses the same contracts to parse server responses. When a request is made, the client calls schema.parse(payload) on the JSON response. This ensures that the data received matches the expected structure before it reaches the application logic.
The sequence diagram shows how the client validates the response against the Zod schema before returning it to the caller.
Sources: packages/api-client/src/client.ts:42-63, packages/contracts/src/openapi.ts:108-115
Standard Error Contract
The ErrorResponse schema provides a consistent structure for all API errors. Every error includes a specific ErrorCode, a human-readable message, and an optional fields object for validation failures.
// Example usage in tests to verify the error shape
const parsed = ErrorResponse.parse({
error: {
code: 'SLOT_TAKEN',
message: 'This slot was just booked. Pick another time.',
fields: { slotStart: 'taken' },
requestId: 'req_123',
},
});
Sources: packages/contracts/src/contracts.test.ts:16-25
Public vs. Private Operations
The buildOpenApiDocument logic automatically applies security requirements. Most endpoints require a bearerAuth token. Specific endpoints are marked public: true and are exempted from security in the generated document.
| Public Endpoint | Purpose |
|---|---|
GET /health | Service health check. |
POST /auth/login | Initial staff password step. |
POST /auth/otp/request | Patient OTP request. |
POST /display/board | Waiting-room token display. |
Sources: packages/contracts/src/openapi.ts:108-175, packages/contracts/src/contracts.test.ts:74-88
Summary
Zod contracts eliminate the gap between API implementation and documentation. By using these schemas in both the Fastify backend and the typed API client, the project maintains strict type safety across all network boundaries. The automated OpenAPI generation ensures that external documentation always reflects the actual code.