OpenAPI contracts
Combined, legacy-only, and v2-only OpenAPI 3.1 contracts generated from the Go routes and canonical v2 DTOs.
StatsHub publishes a combined OpenAPI contract for tooling that intentionally spans the complete HTTP API. The documentation site also publishes isolated legacy and v2 contracts so a version-specific client never sees routes from the other surface. All three describe handlers served by the Go API; none introduces a parallel implementation.
Published documents
| Location | Contents |
|---|---|
/api/openapi.json | Combined legacy /api and canonical /api/v2 contract. |
/api/openapi-v2.json | Focused v2 contract with /api/v2 as its server base. |
/api/docs | Interactive explorer served by the API process. |
/openapi.json | Combined copy published by this documentation site. |
/openapi-v1.json | Legacy-only copy derived from the combined contract. |
/openapi-v2.json | V2-only copy published by this documentation site. |
/docs/api/v1/explorer | Searchable graph and inspector for legacy operations only. |
/docs/api/v1/reference | Generated pages for the legacy contract only. |
/docs/api/v2/explorer | Searchable graph and inspector for v2 operations only. |
/docs/api/v2/reference | Generated pages for the v2 contract only. |
The checked-in source documents live at
apps/api/docs/openapi.json and
apps/api/docs/openapi-v2.json. Reviewing an API change therefore
also reviews its contract change.
How generation works
The two surfaces use different generation strategies because they have different compatibility promises:
- Legacy
/apioperations are recovered from the existing Chi route tree and Go handlers. The generator records the exact paths, parameters, authentication helpers, request bodies, statuses, and legacy response envelopes. - Canonical
/api/v2operations are registered design-first from their real Go DTOs. Collection envelopes, Problem Details, cursor parameters, security, and write bodies are closed schemas rather than inferred maps.
The focused v2 document is merged into the combined document. V2 component names are prefixed, so an identically named legacy response cannot weaken a v2 schema.
Contract checks
Tests compare the combined document with the live Chi router in both directions. The v2 tests additionally reject:
- missing or duplicate operation IDs;
- undocumented default responses;
- open JSON success schemas;
- non-Problem JSON error schemas;
- missing authentication or write-body declarations on account operations.
Legacy conformance tests continue comparing closed success schemas with recorded response shapes. This preserves old clients while allowing v2 to use a cleaner contract.
Fumadocs generation
apps/docs/scripts/openapi.ts copies both checked-in documents into
public/, derives openapi-v1.json by retaining only legacy paths and their
reachable component schemas, then generates independent reference trees for
v1 and v2. Generated reference files are ignored by Git and rebuilt before
development, lint, and production builds.
Regenerating
cd apps/api
pnpm openapi
pnpm openapi:check
cd ../statshub-docs
pnpm openapiRun the API tests and docs checks with generation. A contract is current only when the route inventory, v2 operation table, generated JSON, and published copies agree.