From f6b92e3d197371966663dc4ee5aba9f7ea4bfee6 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 6 Aug 2026 12:47:52 +0000 Subject: [PATCH] =?UTF-8?q?docs(spec):=20HookEvent=20=E6=9E=9A=E4=B8=BE?= =?UTF-8?q?=E6=B3=A8=E9=87=8A=E4=B8=8D=E5=86=8D=E5=A3=B0=E7=A7=B0=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E5=86=99=E6=8A=8A=E8=A1=8C=E7=BA=A7=E8=B0=93=E8=AF=8D?= =?UTF-8?q?=E6=94=BE=E5=9C=A8=20`input`=20(#5899)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 枚举注释里「row-scoping predicate carried in `input`」与同文件 200 行外的 `HookContextSchema.input` 契约表(":340" 起,PR #5668 落地 #5273 时写下的 「NOT reachable from `input` at all」)自相矛盾。引擎从不在写路径的 HookContext.input 上放谓词,它在引擎内部 OperationContext.ast(#2982)。 改为与契约表一致的措辞,并把读者指向该表与其钉子测试 packages/objectql/src/hook-input-shape-contract.test.ts。主句(批量写触发同名 事件、没有 *Many 事件)保留。纯注释订正,未触及 .describe()、键或类型。 Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011M7UwH25Unfi73UHim7ajY --- packages/spec/src/data/hook.zod.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/spec/src/data/hook.zod.ts b/packages/spec/src/data/hook.zod.ts index 4962681183..19b500905a 100644 --- a/packages/spec/src/data/hook.zod.ts +++ b/packages/spec/src/data/hook.zod.ts @@ -134,10 +134,16 @@ export const HookEvent = z.enum([ // Write — before/after per mutation kind. These fire on BOTH single-id and // bulk (`multi: true`) writes: a bulk update/delete runs the SAME - // `beforeUpdate`/`beforeDelete`/`afterUpdate`/`afterDelete` with the - // row-scoping predicate carried in `input` (there is no per-cardinality - // `*Many` event — one write event covers one row or many, Salesforce's - // bulk-first model). See #3195. + // `beforeUpdate`/`beforeDelete`/`afterUpdate`/`afterDelete` (there is no + // per-cardinality `*Many` event — one write event covers one row or many, + // Salesforce's bulk-first model). The row-scoping predicate is NOT reachable + // from `input` on those write events: it lives on the engine-internal + // `OperationContext.ast` (#2982) so that the filters middleware composes onto + // it, where no handler can widen it — scope a bulk batch through + // `options.where` at the CALLER, or work per row on the `after*` events. Full + // per-event shapes in the `HookContextSchema.input` contract table below, + // pinned against the real engine by + // `packages/objectql/src/hook-input-shape-contract.test.ts`. See #3195. 'beforeInsert', 'afterInsert', 'beforeUpdate', 'afterUpdate', 'beforeDelete', 'afterDelete',