Skip to content

Serve interactive Swagger UI for the existing OpenAPI 3.1 contract #374

@greatest0fallt1me

Description

@greatest0fallt1me

Description

The backend already ships a machine-readable OpenAPI 3.1 contract at docs/openapi.json, which is loaded at module init (src/routes/index.ts:11-12) and served verbatim as JSON from GET /api/openapi.json (src/routes/index.ts:38-42). There is no human-facing way to browse it: swagger-ui-express is absent from package.json and no /docs route exists. Developers integrating with Callora must hand-read raw JSON to discover routes such as POST /api/billing/deduct and GET /api/usage. This issue adds an interactive Swagger UI mounted on top of the contract the app already publishes.

Requirements and context

  • Mount an interactive API explorer (e.g. swagger-ui-express) at GET /api/docs, backed by the same openApiSpec object already parsed in src/routes/index.ts:12 so the UI never drifts from /api/openapi.json.
  • Wire the new route inside createApiRouter in src/routes/index.ts (the function that already serves /openapi.json), keeping the existing GET /api/openapi.json endpoint unchanged.
  • Respect the existing Helmet Content Security Policy configured in src/app.ts:112-140 (note scriptSrc: ["'self'"] and styleSrc: ["'self'", "'unsafe-inline'"]); relax the CSP for the docs route only if Swagger UI assets require it, without weakening the global policy.
  • Non-functional: do not load the UI assets in NODE_ENV=production unless explicitly enabled via a new opt-in env var documented in README.md; keep startup time unaffected for non-docs traffic.
  • Update README.md (which currently documents GET /api/health, GET /api/apis, etc.) to mention the new GET /api/docs explorer.

Acceptance criteria

  • GET /api/docs returns an HTML page that renders Swagger UI against the existing spec.
  • The UI reads the same in-memory openApiSpec used by GET /api/openapi.json (no second copy of the contract).
  • The global Helmet CSP in src/app.ts is not weakened for non-docs routes.
  • Docs UI is gated in production behind a documented, default-off env flag.
  • README.md documents the new endpoint and the production flag.
  • New integration test asserts GET /api/docs responds 200 with text/html and that GET /api/openapi.json still returns the unchanged spec.

Suggested execution

1. Fork the repo and create a branch

git checkout -b feature/swagger-ui-docs

2. Implement changes — add the dependency and mount the explorer in src/routes/index.ts (reusing openApiSpec); add the optional production flag to src/config/env.ts / src/config/index.ts; update README.md.
3. Write/extend tests — add tests/integration/openapi-docs.test.ts (Jest + supertest, matching the existing *.test.ts convention used by tests/integration/health.test.ts).
4. Test and commit

npm run lint
npm run typecheck
npm test -- tests/integration/openapi-docs.test.ts --runInBand
npm run build

Example commit message

feat(docs): serve interactive Swagger UI for OpenAPI 3.1 contract

Guidelines

This repo targets 90%+ line coverage (see README.md "Target Coverage: 90%+"); keep new code at or above that bar. Add JSDoc to any new route handler and config field, and document the endpoint in README.md. Timeframe: 96 hours.

Metadata

Metadata

Assignees

No one assigned

    Labels

    GRANTFOX OSSGrantFox OSS programMAYBE REWARDEDGrantFox — potentially rewardedOFFICIAL CAMPAIGNGrantFox official campaignadvancedHigh complexity / deep contextbackendBackend servicedxDeveloper experienceenhancementNew feature

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions