Skip to content

Generate @gonext/api-types from existing OpenAPI spec — eliminate per-page envelope adapters #514

Description

@tayebmokni

Summary

`apps/api/openapi/openapi.yaml` is the hand-authored API source of truth. The admin app and `packages/ts/sdk` each define their own decoupled `Post` / `User` / `Media` types that drift from the wire format.

Confirmed impedance mismatches between server JSON and admin TypeScript Post type alone (8+ items):

  • Envelope: server `{data, pagination.next_cursor}` vs admin `{posts, nextCursor, total}`
  • Author: server `author_id` vs admin `author: {id, displayName}`
  • Dates: server has three (`published_at` / `updated_at` / `created_at`) vs admin's single `date`
  • `commentsCount`: admin expects, server doesn't emit
  • Cursor name: `pagination.next_cursor` vs `nextCursor`
  • Status enum drift between admin types and server's `validStatuses`
  • Nullable mismatches (server emits null timestamps, admin types as string)
  • Comments package solves this differently than posts — drift between sibling modules

Per-page adapters proliferating across:

  • `posts/page.tsx:121-144` — full envelope + field flattener
  • `comments/types.ts:91` — `WireComment` → `Comment` translator (the GOOD pattern)
  • `redirects/page.tsx:29`, `webhooks/page.tsx:37`, `jobs/dlq/page.tsx:46` — `data || []` chains
  • `marketplace/actions.ts:73,113` — `body.data ?? []`

Fix

  1. Add `packages/ts/api-types` workspace package.
  2. Wire `openapi-typescript` to generate `packages/ts/api-types/src/index.ts` from `apps/api/openapi/openapi.yaml` on build (or commit the generated file).
  3. Migrate `apps/admin` and `packages/ts/sdk` to import wire types from `@gonext/api-types`.
  4. Keep UI types (`Post` with `author.displayName`) as a transformed layer, but the wire side becomes single-source.

Why P1 not P0

The current per-page adapters work. This is technical debt, not a production-down issue. But every new admin page will accumulate a copy of the same pattern until this lands.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions