feat(api-types): @codespar/api-types — shared Zod contract for api.codespar.dev - #12
Merged
Merged
Conversation
…pi.codespar.dev
Single source of truth for every /v1/* REST shape (api-keys, projects,
connections, servers, sessions). Ships Zod schemas + inferred TS types so
both the enterprise backend and the web dashboard can import the same
contract instead of hand-rolling mirror interfaces.
Two bugs in codespar-web last week traced back to that duplication:
- #155: POST /v1/api-keys omitted revoked_at; web assumed present,
undefined !== null rendered a freshly-created key as "Revoked"
- #156: GET /v1/api-keys returns { keys }; web parsed data.api_keys,
list came up empty
Both regressions are captured in the test suite so the schemas can't
drift back into the broken shapes. Next PRs adopt these types in
codespar-enterprise routes + codespar-web Server Actions.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2 tasks
fabianocruz
added a commit
that referenced
this pull request
Apr 24, 2026
## Summary - Follow-up to #12: the initial `ConnectionRowSchema` claimed `org_id` and `project_id`, but the backend's `serializeConnection()` strips both before sending. Any runtime `.parse()` of a real `/v1/connections` response would have failed. - Drops both fields + updates the test. ## Why it matters Discovered while adopting the schema in codespar-enterprise#41 — the fix was written but landed on the `feat/api-types-package` branch *after* #12 was squash-merged. This PR brings main to the correct shape before publishing `@codespar/api-types@0.1.0` to npm. ## Test plan - [x] `npm run build -w @codespar/api-types` — clean - [x] `npm run test -w @codespar/api-types` — 14/14 pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
@codespar/api-types(v0.1.0) — Zod schemas + inferred TS types for every/v1/*REST shape the managed-tier API exposes today (api-keys, projects, connections, servers, sessions).codespar-enterprise(backend) andcodespar-web(dashboard) to import, replacing today's duplicated hand-rolled interfaces on both sides.Why
Two regressions in the last 48h traced back to type duplication between web and backend:
POST /v1/api-keysresponse omitsrevoked_at; web type assumed present;undefined !== nullrendered a freshly-created key as Revoked.GET /v1/api-keysreturns{ keys }; web parseddata.api_keys; list came up empty on refresh.Both are regression-pinned in the test suite (see
src/index.test.ts). Parsing responses at the fetch boundary with these schemas would have caught each one at runtime with a useful ZodError instead of silently rendering a broken UI.Coverage
api-keysCreateApiKeyRequest,CreatedApiKey,ApiKeyRow,ListApiKeysResponseprojectsCreateProjectRequest,UpdateProjectRequest,ProjectRow,ListProjectsResponseconnectionsCreateConnectionRequest,ConnectionRow,ListConnectionsResponse,RotateWebhookSecretRequest/ResponseserversServerRow,ListServersResponse,ServerAuthSchemaResponsesessionsCreateSessionRequest,SessionRow,SessionDetail,ListSessionsResponse,ToolCallRow,ListToolCallsResponse,ExecuteToolRequest/ResponseDesign choices
z.infer, not hand-written types. Compile-time catches the easy drift; runtime.parse()at the fetch boundary catches the rest. Same schema serves both.TimestampSchema = z.string().datetime({ offset: true }). Fastify auto-serializesDateto ISO-8601 — the wire always carries strings, never JS Date objects. Codified once so no route has to remember.@codespar/types.@codespar/typesis the session runtime contract used by the public SDK. REST admin shapes (ApiKeyRow, etc.) are a different audience — dashboards and internal tools, not agent authors. Keeping them apart avoids leaking internal-facing types into the SDK's public surface.Test plan
npm run build -w @codespar/api-types— clean tscnpm run test -w @codespar/api-types— 14/14 passnpm run buildat monorepo root — 17/17 packages build cleannpm testat monorepo root — 33/33 pass@codespar/api-types@0.1.0to npm after mergecodespar-enterprise— adopt in routes, validate responsescodespar-web— delete duplicated types, import from@codespar/api-types🤖 Generated with Claude Code