Skip to content

docs: the pages describe the order-api that ships, and a gate keeps them there - #77

Merged
btravers merged 9 commits into
mainfrom
fix/docs-describe-shipped-order-api
Aug 20, 2026
Merged

docs: the pages describe the order-api that ships, and a gate keeps them there#77
btravers merged 9 commits into
mainfrom
fix/docs-describe-shipped-order-api

Conversation

@btravers

Copy link
Copy Markdown
Contributor

Closes #75. Contributes to #53.

The problem was worse than "stale"

Six documentation pages described examples/order-api before it had
authentication — and their samples do not compile against the shipped code:

// what the pages showed          // what the code has
place.execute(input.id, input.quantity)
                                 PlaceOrder.execute(tenantId, id, quantity)
find.execute(input.id)           FindOrder.execute(tenantId, id)

Ten call sites passing an order id where a tenant goes. Every one of those pages
claims to be showing the real thing — "lifted from examples/order-api", "the
real deployment this recipe describes", "examples/order-api's orders slice" —
so they could not stay unauthenticated while pointing at a marked example.

The drift came in with #73 and survived because nothing compiles these
samples
.

What changed

Five pages take the mechanical edit: the contract fragment gains
authenticated(...), the controller destructures context and passes
context.principal.tenantId first, the slice imports HttpController from the
application's own src/auth.ts, and prose describing the tenant as an input
field is corrected.

docs/examples/order-api.md needed more. It documents the example file by file,
so it was missing a whole file: no src/auth.ts, no src/authenticator.ts, it
never named httpAuth<Identity>(), and its slice table listed four paths where
the example ships five. It now has a section on the identity factory — the
contract says whether a route is protected, httpAuth<Identity>() says what
the principal is — a corrected file table, and five compile-time gates where it
listed three.

The gate — the actual fix

examples/order-api/src/docs-examples.test-d.ts, following
packages/core/src/docs-examples.test-d.ts's shape: a header saying what it is,
then sections each naming the page it mirrors. It carries the corrected
controllers, the keyed router, the HttpModule root with its authenticator, and
the lifted single-slice root.

Compiled against the real PlaceOrder / FindOrder / contract, not stubs
— a stub would have accepted all ten broken calls, which is exactly how this
survived.

Verified to bite, in both directions:

  • reverting the tenant argument → TS2554: Expected 3 arguments, but got 2
  • importing HttpController / HttpRouter from @btravstack/http instead of
    the application's ./auth.js → five × TS2339: Property 'tenantId' does not exist on type 'never'

The root CLAUDE.md's "Deferred, deliberately" entry is updated: its own
trigger was "add it the next time one of those samples is found to have
drifted", and that fired twice in two days — the Unauthenticated({ reason })
samples in #73, and this.

Two things worth a reviewer's eye

docs/how-to/serve-orpc-over-http.md now marks its contract, and it bills
itself as "a minimal, standalone illustration". The argument for marking: it
imports the real PlaceOrder, so it needs a tenant from somewhere, and the
shipped contract no longer carries one on the input. The argument against: auth
has its own how-to, and a minimal recipe should not introduce a concept it then
explains how to remove. It is currently marked, with a paragraph saying exactly
how to make it public and what changes if you do. An eight-line revert if you
would rather that page stay public
— say so and I will flip it.

What the gate does not cover. The pages' zod contract fragments are not
compiled by the new file: zod and @btravstack/contract are the contract
workspace's dependencies, not order-api's. A fragment is gated where it lives.
What is covered is everything downstream — so a marker removed from the real
contract still fails this file, because the controllers are typed by it.

Gate

format --check (439 files) · lint · typecheck 31/31 · knip · test
29/29 · docs build — all green. @btravstack/example-order-api:typecheck was
re-run with --force to prove the new file was compiled rather than cached.

Copilot AI lite review requested due to automatic review settings August 20, 2026 15:16

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the documentation site’s HTTP (order-api) examples to reflect the authenticated orders fragment introduced in examples/order-api, and adds a compile-time type-test gate in the example workspace so these docs-aligned samples can’t drift again.

Changes:

  • Add examples/order-api/src/docs-examples.test-d.ts to typecheck the key docs samples against the real contract and real use cases.
  • Update multiple docs pages to show authenticated(...) contracts and tenant resolution via context.principal.tenantId (plus authenticator wiring at the root).
  • Update the root CLAUDE.md “Deferred, deliberately” entry to record that the HTTP docs gate is now implemented (in the example workspace).

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
examples/order-api/src/docs-examples.test-d.ts New type-level gate compiling the docs’ HTTP samples against the real example code.
docs/reference/http.md Updates router sample to use principal-derived tenant for authenticated fragments.
docs/index.md Updates the homepage “At a glance” sample to reflect authenticated contracts and root authenticator wiring.
docs/how-to/split-a-router-into-controllers.md Updates contract/controller/root samples and prose to match authenticated orders and public customers.
docs/how-to/serve-orpc-over-http.md Updates the minimal recipe to include authenticated contracts and authenticator-aware composition.
docs/explanation/the-kernel-maps-nothing.md Updates the example snippet to show tenant coming from context.principal.
docs/examples/order-api.md Refreshes the end-to-end example page (auth, authenticator, controller calls, gates) to match what ships.
CLAUDE.md Documents that the HTTP docs samples are now gated via the new example type-test file.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread docs/how-to/serve-orpc-over-http.md
Comment thread docs/how-to/split-a-router-into-controllers.md
Comment thread docs/examples/order-api.md
Three from review, one of them a repeat: split-a-router's customers fragment
typed its NOT_FOUND payload with orderRef — the same defect fixed in the real
contract in #76, propagated into a sample the sweep touched but did not
question. It has its own customerRef now, with the comment saying why.

serve-orpc-over-http still said 'Two gates hold at compile time' after this
branch marked its contract, which adds a third. And the example page's
authenticator fence referenced HttpAuthenticator, Unauthenticated, ErrAsync
and OkAsync without importing any of them.

Both changed fences extracted and compiled in scratch files, then deleted.
@btravers
btravers merged commit 457bcb7 into main Aug 20, 2026
13 checks passed
@btravers
btravers deleted the fix/docs-describe-shipped-order-api branch August 20, 2026 15:29
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.

Six docs pages still describe order-api before it had authentication

2 participants