Skip to content

docs(api): generate OpenAPI examples#4625

Merged
koala73 merged 6 commits into
mainfrom
codex/issue-4610-openapi-examples
Jul 2, 2026
Merged

docs(api): generate OpenAPI examples#4625
koala73 merged 6 commits into
mainfrom
codex/issue-4610-openapi-examples

Conversation

@koala73

@koala73 koala73 commented Jul 1, 2026

Copy link
Copy Markdown
Owner

Summary

  • Adds a post-generation OpenAPI examples injector for WorldMonitor service specs and the unified bundle.
  • Wires the injector into make generate and exposes npm run gen:openapi:examples.
  • Regenerates all OpenAPI artifacts so 192/192 operations carry response examples and all 137 request-bearing operations carry parameter/body examples.
  • Adds a parser-based regression test that validates JSON, per-service YAML, and bundled YAML examples against schemas.

Intent

Fixes #4610 by filling the generated OpenAPI docs with deterministic, schema-valid request/response examples.

Non-goals: no runtime API behavior changes, no auth/gateway changes, no manual per-endpoint example authoring.

Validation Matrix

Check Reason Result
Already-fixed gate on origin/main Verify #4610 still reproduced before implementation Failed as expected: 34 service JSON specs, 192 ops, 137 request targets, withReq=0, withResp=0
node scripts/openapi-inject-examples.mjs --check Injector idempotency and coverage Pass: 34 specs + bundle carry generated examples (192 operations)
node --test tests/openapi-examples-contract.test.mjs Focused acceptance regression Pass: JSON/YAML/bundle examples present and schema-valid
node scripts/openapi-inject-security.mjs --check Adjacent OpenAPI auth contract safety Pass
node --test tests/openapi-security-contract.test.mjs tests/openapi-examples-contract.test.mjs Source-affinity OpenAPI contracts Pass: 143 tests
./node_modules/.bin/biome lint scripts/openapi-inject-examples.mjs tests/openapi-examples-contract.test.mjs Focused lint on new code/tests Pass
npm run lint Broad lint/safe-html Pass; existing warnings outside this diff remain warnings only
npm run typecheck App TypeScript check Pass
npm run typecheck:api API TypeScript + Convex string-call audit Pass
npm run docs:check Docs stats parity Pass: 73 doc claims match code
git diff --check Whitespace/conflict markers Pass

Review Gates

  • Baseline reviewer: Pass; generated docs spot-checked, no runtime/auth behavior changed.
  • Code Review Expert: Pass; no P0/P1/P2/P3 findings or removal candidates.
  • Outcome reviewer: Pass; issue contract reread and validation evidence covers all 192 operations.

Documentation

Generated OpenAPI docs updated under docs/api/ for service JSON, service YAML, and worldmonitor.openapi.yaml. No prose docs required.

Screenshots / UI Evidence

Not applicable: generated API documentation contract only, no UI change.

Residual Findings

None.

@vercel

vercel Bot commented Jul 1, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
worldmonitor Ready Ready Preview, Comment Jul 2, 2026 1:21pm

Request Review

@greptile-apps

greptile-apps Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds a post-generation OpenAPI examples injector (scripts/openapi-inject-examples.mjs) that derives deterministic, schema-valid request/response examples from the generated OpenAPI contracts and surgically injects them into 34 service JSON specs, 34 service YAML specs, and the unified bundle. A paired regression test (tests/openapi-examples-contract.test.mjs) validates that every operation carries schema-conforming examples.

  • The injector follows the same pattern as the existing openapi-inject-security.mjs: wired into make generate and exposed as npm run gen:openapi:examples, with a --check mode for idempotency verification.
  • A two-pass stabilisation loop ensures the injected output is self-consistent before writing to disk.
  • The 70 generated docs/api/ artifacts are the expected output of running the injector against the current proto surface (192 operations across 34 services).

Confidence Score: 4/5

Safe to merge — the change is purely additive documentation generation with no runtime or auth behavior changes.

The injector and test are well-structured: idempotency is verified by a stabilisation pass, the --check mode guards against stale artifacts, and the regression test validates schema constraints across all 192 operations. Two issues reduce confidence slightly: patternString has an overly-broad substring check that can misclassify non–country-code patterns as ISO codes, and requestOperations double-counts operations that carry both query parameters and a JSON body, making the console metric misleading. Neither affects the correctness of the generated artifact content.

scripts/openapi-inject-examples.mjs — the pattern-matching logic in patternString and the requestOperations counter warrant a second look.

Important Files Changed

Filename Overview
scripts/openapi-inject-examples.mjs New 565-line post-generation injector that derives schema-valid examples and inserts them into 34 service JSON specs, 34 service YAML specs, and the unified bundle. Logic is sound; two minor issues: requestOperations double-counts operations with both params and a request body, and patternString has an overly-broad substring match for ISO country-code patterns.
tests/openapi-examples-contract.test.mjs Regression test covering JSON spec, per-service YAML, and bundle examples. Validates schema constraints (type, minimum/maximum, minLength/maxLength, pattern, enum). Hard-coded exact counts (34 specs, 192 ops) will require manual bumps when new endpoints are added.
Makefile Adds node scripts/openapi-inject-examples.mjs after the security injector in the generate target; correctly sequenced and comment updated.
package.json Adds gen:openapi:examples npm script alongside the existing gen:openapi:security entry; no other changes.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[make generate] --> B[buf generate\nproto stubs + OpenAPI shapes]
    B --> C[openapi-inject-security.mjs\nadd securitySchemes / 401]
    C --> D[openapi-inject-examples.mjs\nfirst pass]
    D --> E{any spec\nchanged?}
    E -- yes --> F[openapi-inject-examples.mjs\nstabilisation pass]
    E -- no --> G[done]
    F --> G

    D --> D1[processServiceSpec x 34\nJSON + YAML surgical patch]
    D --> D2[processBundle\nworldmonitor.openapi.yaml]

    D1 --> D1a[injectSpecExamples\nmutate in-memory spec]
    D1a --> D1b[serialize write .json]
    D1a --> D1c[patchYamlExamples\nwrite .yaml]

    D2 --> D2a[parseYaml + injectSpecExamples]
    D2a --> D2b[patchYamlExamples\nwrite bundle]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[make generate] --> B[buf generate\nproto stubs + OpenAPI shapes]
    B --> C[openapi-inject-security.mjs\nadd securitySchemes / 401]
    C --> D[openapi-inject-examples.mjs\nfirst pass]
    D --> E{any spec\nchanged?}
    E -- yes --> F[openapi-inject-examples.mjs\nstabilisation pass]
    E -- no --> G[done]
    F --> G

    D --> D1[processServiceSpec x 34\nJSON + YAML surgical patch]
    D --> D2[processBundle\nworldmonitor.openapi.yaml]

    D1 --> D1a[injectSpecExamples\nmutate in-memory spec]
    D1a --> D1b[serialize write .json]
    D1a --> D1c[patchYamlExamples\nwrite .yaml]

    D2 --> D2a[parseYaml + injectSpecExamples]
    D2a --> D2b[patchYamlExamples\nwrite bundle]
Loading

Reviews (1): Last reviewed commit: "docs(api): generate OpenAPI examples" | Re-trigger Greptile

Comment thread scripts/openapi-inject-examples.mjs
Comment thread scripts/openapi-inject-examples.mjs Outdated
Comment thread tests/openapi-examples-contract.test.mjs
@mintlify

mintlify Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
WorldMonitor 🟢 Ready View Preview Jul 1, 2026, 10:09 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@koala73
koala73 merged commit aa0f997 into main Jul 2, 2026
25 checks passed
@koala73
koala73 deleted the codex/issue-4610-openapi-examples branch July 2, 2026 13:23
koala73 added a commit that referenced this pull request Jul 2, 2026
The per-service YAML specs (docs/api/*Service.openapi.yaml) and the served
bundle (worldmonitor.openapi.yaml → public/openapi.yaml) carried only the
entitlement 403s from the injector chain — never the auth half the per-service
JSON specs already have. PR #4602 deferred per-op YAML auth surgery, and the
sibling injectors (#4621/#4623/#4625/#4626) that later reached the YAML never
backfilled it.

This generalizes the bundle-only top-level insertion into a reusable
injectYamlAuthContract() applied to BOTH the per-service YAML loop and the
bundle, reaching full parity with injectJson():
- top-level securitySchemes (2 API-key, or 3 incl. BearerAuth when the artifact
  has a bearer-capable op — mirrors expectedSchemesForSpec)
- root API-key security requirement
- UnauthorizedError schema
- per-operation 401 on authenticated ops (185), security:[] opt-outs on the 7
  public RPCs, and BearerAuth stamping on the ~19 entitlement/premium ops

Reuses the entitlement pass's YAML range-finders; js-yaml is used read-only to
enumerate operation paths (handling the one multi-method path,
/api/v2/shipping/webhooks); all writes stay formatting-preserving and
additions-only. The narrower injectBundle() is removed.

Scope note: widened from the plan's bundle-only DoD to all 34 per-service YAML
after discovering they shared the identical gap (confirmed with the user).

Verified: 401 parity 185 (per-service YAML) / 185 (bundle); idempotent (full
Makefile injector chain re-run = 0 drift); per-service JSON byte-unchanged;
395 contract tests pass (incl. mcp-api-parity, doc-parity, deploy-config).

Claude-Session: https://claude.ai/code/session_01EsjtheWqt8GxEZfd3DyTMu
koala73 added a commit that referenced this pull request Jul 3, 2026
…e + per-service parity (#4650) (#4654)

* fix(api): extend OpenAPI auth injection to all YAML artifacts (#4650)

The per-service YAML specs (docs/api/*Service.openapi.yaml) and the served
bundle (worldmonitor.openapi.yaml → public/openapi.yaml) carried only the
entitlement 403s from the injector chain — never the auth half the per-service
JSON specs already have. PR #4602 deferred per-op YAML auth surgery, and the
sibling injectors (#4621/#4623/#4625/#4626) that later reached the YAML never
backfilled it.

This generalizes the bundle-only top-level insertion into a reusable
injectYamlAuthContract() applied to BOTH the per-service YAML loop and the
bundle, reaching full parity with injectJson():
- top-level securitySchemes (2 API-key, or 3 incl. BearerAuth when the artifact
  has a bearer-capable op — mirrors expectedSchemesForSpec)
- root API-key security requirement
- UnauthorizedError schema
- per-operation 401 on authenticated ops (185), security:[] opt-outs on the 7
  public RPCs, and BearerAuth stamping on the ~19 entitlement/premium ops

Reuses the entitlement pass's YAML range-finders; js-yaml is used read-only to
enumerate operation paths (handling the one multi-method path,
/api/v2/shipping/webhooks); all writes stay formatting-preserving and
additions-only. The narrower injectBundle() is removed.

Scope note: widened from the plan's bundle-only DoD to all 34 per-service YAML
after discovering they shared the identical gap (confirmed with the user).

Verified: 401 parity 185 (per-service YAML) / 185 (bundle); idempotent (full
Makefile injector chain re-run = 0 drift); per-service JSON byte-unchanged;
395 contract tests pass (incl. mcp-api-parity, doc-parity, deploy-config).

Claude-Session: https://claude.ai/code/session_01EsjtheWqt8GxEZfd3DyTMu

* fix(api): close JSON/YAML parity gaps in OpenAPI auth injector

Follow-up hardening on the YAML auth-contract injector so it fully
mirrors injectJson and stays convergent under source-of-truth edits:

- Per-method entitlement stamping: injectYamlEntitlementContract now
  iterates every HTTP method of a gated path (via enumerateYamlOperations)
  instead of only the first, so a multi-method entitlement path gets the
  403 + PRO-gated note on all methods, matching the JSON sibling.
- Skip public paths in the entitlement pass, mirroring injectJson's
  isPublic-first branch (a public+entitlement overlap no longer stamps a
  stray ForbiddenError 403 on the YAML).
- Auth pass now removes stale operation-level artifacts: a public op drops
  a leftover 401 (removeYamlUnauthorizedResponse), and a non-bearer op
  strips a leftover BearerAuth security block (removeYamlOperationSecurity),
  matching injectJson's delete-op.security / delete-op.responses['401'].
- Fail closed when a path appears in both ENDPOINT_ENTITLEMENTS and
  PUBLIC_FORBIDDEN_GATES, which would otherwise oscillate the 403 body on
  every run and permanently break the pre-push freshness gate.

Removed the now-unused first-method-only findYamlOperationRange. All fixes
target latent reclassification cases; the 34 committed YAML artifacts +
bundle are byte-unchanged (make-generate idempotent, --check clean) and
all 246 contract tests pass.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_014Ua87UaGSbnHspLCZwfNZK

* fix(api): close residual JSON/YAML parity gaps found in adversarial review

Follow-up to the parity fixes, closing three latent divergences surfaced
by adversarial validation (all dormant under the current config; the 34
YAML artifacts + bundle stay byte-unchanged and --check is clean):

- Quoted-scalar descriptions: appendNoteToYamlScalar now inserts the
  entitlement/gate note INSIDE a single- or double-quoted description scalar
  instead of after the closing quote, which previously produced unparseable
  YAML for any gated op whose description the generator chose to quote (e.g.
  one containing ": "). The per-method stamping had widened this pre-existing
  hazard's blast radius.
- ForbiddenError schema parity: set matchedEntitlementPath before the
  public-path opt-out so a spec whose only entitlement path is also public
  still emits the ForbiddenError schema, matching injectJson's
  public-agnostic hasEntitlementPath.
- Public-forbidden-gate parity: skip non-public gate paths in the gate loop,
  mirroring injectJson which applies the bot-verification 403 only inside its
  isPublic branch (a non-public gate path now takes the authenticated 401
  path instead of getting a stray bot 403).

Validated end-to-end against synthetic fixtures (quoted single/double
scalars, public-only entitlement spec, non-public gate path): output is
valid YAML, idempotent, and matches the JSON contract. 246 contract tests
still pass.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_014Ua87UaGSbnHspLCZwfNZK

---------

Co-authored-by: Claude <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs(api): emit request/response examples across all OpenAPI specs (#4599)

1 participant