Skip to content

Commit 123ced3

Browse files
committed
Add endpoint-level OpenAPI coverage
1 parent 819f4ea commit 123ced3

9 files changed

Lines changed: 4841 additions & 346 deletions

File tree

.github/workflows/ci.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,13 @@ jobs:
5454
run: pnpm test
5555

5656
- name: OpenAPI drift gate
57-
# Regenerates the stub from the Zod schemas and fails if it
58-
# differs from the committed artefact at
59-
# `docs/openapi.stub.json`. Forces every DTO change to land
60-
# together with its spec update.
57+
# Regenerates the spec from the Zod schemas and route
58+
# definitions and fails if it differs from the committed
59+
# artefact at `docs/openapi.json`. Forces every DTO or route
60+
# change to land together with its spec update.
6161
run: |
6262
pnpm openapi
63-
git diff --exit-code docs/openapi.stub.json
63+
git diff --exit-code docs/openapi.json
6464
6565
- name: Next.js build
6666
run: pnpm build

apps/docs/src/content/docs/openapi.mdx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ title: OpenAPI Spec
33
description: Machine-readable OpenAPI schema for the API
44
---
55

6-
The full OpenAPI schema describes every endpoint, parameter, and response shape. Use it with code generators, Swagger/Redoc viewers, or Postman.
6+
The OpenAPI 3.0.3 document describes every endpoint with its parameters, response envelopes, and error shape. Use it with code generators, Swagger/Redoc viewers, or Postman.
77

88
```
99
https://l2api.dev/api/openapi.json
1010
```
11+
12+
List rows, drops, shops, hennas, and meta endpoints carry exact schemas. The large detail responses (item, NPC, quest, class, armor set, raw NPC) currently document their stable top-level fields and allow additional properties — full field-level precision for those is planned. The prose contract in the repo's `docs/api-contract.md` remains the authoritative field reference.

docs/api-contract.md

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -784,24 +784,35 @@ to do in one shot and is being staged in three phases.
784784
compile-time
785785
`Expect<Equals<z.infer<typeof Schema>, ExistingDto>>` assertion, so
786786
any drift between the schema and the hand-written interface fails
787-
`pnpm typecheck`. A stub OpenAPI document
788-
(`docs/openapi.stub.json`) is regenerated by `pnpm openapi`. The
789-
schemas file is **not imported by route handlers**, so Zod stays
790-
out of the runtime lambda bundle. Public response shapes are
791-
unchanged by Phase A — schemas are an additive type-system safety
792-
net, not a runtime validator.
787+
`pnpm typecheck`. The OpenAPI document (`docs/openapi.json`) is
788+
regenerated by `pnpm openapi`. The schemas file is **not imported
789+
by route handlers**, so Zod stays out of the runtime lambda bundle.
790+
Public response shapes are unchanged by Phase A — schemas are an
791+
additive type-system safety net, not a runtime validator.
792+
793+
**Endpoint-level path coverage (landed)**
794+
`scripts/audit/generate-openapi.ts` registers every public route
795+
under `src/app/api/[chronicle]/` with its path/query parameters,
796+
the `{ data }` / `{ data, meta }` envelopes, and the shared
797+
`{ error, status }` error schema. List/summary, drop, item-source,
798+
shop, meta-count, raw-spawn, and henna-detail schemas are **exact**
799+
and carry the same compile-time `Equals` assertions (checked by
800+
`pnpm typecheck:scripts`). The large detail schemas (`ItemDetail`,
801+
`NpcDetail`, `QuestDetail`, `ClassDetail`, `ArmorSet`, `RawNpc`)
802+
are **approximate**: they document the stable top-level fields and
803+
set `additionalProperties: true` pending Phase B.
793804

794805
**Phase B (deferred)** — migrate the larger DTOs (`ItemDetailDto`,
795806
`NpcDetailDto`, `QuestDetailDto`, etc.) one at a time and switch
796807
their TypeScript types to `z.infer<typeof ...>`, making schemas the
797808
source of truth. Each migration must pass the existing snapshot
798809
suite without diff. Routes still don't validate at runtime.
799810

800-
**Phase C (deferred)**register every route's request/response in
801-
the OpenAPI registry and generate a complete spec. The Phase-A stub
802-
is already published at runtime via `GET /api/openapi.json`, so
803-
Phase C is purely about widening `components.schemas` and populating
804-
`paths` — not about distribution.
811+
**Phase C (deferred)**replace the approximate detail schemas in
812+
the spec with the exact Phase-B schemas. The document is already
813+
published at runtime via `GET /api/openapi.json` with full path
814+
coverage, so Phase C is purely a precision pass on
815+
`components.schemas` — not about distribution.
805816

806817
The roadmap is intentionally conservative: snapshots remain the
807818
authoritative regression detector through all three phases. A bug
@@ -856,4 +867,4 @@ and should not be pinned by external consumers:
856867

857868
- [`api.md`](./api.md) — external-facing API overview (endpoints, query params, examples).
858869
- [`AGENTS.md`](../AGENTS.md) — project-wide engineering principles, scope, and out-of-scope notes.
859-
- [`openapi.stub.json`](./openapi.stub.json) — auto-generated stub spec covering the Phase-A schemas. Regenerate with `pnpm openapi`.
870+
- [`openapi.json`](./openapi.json) — auto-generated OpenAPI 3.0.3 spec covering every public route; detail-DTO schemas are approximate pending Phase B. Regenerate with `pnpm openapi`.

docs/api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ The same `HennaSummary` shape appears as a cross-link from item detail (`ItemDet
133133

134134
| Method | Path | Description |
135135
|---|---|---|
136-
| GET | `/api/openapi.json` | OpenAPI 3.0 document for the API. Chronicle-agnostic — the document describes `/api/{chronicle}/...` as a parameterised path, with `{chronicle}` exposed as a server-template variable. Phase A: `components.schemas` is populated for the small reusable cross-link DTOs (`NpcRef`, `ClassRef`, `QuestRef`, `RegionRef`, `LocationRef`, `EnrichedSpawn`, `QuestClientJournalEntry`, `HennaSummary`); `paths` is intentionally empty pending Phase C per-route generation (see `docs/api-contract.md`). The document is the committed `docs/openapi.stub.json` build artifact, served as a convenience without an envelope. |
136+
| GET | `/api/openapi.json` | OpenAPI 3.0.3 document for the API. Chronicle-agnostic — every data path carries an explicit `{chronicle}` path parameter against the `/api` server root. `paths` covers every public route with its parameters and response envelopes; list/summary, drop, shop, meta, and henna schemas are exact, while the large detail schemas (`ItemDetail`, `NpcDetail`, `QuestDetail`, `ClassDetail`, `ArmorSet`, `RawNpc`) document stable top-level fields and allow additional properties pending the Phase B Zod migration (see `docs/api-contract.md`). The document is the committed `docs/openapi.json` build artifact, served as a convenience without an envelope. |
137137

138138
## Response shapes
139139

0 commit comments

Comments
 (0)