Skip to content

Commit cf85a44

Browse files
hotlongclaude
andcommitted
fix(rest, runtime): cite the folded-type and plural-spelling commits, and the H0 double refuses unsupported where shapes
Claude-Session: https://claude.ai/code/session_local_1d2a197c-c20e-4e90-9be8-413d4d432289 Co-authored-by: Claude <noreply@anthropic.com>
1 parent a4681f9 commit cf85a44

3 files changed

Lines changed: 25 additions & 9 deletions

File tree

‎packages/rest/src/meta-item-read-gate.ts‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,9 @@ export function metaCallerOrganizationId(caller: unknown): string | undefined {
166166

167167
/**
168168
* [#9454 · #20408] The organization a `/meta` READ of `type` carries:
169-
* `organizationIdForMetaRead` over the FOLDED segment (#10340 — the raw plural
170-
* would miss the registry's override flag) and the caller's vetted
169+
* `organizationIdForMetaRead` over the FOLDED segment (folded-type commit
170+
* 26f3588fb, whose card no longer resolves: the raw plural would miss the
171+
* registry's override flag) and the caller's vetted
171172
* organization ({@link metaCallerOrganizationId}). An organization reaches the
172173
* read only for a type the registry declares `allowOrgOverride`, so a
173174
* non-overridable type never resurrects a pre-#6190 phantom org row.
@@ -1956,8 +1957,9 @@ export async function translateMetaList(
19561957
/**
19571958
* [#20408] Translate ONE metadata document for the request's locale — the item
19581959
* twin of {@link translateMetaList}. `metaType` is the canonical singular (the
1959-
* caller folds its URL segment once, #6349: the translatable set is
1960-
* singular-only, so an unfolded plural would skip the whole localization).
1960+
* caller folds its URL segment once — plural-spelling commit 2443bb4c4e, whose
1961+
* card no longer resolves: the translatable set is singular-only, so an
1962+
* unfolded plural would skip the whole localization).
19611963
*
19621964
* Takes the DOCUMENT, never the `getMetaItem` envelope (#5563): nav and field
19631965
* labels live on the document. A missing bundle is not a bail-out (the

‎packages/rest/src/rest-server.ts‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5785,8 +5785,9 @@ export class RestServer {
57855785
// and same registry gate as every other read door here.
57865786
const listCtx = await this.resolveExecCtx(environmentId, req)
57875787
.catch(rethrowAuthzStoreUnavailable);
5788-
// [#10340] FOLDED, not raw — see the PUT door's org-scope
5789-
// comment for the measurement. [#20408] Asked of
5788+
// [folded-type commit 26f3588fb] (the original card no
5789+
// longer resolves) FOLDED, not raw — see the PUT door's
5790+
// org-scope comment for the measurement. [#20408] Asked of
57905791
// `metaReadOrganizationId`, the one answer the runtime
57915792
// dispatcher's list asks too.
57925793
const listOrganizationId = metaReadGate.metaReadOrganizationId(req.params.type, listCtx);
@@ -6357,8 +6358,9 @@ export class RestServer {
63576358
// ⚠️ NOT a new seam: memoised per request, and this
63586359
// handler resolves the same context again further down.
63596360
// [#20338] `readCtx` is resolved above the draft switches.
6360-
// [#10340] FOLDED, not raw — see the PUT door's org-scope
6361-
// comment for the measurement. [#20408] Asked of
6361+
// [folded-type commit 26f3588fb] (the original card no
6362+
// longer resolves) FOLDED, not raw — see the PUT door's
6363+
// org-scope comment for the measurement. [#20408] Asked of
63626364
// `metaReadOrganizationId`, the one answer the runtime
63636365
// dispatcher's item read asks too.
63646366
const readOrganizationId = metaReadGate.metaReadOrganizationId(req.params.type, readCtx);

‎packages/runtime/src/domains/meta-read-org-scope-parity.test.ts‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,20 @@ function makeQl() {
145145
{ id: 'ps_shared', name: 'shared_access', system_permissions: ['manage_metadata', 'studio.access'] },
146146
],
147147
};
148+
/**
149+
* Equality plus `$in` — the two shapes the shared resolver issues — and a
150+
* loud refusal of every other shape, so a combinator this double does not
151+
* implement can never read as a field that happened not to match.
152+
*/
148153
const matches = (row: any, where: any): boolean => Object.entries(where ?? {}).every(([field, cond]) => {
149-
if (cond !== null && typeof cond === 'object' && Array.isArray((cond as any).$in)) return (cond as any).$in.includes(row[field]);
154+
if (field.startsWith('$')) throw new Error(`fixture where-matcher: unsupported combinator '${field}'`);
155+
if (cond !== null && typeof cond === 'object') {
156+
const ops = Object.keys(cond as object);
157+
if (ops.length !== 1 || ops[0] !== '$in' || !Array.isArray((cond as any).$in)) {
158+
throw new Error(`fixture where-matcher: unsupported operator shape on '${field}'`);
159+
}
160+
return (cond as any).$in.includes(row[field]);
161+
}
150162
return row[field] === cond;
151163
});
152164
return {

0 commit comments

Comments
 (0)