Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/api/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ export TRAKRF_API_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

## Testing connectivity

Once you have a key, verify it with the interactive reference at [`/api`](/api) — click any endpoint's **Try it** button and paste your key. Or curl:
Once you have a key, verify it with curl:

```bash
curl -i -H "Authorization: Bearer $TRAKRF_API_KEY" \
Expand Down
8 changes: 8 additions & 0 deletions docs/api/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ This log records changes to the TrakRF public API under `/api/v1/` that affect i

Initial public API release. Stable contract for paths, field names, response shapes, and error envelopes per the [v1 stability commitment](./versioning).

### BB1 hygiene — Try-it wording dropped, `invalid_context` added to versioning open-enums list, `datamodel-codegen` version string unmangled

Three docs hygiene items from the BB1 post-launch-asset-location-removal black-box cycle. All pre-launch presentation-layer corrections; no service behavior change.

- **"Try it" / "try-it-now widget" wording removed from [Authentication → Testing connectivity](./authentication#testing-connectivity) and [Quickstart → Next steps](./quickstart#next-steps).** Both pages previously pointed integrators at a Try-it button on the [interactive reference](/api), but `/api` renders with Redoc — a read-only reference with no request console. The auth page now leads with the curl recipe directly; the quickstart's interactive-reference bullet drops the widget claim. Swapping to a console-bearing renderer (Swagger UI / Scalar) is a separate product decision out of scope for this hygiene pass.
- **`invalid_context` added to the [Versioning → Open (extensible) enums in v1](./versioning#open-extensible-enums-in-v1) field-code list.** The page enumerated 10 of the 11 current `FieldErrorCode` values — the [BB62-introduced](#bb62-fix-wave--body-decode-failures-normalized-to-validation_error-new-invalid_context-code-for-known-field-wrong-context-rejections-x-package-name-spec-extension-ancestors-ordering-prose-fix) `invalid_context` code was missing. An integrator building an exhaustive matcher from the versioning page would silently omit a real code emitted in production. The full set is now on the page and matches both the [errors catalog](./errors#validation-errors) and the spec enum.
- **`datamodel-codegen` version string normalized on [Design notes](./design-notes) and [Quickstart → Raw spec for codegen](./quickstart#5-raw-spec-for-codegen).** The pinned version was rendered with a bare `@` between the package name and the SemVer, which the docs origin's Cloudflare email-obfuscation pass rewrote to a `[email protected]` placeholder for raw-HTML, no-JS, view-source, reader-mode, and scraper consumers — exactly the automated-integrator audience the API targets. The pages now write the package and version separated by a space, so the load-bearing fact (which version is known-broken) survives obfuscation. Disabling the Cloudflare rule on the docs path is a config change tracked separately and not required for this fix.

### Asset current location removed from the asset resource

An asset's current location is fact data — derived from the scan-event stream — not a dimension attribute the asset resource carries. `location_id` and `location_external_key` are removed from the asset response shape and from the `GET /api/v1/assets` filter surface; current location is read from the scan-data endpoints, and `POST` / `PATCH` reject the two fields uniformly on presence. The reporting endpoints (`/reports/asset-locations`, `/assets/{id}/history`) are unchanged — they remain the system of record for asset location. Pre-launch contract change; no `v1.0.0`-or-later wire baseline to break.
Expand Down
2 changes: 1 addition & 1 deletion docs/api/design-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ We're on OpenAPI 3.0.3. Nullable response fields use `nullable: true` rather tha
Generator behavior varies:

- **Verified-working:** `openapi-typescript@7.x` (emits `string | null`) and `openapi-generator-cli` python target (emits `Optional[StrictStr]`). Both round-trip CRUD against null-bearing responses unmodified.
- **Known-broken:** `datamodel-codegen@0.57.0` emits nullable fields as non-Optional required types. Pydantic validation fails on every nullable field that's actually `null`.
- **Known-broken:** `datamodel-codegen` 0.57.0 emits nullable fields as non-Optional required types. Pydantic validation fails on every nullable field that's actually `null`.

For integrators using `datamodel-codegen`, switch to one of the verified-working targets, or apply `--use-annotated --use-union-operator` flags with custom post-processing.

Expand Down
4 changes: 2 additions & 2 deletions docs/api/quickstart.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ The bare-form `/openapi.yaml` and `/openapi.json` at the app origin also resolve
The spec declares its security scheme as `BearerAuth` (HTTP Bearer, JWT format), so class-emitting generators surface the credential as a Bearer access token — `openapi-generator-cli`'s `typescript-fetch` target produces a `Configuration` with an `accessToken` field, and the Java/Python targets follow the same shape. The wire format remains `Authorization: Bearer <jwt>`; pass the API key minted in step 2 wherever the generated client expects an access token.

:::tip Verified-working codegen targets
TrakRF spec round-trips end-to-end against `openapi-typescript@7.x` (TypeScript types feeding `openapi-fetch`), `openapi-generator-cli` python (`Optional[...]` for every nullable read field), and the typescript / Java targets from the same generator. If you reach for `datamodel-codegen` (Pydantic from OpenAPI), be aware that `datamodel-codegen@0.57.0` emits `nullable: true` read-shape fields as **non-Optional** required types, so Pydantic raises `ValidationError` on every nullable field that actually comes back `null` (`deleted_at` on every resource, `valid_to`, and the location `parent_id` / `parent_external_key` pair). Either switch to the `openapi-generator-cli` python target or run `datamodel-codegen` with `--use-annotated --use-union-operator` plus a post-processing pass that wraps nullable fields in `Optional[…]`. The same note lives on the [interactive reference's intro](/api).
TrakRF spec round-trips end-to-end against `openapi-typescript@7.x` (TypeScript types feeding `openapi-fetch`), `openapi-generator-cli` python (`Optional[...]` for every nullable read field), and the typescript / Java targets from the same generator. If you reach for `datamodel-codegen` (Pydantic from OpenAPI), be aware that `datamodel-codegen` 0.57.0 emits `nullable: true` read-shape fields as **non-Optional** required types, so Pydantic raises `ValidationError` on every nullable field that actually comes back `null` (`deleted_at` on every resource, `valid_to`, and the location `parent_id` / `parent_external_key` pair). Either switch to the `openapi-generator-cli` python target or run `datamodel-codegen` with `--use-annotated --use-union-operator` plus a post-processing pass that wraps nullable fields in `Optional[…]`. The same note lives on the [interactive reference's intro](/api).
:::

:::note Repeatable query parameters in typed clients
Expand Down Expand Up @@ -252,7 +252,7 @@ If your key was minted without `tracking:read`, the calls return `403 forbidden`

## Next steps

- [Interactive reference](/api) — every endpoint, request/response shape, try-it-now widget
- [Interactive reference](/api) — every endpoint, request/response shape
- [Authentication](./authentication) — scopes, key lifecycle, rotation
- [Pagination, filtering, sorting](./pagination-filtering-sorting) — conventions for list endpoints
- [Resource identifiers](./resource-identifiers) — canonical `id`, natural-key `external_key`, and the `?external_key=` list filter
Expand Down
2 changes: 1 addition & 1 deletion docs/api/versioning.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ These enum sets will not grow within v1:
These are designed to grow:

- **Error `type`** (`ErrorResponse.error.type`) — marked `x-extensible-enum: true` in the spec. Current values are documented in the [errors catalog](./errors#error-type-catalog); future values may appear in any v1 release. Clients should branch on HTTP status (closed) for retry/alerting policy and treat unknown `type` values as generic errors of that status class.
- **Validation field codes** (`fields[i].code` on `validation_error` responses) — current set is `required`, `invalid_value`, `unknown_field`, `too_short`, `too_long`, `too_small`, `too_large`, `fk_not_found`, `ambiguous_fields`, `read_only`. New codes may appear. Treat unknown codes as generic invalid-value and surface the `message` field.
- **Validation field codes** (`fields[i].code` on `validation_error` responses) — current set is `required`, `invalid_value`, `unknown_field`, `invalid_context`, `too_short`, `too_long`, `too_small`, `too_large`, `fk_not_found`, `ambiguous_fields`, `read_only`. New codes may appear. Treat unknown codes as generic invalid-value and surface the `message` field.
- **Scope strings** (keys on API-key responses, scope columns in the UI) — TrakRF may introduce new scopes (e.g. `reports:read`, `webhooks:write`) in any v1 release. Clients that display the list of scopes available to a key must render unknown scope strings as-is rather than filtering them out.
- **`tag_type` discriminator** (`Tag.tag_type` on every tag variant; the `oneOf` discriminator mapping) — current values are `rfid`, `ble`, `barcode`. New variants may be added as additive minor revisions; integrators should treat unknown variants as forward-compatible and pass them through untouched. See [Resource identifiers → Tag is a polymorphic resource](./resource-identifiers#tag-is-a-polymorphic-resource).

Expand Down
Loading