You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 5326b36
Browse filesBrowse the repository at this point in the historyBrowse files
fix(rest): converge the record-sharing family onto the ADR-0112 D5 envelope (#8111) (#8212)
* fix(rest): converge the record-sharing family onto the ADR-0112 D5 envelope (#8111)
`registerSharingEndpoints` answered two retired dialects across its nine
refusal arms: `respond501` was flat `{ code, message }`, and the five mapped
verdicts (400/403/404/409/422) plus the three verb-specific 500s were
`{ code, error: '<bare string>' }`. `body.error.code` — the one position
ADR-0112 D5 declares — read `undefined` on all nine.
Every arm now emits through the shared `sendError` from `@objectstack/types`
(imported here as `sendEnvelopeError`; this module has a local `sendError` of
its own for thrown errors), so the family agrees by construction rather than
by nine literals that happen to match.
No status code moves and no code VALUE changes. The 409 arm's `CONFLICT` was
registered in neither `StandardErrorCode` nor `ERROR_CODE_LEDGER` — so
`ApiErrorSchema`, whose `code` is a closed enum, would have rejected that
body — and is now registered under `@objectstack/rest`, keeping the emitted
value byte-identical. Renaming it onto `RESOURCE_CONFLICT` would change what
clients read and is filed separately.
The `CODE:` message prefix stays: censused as a server-internal service→REST
derivation, stripped before the response is written, never on the wire.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B3Kurx8qufrDzNjk4rag7V
* docs(spec): regenerate api references for the CONFLICT ledger entry (#8111)
Registering `CONFLICT` in `ERROR_CODE_LEDGER` grows `ErrorCode` — the union
`ApiErrorSchema.code` parses against — by exactly one member, and every
generated reference page that renders an `ApiError`-shaped field prints that
enum as a truncated summary with a "+N more" count. So one ledger row moves
134 counter lines across 11 pages, plus the two pages that list the vocabulary
in full gain a `CONFLICT` bullet.
Generated output only (`gen:schema` + `gen:docs`), never hand-edited.
Measured as a genuine cascade, not absorbed drift: a pristine `origin/main`
tree regenerates completely clean under the identical commands, and every one
of the 136 changed lines here is either the `+264 more` → `+265 more` counter
(134) or a `CONFLICT` bullet (2) — nothing else.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B3Kurx8qufrDzNjk4rag7V
* test(qa): migrate #8209's share-grant dogfood pin to the ADR-0112 D5 position (#8111)
`federated-phantom-share-grant.dogfood.test.ts` (added by #8209 / PR #8209 for
#8119) asserts the `/data/:object/:id/shares` refusal envelope. It was written
against the FLAT dialect — `body.code` / `body.error` as a bare string — because
that is what the route emitted when it landed. This PR converges that family onto
`{ error: { code, message } }`, so the pin reads `undefined` and fails.
Migrated, not loosened: the assertions move to `body.error.code` and
`body.error.message` and assert the D5 position ALONE. Accepting either shape
would re-admit the dialect this card retires.
The CONTROL case's negative assertion moves too. It did not fail — a negative
assertion on the vacated flat position passes for free
(`undefined !== 'SHARING_NOT_ENABLED'`) — which is exactly why it had to move:
left alone it would have gone on "passing" while reading a key no response
carries any more.
Why the queue caught this and PR CI did not: the merge queue runs the FULL
suite, PR-side CI only the affected subset, and neither PR alone is red — #8209
was green before this convergence existed and this branch was green before
#8209's pin existed. The interaction is only visible composed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B3Kurx8qufrDzNjk4rag7V
---------
Co-authored-by: Claude <noreply@anthropic.com>
|**data**|`{ name: string; title?: string; measures: object[]; dimensions: object[] }[]`| ✅ | Available cubes, each as the `CubeMeta` discovery projection — the cube name, its title, and the measures/dimensions a client may name in a query. A bare array: there is no `cubes` wrapper object, and no cube `sql` is published. |
50
50
@@ -79,7 +79,7 @@ const result = AnalyticsEndpoint.parse(data);
79
79
| Property | Type | Required | Description |
80
80
| :--- | :--- | :--- | :--- |
81
81
|**success**|`boolean`| ✅ | Operation success status |
Copy file name to clipboardExpand all lines: content/docs/references/api/batch.mdx
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -55,7 +55,7 @@ const result = BatchConfigSchema.parse(data);
55
55
| :--- | :--- | :--- | :--- |
56
56
|**id**|`string`| optional | Record ID if operation succeeded |
57
57
|**success**|`boolean`| ✅ | Whether this record was processed successfully |
58
-
|**errors**|`{ code: Enum<'VALIDATION_ERROR' \| 'INVALID_FIELD' \| 'MISSING_REQUIRED_FIELD' \| … +264 more>; message: string; category?: string; httpStatus?: integer; … }[]`| optional | Array of errors if operation failed. Branch on `errors[0].code` — an atomic batch that rolled back marks rows that were written then undone with code ROLLED_BACK and rows never reached with NOT_ATTEMPTED, while the causal row keeps its own error (#4793). A NON-atomic batch that stopped (the `continueOnError: false` default) marks its un-attempted tail with the same NOT_ATTEMPTED code — rows before the failure stay written and keep reporting success, since nothing was rolled back (#7539). |
58
+
|**errors**|`{ code: Enum<'VALIDATION_ERROR' \| 'INVALID_FIELD' \| 'MISSING_REQUIRED_FIELD' \| … +265 more>; message: string; category?: string; httpStatus?: integer; … }[]`| optional | Array of errors if operation failed. Branch on `errors[0].code` — an atomic batch that rolled back marks rows that were written then undone with code ROLLED_BACK and rows never reached with NOT_ATTEMPTED, while the causal row keeps its own error (#4793). A NON-atomic batch that stopped (the `continueOnError: false` default) marks its un-attempted tail with the same NOT_ATTEMPTED code — rows before the failure stay written and keep reporting success, since nothing was rolled back (#7539). |
59
59
|**data**|`Record<string, any>`| optional | Full record data (if returnRecords=true) |
60
60
|**index**|`number`| optional | Index of the record in the request array |
61
61
|**droppedFields**|`{ object: string; fields: string[]; reason: Enum<'readonly' \| 'readonly_when' \| 'primary_key'> }[]`| optional | Write-observability (#3407/#3431/#3455): caller-supplied fields LEGALLY stripped from THIS row before it was written — static `readonly` (#2948) / TRUE `readonlyWhen` (#3042) on update, or the #3043 create-ingress strip. Per-row because a batch can drop different fields on different rows (`readonlyWhen` is record-state-dependent). Present ONLY when ≥1 field was dropped for this row; the row still succeeded (success unchanged). A single response header cannot express per-row drops, so this body field is the canonical bulk channel — REST does not emit `X-ObjectStack-Dropped-Fields` for batches. Optional — omit-when-empty keeps the shape backward-compatible. |
@@ -122,7 +122,7 @@ const result = BatchConfigSchema.parse(data);
122
122
| Property | Type | Required | Description |
123
123
| :--- | :--- | :--- | :--- |
124
124
|**success**|`boolean`| ✅ | Operation success status |
0 commit comments