Skip to content

Frontend: shared typed API client generated from the OpenAPI export (replace ~34 hand-rolled fetch calls) #504

Closed

Description

@antosubash

Tier 2: structural

Problem

  • About 34 non-test files call fetch() directly. Examples: tenants/components/{InviteForm,MembersTable,CreateOrgForm}.tsx, users/pages/{Login,Register,ResetPassword}.tsx, settings/.../ModuleForm.tsx, file_storage/pages/Browse.tsx:94,119, branding/pages/Manage.tsx:92-119.
  • Each call repeats method, headers, credentials, JSON parsing, detail extraction and toast.error, and the calls have already drifted. Browse.tsx sends no credentials, InviteForm sends same-origin, and api_tokens/pages/api.ts sends a CSRF header.
  • packages/ui/src/lib has no HTTP helper.
  • The OpenAPI export from hosting: first-class OpenAPI export for typed client generation (title/version, operationIds, CLI export) #456 (make openapi) is used by nothing. Response bodies are cast by hand, for example (await response.json()) as { accept_url: string }. There are 29 .json() calls.

Cost

Any cross-cutting change, such as CSRF opt-in, a 401 redirect or request-id propagation, has to touch every call site. Request and response shapes drift silently from the SQLModel DTOs.

Proposal

  1. Add packages/ui/src/lib/api.ts: a typed apiRequest<T>() returning { ok, data, detail, status }, which centralises credentials, the CSRF header and error toasts.
  2. Generate types with openapi-typescript into a packages/api-types workspace, and add a CI drift check (make openapi && git diff --exit-code).
  3. Migrate module by module, starting with tenants and users.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions