Skip to content

docs(api): TRA-743 — single-source OpenAPI spec, retire mirror#158

Merged
mikestankavich merged 1 commit into
mainfrom
worktree-tra-743-spec-singlesource
May 16, 2026
Merged

docs(api): TRA-743 — single-source OpenAPI spec, retire mirror#158
mikestankavich merged 1 commit into
mainfrom
worktree-tra-743-spec-singlesource

Conversation

@mikestankavich
Copy link
Copy Markdown
Contributor

TRA-743 — docs side of the "eliminate docs-side mirror, single source on platform" pivot.

Platform PR #357 (merged) removed info.contact.url from the spec source so the docs site can redirect spec asset requests to app.{env}.trakrf.id without re-introducing the URL-drift class TRA-742 / BB42 / BB43 surfaced. This PR lands the docs side: a redirect-based architecture in place of the mirrored static assets, plus retirement of every sync mechanism that existed only to service the mirror.

Architecture

  • Redoc /api page fetches the spec from app.{env}.trakrf.id/api/v1/openapi.yaml at build time (redocusaurus's URL form). Build container needs outbound access to the platform host; both deploy through the same CF/Railway pipeline so this is a non-issue.
  • /api/openapi.{json,yaml} 302-redirects to the platform via functions/_middleware.js. Env-aware off the docs request hostname (docs.trakrf.id → prod, docs.preview.trakrf.id → preview, anything else → preview). The five legacy alias paths (/api/v1/openapi.*, /openapi.*, /redocusaurus/trakrf-api.yaml) collapse to /api/openapi.* first, then chain to the platform via the same redirect.
  • Postman collection retired. Postman / Insomnia / Bruno / Hoppscotch all import from a URL. The static collection artifact was vestigial.

Why functions/_middleware.js instead of _redirects

Cloudflare Pages on this project does not honor _redirects (history note already in the middleware file, see TRA-598 / TRA-694). Pages Functions run in the Workers runtime ahead of static-asset serving and are config-independent, so the redirect lives there.

Deleted

Scripts: refresh-openapi.sh, swap-openapi-env.mjs, generate-postman.mjs, tests/blackbox/check-spec-sync.sh.

Static assets: openapi.{json,yaml}, trakrf-api.postman_collection.json (also dropped from .gitignore), platform-meta.json.

Components: src/components/SpecMirrorBadge.tsx and the callout that used it on docs/api/README.mdx. "Spec mirrored from " has no referent in a single-source world.

package.json scripts: predev, postbuild, refresh-openapi, generate-postman. prebuild keeps write-health-json.mjs (now docs-commit-only — the platform block is gone since platform identity lives on app.{env}.trakrf.id/health.json).

Dev dependency: openapi-to-postmanv2.

Rewritten

  • docs/api/postman.mdx — URL-import guidance for Postman, Insomnia, Bruno, Hoppscotch. Replaces "download this file" with "paste this URL."
  • docs/api/README.mdx — removes the SpecMirrorBadge callout; the codegen pointer now references the platform spec URLs directly.
  • docs/api/quickstart.mdx — §4 (Postman) and §5 (raw spec) updated; both now reference the platform URLs via <EnvBaseURL />.
  • README.md /health.json and "deploy modes" sections updated.

BB harness

  • check-spec-sync.sh (three-way diff: platform-source, docs-mirror, app-live) is gone. With no mirror there's no drift to detect.
  • check-deploy-lag.sh replaces it (simpler probe: is docs.preview.trakrf.id/health.json reporting origin/main's tip?). bb_cycle preflight loop preserved with the new probe — Cloudflare Pages build queue lag is still a real failure mode the BB cycle should fail-fast on.
  • BB.md §1 ("Fetch the spec") updated to describe the redirect-based architecture so the BB run doesn't misinterpret an /api/openapi.yaml 302 as a finding.

BACKLOG entry

tests/blackbox/BACKLOG.md gains the deferred-work entry for restoring info.contact.url. Trigger: helpdesk lands (Zendesk / Help Scout / Intercom) or a marketing /contact page with topic routing ships. Current state — info.contact.{name, email} only — renders fine in Redoc / Swagger UI; adding URL later is non-breaking by OpenAPI 3.0 design.

CORS — deferred

Per ticket. The 302 path works for browser navigation, curl, and programmatic fetch without Access-Control-Allow-Origin on the spec endpoint. Revisit if the docs site adds browser-side spec rendering that fetches the spec via XHR/fetch against a different origin.

Test plan

  • pnpm lint clean (excluding pre-existing spec/superpowers/** warnings)
  • pnpm typecheck clean
  • DEPLOY_ENV=preview pnpm build succeeds; Redoc /api page renders the preview-host spec (verified host strings present in build/api/index.html)
  • bash scripts/test_bb_cycle.sh — 8/8 pass with the new check-deploy-lag.sh probe
  • static/health.json emits just the docs block
  • Preview deploy: curl -IL https://docs.preview.trakrf.id/api/openapi.yaml follows 302 to app.preview.trakrf.id/api/v1/openapi.yaml (verified after merge)
  • Preview deploy: same for openapi.json and the five legacy aliases (/api/v1/openapi.*, /openapi.*, /redocusaurus/trakrf-api.yaml chain through cleanly)
  • Preview deploy: the rendered /api page on docs.preview.trakrf.id shows the current operation set with no contact.url field
  • Prod equivalents after main → preview cut

🤖 Generated with Claude Code

Platform PR #357 removed `info.contact.url` from the spec source so the
docs site can redirect spec asset requests to the platform without
re-introducing the URL-drift class BB42/BB43 surfaced. This is the docs
side of that pivot.

- Redocusaurus `/api` page now fetches the spec from
  `app.{env}.trakrf.id/api/v1/openapi.yaml` at build time. No bundled
  spec copy lives in the docs repo anymore.
- `functions/_middleware.js` 302-redirects `/api/openapi.{json,yaml}`
  (and the five legacy aliases) to the platform origin, env-aware via
  the docs request hostname.
- Mirror sync machinery retired: `refresh-openapi.sh`,
  `swap-openapi-env.mjs`, `generate-postman.mjs`, the bundled
  `openapi.{json,yaml}`, `platform-meta.json`, the Postman collection,
  `check-spec-sync.sh`, and the `predev`/`postbuild` package.json
  hooks plus `openapi-to-postmanv2` are all gone.
- Postman page rewritten to URL-import guidance for Postman, Insomnia,
  Bruno, and Hoppscotch. Quickstart's Postman + raw-spec sections
  updated to match.
- `SpecMirrorBadge` and its callout deleted — "spec mirrored from"
  has no referent in a single-source world.
- `docs/health.json` keeps the `docs.{commit, build_time}` block;
  the `platform` block is gone (platform identity lives on
  `app.{env}.trakrf.id/health.json`).
- `BB.md` updated to describe the redirect; `check-deploy-lag.sh`
  replaces the spec-sync preflight (simpler probe: is preview docs on
  `origin/main`?). `bb_cycle` preflight loop preserved with the new
  probe.
- `BACKLOG.md` gains the deferred-work entry for restoring
  `info.contact.url` (trigger: helpdesk or topic-routing /contact
  page lands).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

🚀 Preview Deployment Update

✅ This PR has been successfully merged into the preview branch.

The preview environment will update shortly at: https://docs.preview.trakrf.id

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 16, 2026

Deploying docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: 7ec727c
Status: ✅  Deploy successful!
Preview URL: https://9d998333.docs-4n7.pages.dev
Branch Preview URL: https://preview.docs-4n7.pages.dev

View logs

@mikestankavich mikestankavich merged commit b76860d into main May 16, 2026
2 checks passed
@mikestankavich mikestankavich deleted the worktree-tra-743-spec-singlesource branch May 16, 2026 14:39
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.

1 participant