The contract between apps/web and apps/backend is not hand-written; it is generated along
this chain:
Backend DTO → Swagger → packages/api/src/schemas/openapi.json → api.ts → SDK → apps/web
-
After changing a DTO or a handler's return type, run:
pnpm --filter app-backend generate:api-schemas
(needs a valid root
.env) and commit the regenerated schemas — otherwiseapps/webtypechecks against a stale contract. -
Supabase database types are generated separately:
pnpm --filter app-backend generate-types
The
database.types.tsfile is copied intopackages/api. -
Do not edit the generated files (
openapi.json,api.ts,database.types.ts): they are eslint-ignored, solint:fixcannot reformat them.
packages/api provides a hand-written wrapper over the generated types: createSdk,
createApiClient. createSdk(supabase, options) attaches the caller's access token to every
request; it defaults to a relative /api base URL (which only resolves in the browser), so SSR
callers must pass an absolute baseUrl (ApiClientOptions). Full description on the
api package page and in apps/backend/README.md.