| name | openapi-sync |
| description | Keep the frontend API types in sync with the backend after any endpoint change — regenerate menu-api.ts from the OpenAPI spec produced by the .NET build. |
| user-invokable | true |
| context | inline |
OpenAPI Sync
Purpose
Use this skill after any change to a MenuApi endpoint (new endpoint, changed request/response shape, renamed route). The frontend uses generated TypeScript types from the backend's OpenAPI spec; stale types cause type errors and runtime mismatches.
How it works
- The .NET build writes
open-api/menu-api.json at the repository root.
pnpm generate-openapi (from ui/menu-website/) reads that file and outputs src/generated/open-api/menu-api.ts.
src/services/recipe-api.ts consumes the generated types via openapi-fetch.
Never hand-write types in src/generated/ — the entire src/generated/ folder is overwritten on each run.
Steps
1. Build the backend to produce the spec
cd backend
dotnet restore MenuApi.sln
dotnet build MenuApi.sln --configuration Release --no-restore
This writes open-api/menu-api.json.
2. Regenerate the frontend types
cd ui/menu-website
pnpm generate-openapi
This reads ../../open-api/menu-api.json and outputs src/generated/open-api/menu-api.ts.
3. Commit the generated types
Commit src/generated/open-api/menu-api.ts in the same commit as the backend change that caused the update.
open-api/menu-api.json is generated by the .NET build and is gitignored (open-api/.gitignore ignores *.json) — do not attempt to commit it. It is consumed as a build artifact at generation time and uploaded to CI artefacts for the frontend job.
Validation
After regeneration, confirm the frontend still compiles and passes lint:
cd ui/menu-website
pnpm run lint
pnpm run build
Common mistakes
- Running
pnpm generate-openapi before building the backend — the spec file will be stale or missing.
- Editing
src/generated/open-api/menu-api.ts by hand — changes will be silently overwritten on the next generation run.
- Trying to commit
open-api/menu-api.json — it is gitignored and is consumed as a build-time artefact, not a tracked file.