feat(contracts,api,upload,content): generate /openapi.json from Zod schemas#15
Conversation
|
Caution Review failedPull request was closed or merged during review WalkthroughThis PR refactors OpenAPI document generation across Agent Paste's API, Content, and Upload worker applications. Instead of maintaining hand-written OpenAPI schemas in each worker, the PR centralizes generation using Zod schemas from a shared contracts package. A new Zod wrapper enables OpenAPI metadata annotations on schemas. Three document builder functions generate OpenAPI 3.1 specifications dynamically, accepting environment-based server URLs. Golden JSON files serve as reference contracts. A CLI script validates that generated documents match golden files in CI. Each worker app now imports and calls the appropriate builder when serving Sequence DiagramsequenceDiagram
participant Client
participant Worker as API/Content/Upload Worker
participant Handler as /openapi.json Handler
participant Builder as buildApiOpenApiDocument
participant Registry as OpenAPIRegistry
participant Generator as OpenApiGeneratorV31
Client->>Worker: GET /openapi.json
Handler->>Builder: Call buildXxxOpenApiDocument(options)
Builder->>Registry: Create registry
Builder->>Registry: Register schemas, security, endpoints
Builder->>Generator: Generate from registry
Generator->>Builder: OpenAPI 3.1 Document
Builder->>Handler: Return Record<string, unknown>
Handler->>Client: 200 + OpenAPI JSON
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add Comment |
3bad1b6 to
3afb7db
Compare
82a8182 to
7e9d4a5
Compare
3afb7db to
1807c4e
Compare
…chemas Replace hand-written OpenAPI documents in api/upload/content with documents generated from the Zod schemas in `packages/contracts` using `@asteasolutions/zod-to-openapi` (the peer that powers `@hono/zod-openapi`). The generators live in `packages/contracts/src/openapi/` and emit one document per Worker. `pnpm openapi:check` diffs every served document against a checked-in golden under `packages/contracts/openapi/`; a forced-drift smoke confirms the check fails on any mismatch. `pnpm verify` now runs `openapi:check` so CI catches contract drift. A central `packages/contracts/src/zod.ts` extends Zod with `.openapi()` before any schema is constructed, which Zod 4 requires. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Drop the 401 response from the public Agent View route, which has no security requirement. - Introduce a dedicated `RateLimitErrorEnvelope` schema so 429 responses only advertise `rate_limited_actor`/`rate_limited_workspace` codes instead of the full error code enum. - Inline single-use helpers in the content generator and drop the pointless `zod-setup` re-export. Deferred (recorded for the follow-up SDK work, not in scope for this PR): list operations still surface `page_info.next_cursor` without a matching `cursor` query parameter, and the admin api-key create body still mirrors `workspace_id` from the path. Both are pre-existing contract shapes used by `packages/api-client`; changing them is a contract migration, not an OpenAPI generation task. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
7e9d4a5 to
dc7742f
Compare
|
agent-paste PR preview resources were cleaned up. The pr-preview-${context.issue.number} environment is left in place; remove it from the GitHub UI if desired. |
Summary
/openapi.jsonforapi,upload, andcontentWorkers from the Zod contracts inpackages/contractsusing@asteasolutions/zod-to-openapi(the peer that backs@hono/zod-openapi; the Workers ship plain Hono routes so the generator is used directly).pnpm openapi:checktask (wired intopnpm verifyand Turbo) diffs every served document against goldens underpackages/contracts/openapi/;pnpm openapi:writerefreshes them.openapi:checkto exit 1.Implementation notes
packages/contracts/src/zod.tsextends Zod with.openapi(...)before any schema is constructed (Zod 4 requirement). Every schema module routes through it so the order is deterministic.packages/contracts/src/openapi/keeps each file under 300 LOC.openApiDocument()helpers in all three Workers (~200 LOC each) are deleted in favor of a one-line call into the contract builder.RateLimitErrorEnvelopewhoseerror.codeenum is narrowed torate_limited_actor/rate_limited_workspaceonly (CodeRabbit major).CodeRabbit triage
coderabbit review --agentreturned 8 findings against this branch.zod-setupre-export; consumers importzfrom../zod.jsdirectly.paramsandfileBytesResponsehelpers incontent.ts.params/fileBytesResponse(same finding as #2).page_info.next_cursorexists in the existing contract but list routes don't acceptcursoryet. Adding pagination is a route-layer change, out of scope for OpenAPI generation.RateLimitErrorEnvelopewith a narrowederror.codeenum.agentView.publicroute.CreateApiKeyRequestrequiresworkspace_idin body even when the path provides it. Pre-existing contract used bypackages/api-client; changing it is a contract migration, not an OpenAPI generation task.as unknown as Record<string, unknown>cast. Workers return JSON viac.json(...), which wantsRecord<string, unknown>. ImportingOpenAPIObjectfromopenapi3-ts/oas31would still require a cast at the call site, so the indirection isn't worth it.Test plan
pnpm verify(60/60 Turbo tasks)packages/contracts/openapi/content.jsonthenpnpm openapi:checkexits 1; restore then exit 0.Stacked on
worktree-agent-a14b512aa4365cfc5(PR #10) for theX-Request-Id+request_idplumbing.Summary by CodeRabbit
Release Notes
New Features
/openapi.json) now serve auto-generated, up-to-date documentation for the API, Content, and Upload services.Documentation
Chores