Skip to content

Generate the frontend API client from qh's OpenAPI spec - #8

Merged
thorwhalen merged 1 commit into
mainfrom
generated-api-client
May 21, 2026
Merged

Generate the frontend API client from qh's OpenAPI spec#8
thorwhalen merged 1 commit into
mainfrom
generated-api-client

Conversation

@thorwhalen

Copy link
Copy Markdown
Owner

Summary

frontend/src/api/schema.ts was hand-written and verified against the live backend, because qh's /openapi.json emitted empty request/response schemas. With i2mint/qh#9, qh now derives full JSON Schema from ef.service.EfService's Python type hints — so the frontend's API types are now generated from the spec.

What changed

  • backend/export_openapi.py — exports the backend's OpenAPI document to frontend/src/api/openapi.json, the committed API-contract snapshot.
  • Frontend toolingopenapi-typescript devDependency + a gen:api script that regenerates src/api/openapi.d.ts from openapi.json.
  • src/api/schema.ts — was 113 lines of hand-written interfaces; now thin aliases (CorpusInfo, Segment, SearchHit, ExploreResult, CreateCorpusBody, QueryBody, ExploreBody) over the generated types. All 8 consumer files are untouched — the named-alias layer keeps the import surface stable.
  • src/surfaces/SearchSurface.tsx — guards SearchHit.source_id. The generated types correctly show it as nullable (ef's source_id: str | None); the hand-written schema had wrongly declared it always-present, so this is a latent-bug fix the generated types surfaced.
  • .gitignore — track frontend/src/api/openapi.json (it was caught by a broad *.json ignore).

Refresh workflow

After a backend API change:

cd backend  && python export_openapi.py   # refresh openapi.json
cd frontend && pnpm gen:api               # regenerate openapi.d.ts

Verification

  • pnpm typecheck and pnpm build pass.
  • Backend serves the enriched /openapi.json (with components.schemas).
  • create_corpussearchexplore_corpuslist_corporadelete_corpus all work over HTTP.
  • A browser round-trip through the UI — create a corpus via the form, then search — renders results with zero console/page errors.

Closes #7
Refs i2mint/qh#9

frontend/src/api/schema.ts was hand-written and verified against the live
backend, because qh's /openapi.json emitted empty request/response schemas.
With i2mint/qh#9 qh now derives full JSON Schema from the EfService Python
type hints, so the frontend's API types can be generated from the spec.

- backend/export_openapi.py — exports the backend's OpenAPI document to
  frontend/src/api/openapi.json (the committed API-contract snapshot).
- frontend: openapi-typescript devDependency + `gen:api` script generating
  src/api/openapi.d.ts from openapi.json.
- src/api/schema.ts — was 113 lines of hand-written interfaces; now thin
  aliases (CorpusInfo, Segment, SearchHit, ExploreResult, CreateCorpusBody,
  QueryBody, ExploreBody) over the generated types. All 8 consumers untouched.
- src/surfaces/SearchSurface.tsx — guard SearchHit.source_id, which the
  generated types correctly show as nullable (ef's source_id: str | None);
  the hand-written schema had wrongly declared it always-present.
- .gitignore — track frontend/src/api/openapi.json (the API contract).

Verified end-to-end: tsc + vite build pass; backend serves the enriched
/openapi.json; create -> search -> explore -> list -> delete all work, and a
browser create+search round-trip through the UI renders with zero errors.

Closes #7
@thorwhalen
thorwhalen merged commit 23de85f into main May 21, 2026
@thorwhalen
thorwhalen deleted the generated-api-client branch May 21, 2026 19:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Generate the frontend API client from qh's OpenAPI spec

1 participant