Repository navigation
[17.x] 批量写按行语义实现:hook 按行触发 + record-change trigger 按行绑定 previous/record(#4800/#4862 拍板 A) #5038
Description
Activity
- addedpriority:p0Critical: blocker, must ship before MVPCritical: blocker, must ship before MVP
on Aug 4, 2026 认领:PM 循环第 1 轮(维护者本日加急,p0)
会话:session_01Pbu27iNUfQCHeuS551Rqo7
分支:claude/issue-5038-bulk-write-per-row-semantics
Worktree:objectstack-issue-5038
域:domain:engine+domain:services(跨域单一认领,文件面全列)
文件面:packages/objectql/src/engine.ts(批量分支)、packages/objectql/src/hook-wrappers.ts、packages/services/service-automation/src/engine.ts/plugin.ts(record-change trigger 绑定)、examples/app-showcase/src/automation/flows/**(端到端验证面)、content/docs/data-modeling/formulas.mdx+skills/objectstack-formula/SKILL.md(口径收口,跨入 devx 文档面,已声明)、测试 + changeset(越界即停,报告说明)Blocked-by 核验(对 GitHub 实况):#5037 已关(completed),止血 + ADR 补遗随 PR #5057 落 main(commit
4335497);#4800 的阻塞语义(ADR 补遗随止血单落地)已实质满足,该卡保持开启为设计孵化点,由本单交付后关闭。⚠️ 与 #4619(engine.ts transaction 段)同文件,后者已退回下轮串行。
Generated by Claude Code
- added a commit that references this issue
on Aug 4, 2026 验收:ACCEPT —— PR #5270(转 ready + auto-merge;p0 主线闭环,连带 Closes #4800/#4862)
会话:
session_01Pbu27iNUfQCHeuS551Rqo7(PM 循环第 4 轮)裁定 A 全要素落地:after 型 hook 按行统一触发(裁定明确否决的「按条件文本开关」未犯);行集一次性读取并入 #3106 既有取数(性能护栏:整批多一次查询而非每行一次);
ctx.result按行 =row ⊕ payload;批量 delete 不设result、回落previous(语义正确);onError无需新含义 —— 按行派发恰好给了它记录作用域上下文;资源上限(10k)在 driver 调用前拒绝(ERR_BULK_PER_ROW_HOOK_LIMIT),绝不降级为整批一次(那是本系列要根除的静默漏行)。生产端修好、消费端零改 —— hook-wrappers/trigger/audit 全部随之正确,契约优先的教科书形状。止血退役核实(派发词要求项)——执行且证伪一半:
before*hook 因 phase 定义(可改写唯一一份 payload)保持批次作用域,#5037 诊断保留并收窄,文案三处修正:不再承诺已兑现的过期(留着就是平台毁约)、点名 phase 为原因、把 after* 与 record-change flow trigger 列为真实出路(后者是依据本 PR 事实的反转,不是放松)。实况核验:draft ✓ / Fixes+Closes 三单 ✓ / 15 文件:两处声明外触碰(ADR-0058 addendum、adr-anchors.json invariant)均为被本改动证伪的记录性断言,不改即新造 declared ≠ delivered,接受;showcase +formula devDep 理由成立 ✓ / ⛔ spec、protocol.ts、releases、全部在飞面零触碰 ✓ / trigger 4 例经 stash 反向验证非空洞 ✓ / showcase 37 例从 flow 条件文本生成(不手抄期望)✓ / objectql 1848 + automation 665 + trigger 55 + showcase 120 + 三 plugin 包 + 并 main 后 turbo 65 tasks 全绿 ✓ / changeset 按破坏性变更写明(通知类 hook N 条、缓存失效 N 次;无 hook 对象零影响)✓。
本单合并后解锁:#4619、#5099(需按新语义重核前提)、#5048、#4792、#4953 —— 依序进批。
Generated by Claude Code
- added a commit that references this issue
on Aug 4, 2026 - added 3 commits that reference this issue
on Aug 6, 2026 - added a commit that references this issue
on Aug 17, 2026 - added a commit that references this issue
on Aug 19, 2026 - added a commit that references this issue
on Sep 28, 2026
维护者 2026-08-04 拍板(见 #4800 / #4862 裁定评论):批量写上 after 型 hook 与 record-change flow trigger 按行求值、按行触发是平台契约。本单是 17.x 的实现单,一次设计覆盖两面:
ctx.result形状:整批 vs 单行)、匹配行集一次性读取(复用 validation 侧 Validation rules, requiredWhen and option visibleWhen are silently skipped on multi-row updates (options.multi) #3106 的逐行取数形状);previous不绑定、record只是裸 payload —— 官方文档与 showcase 正在教的 transition 起始条件在批量写上不成立 #4862 的全部事实照单):previous按行绑定、record为该行实际状态而非裸 payload;Blocked-by: #5037(rc 止血单)Blocked-by: #4800(ADR 补遗随止血单落地)关联:#4862(trigger 侧事实与影响面)、#3106(validation 先例)、#4775/#4861(fail-loud 先例)。
Generated by Claude Code