refactor(data): master-detail 保存统一走原子 batchTransaction,把非原子回退隔离进适配器 (#2679)#2684
Merged
Merged
Conversation
…ion; isolate non-atomic fallback in the adapter (#2679) Master-detail saves (MasterDetailForm, LineItemsPanel) now always persist through dataSource.batchTransaction(operations) — one ordered cross-object operation list with { $ref: <op index> } linking a child to a parent created in the same batch. The form no longer contains any client-side orchestration or best-effort compensation-delete; that atomicity anti-pattern is gone from the UI layer (framework #1604 / framework ADR-0034 item 4). - types: batchTransaction? is a first-class (optional) DataSource method, typed via BatchTransactionOperation / BatchRef (replaces (ds as any) sniffing) - core: new emulateBatchTransaction (sequential + $ref resolution + best-effort reverse-order compensation) and runBatchTransaction (prefer adapter, emulate otherwise); ApiDataSource / ValueDataSource / MockDataSource implement it - data-objectstack: ObjectStackAdapter.batchTransaction prefers the SDK client.data.batchTransaction when present, uses POST /api/v1/batch otherwise, and degrades to emulation ONLY on 404/405/501 (endpoint/ runtime missing); 400/401/403/409/500 still surface. Extracted emitBatchMutations; cached detection avoids re-probing - plugin-form: removed applyDetail/createMany/ApplyDetailResult from masterDetailTx.ts; MasterDetailForm + LineItemsPanel build ops and call runBatchTransaction. LineItemsPanel saves + rollup are now atomic on a capable backend - tests: new core emulation suite, MasterDetailForm emulation-fallback + compensation cases, LineItemsPanel suite, adapter 404/501/400/SDK-detect fallback cases; docs (data-source guide, ADR-0001 addendum, rest example), changeset Co-Authored-By: Claude <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
os-zhuang
marked this pull request as ready for review
July 19, 2026 16:14
This was referenced Jul 19, 2026
os-zhuang
added a commit
that referenced
this pull request
Jul 20, 2026
…2695) (#2718) `Build Docs` (@object-ui/site#build) runs fumadocs' remark-image plugin, which fetches every remote image at build time to inline its width/height. For remote badges (shields.io / skills.sh) this turns an external service's availability into a hard build dependency: a shields.io hiccup (Cloudflare 520 / 1200 "Too many requests") throws and fails the entire docs build, unrelated to the PR under test (observed on #2684). Configure remark-image via source.config.ts: - external: { timeout: 10_000 } — bound each remote fetch so a hung connection can't stall CI. - onError — warn (don't fail the build) when a remote image can't be sized, while re-throwing for local/authored images so broken in-repo paths stay fatal. The only live remote badge triggering a build-time fetch is the skills.sh badge in content/docs/guide/agent-skills.md; the shields.io references live inside code fences and are never fetched. Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
承接 framework#1604 / framework ADR-0034 item 4。
masterDetailTx → batchTransaction → POST /api/v1/batch的接线已存在且工作正常;本 PR 按 issue #2679 首选的**方案 A(契约先行)**清理非原子客户端回退路径。Issue 点名的三块"回退清理":
canBatch方法嗅探门、handleParentSaved的 best-effort 补偿删除、applyDetail的created簿记。关键发现:canBatch是方法嗅探而非端点嗅探——ObjectStackAdapter永远有该方法,所以旧后端(无/batch)场景今天其实是 404 直接失败,表单回退分支从不触发。真正的旧后端保护必须做在适配器内。改动
@object-ui/types:batchTransaction?提升为DataSource契约的一等(可选)方法,类型BatchTransactionOperation/BatchRef,去掉(dataSource as any)嗅探。可选而非必选,避免在 minor 里破坏外部实现方。@object-ui/core:新增emulateBatchTransaction(顺序执行 +$ref解析 + 失败时逆序 best-effort 补偿删除)与runBatchTransaction(有适配器方法则用,否则模拟)。ApiDataSource/ValueDataSource/MockDataSource均以该 helper 实现batchTransaction。@object-ui/data-objectstack:ObjectStackAdapter.batchTransaction优先用已发布客户端的client.data.batchTransaction(framework #3271,特性探测),否则走POST /api/v1/batch;仅当端点缺失(404/405)或运行时不支持事务(501,framework rest-server 对此返回 501)时降级到客户端模拟。400/401/403/409/500 等真实错误照常抛出。抽出emitBatchMutations共用,缓存探测结果避免重复探测。这是非原子回退唯一、有测试的落点。@object-ui/plugin-form:从masterDetailTx.ts删除applyDetail/createMany/ApplyDetailResult;MasterDetailForm与LineItemsPanel一律构建 ops 交给runBatchTransaction,表单不再有主子表专属编排/补偿代码。LineItemsPanel保存 + rollup 在有能力后端上现在也原子(rollup 并进同一批的父 op)。行为差异(注意)
handleParentSaved仅!isEdit补偿)。bulk('create')分组($ref 解析与有序语义所需;行项目量小)。/batch)无行为变化;旧/受限后端保留可用但明确非原子的保存路径。硬删除模拟卡在"discovery 广播 batch 能力"这一前提上(尚未广播)。测试 / 验证
core/adapters/__tests__/batchTransaction.test.ts(顺序/索引对齐、$refid/_id/recordId 解析与前向 ref 抛错+补偿、逆序仅补偿 created、runBatchTransaction委托/回退、驱动真ValueDataSource断言事件不双发)。MasterDetailForm.test.tsx新增两例无batchTransaction的模拟路径(端到端$ref解析、子失败→父补偿删除+错误 toast);现有三例原子测试不变。LineItemsPanel.test.tsx(op0=含 rollup 的父 update + 子 diff;无batchTransaction仍可保存)。onMutation.test.ts新增适配器回退用例(404/501 warn 一次+原语保存+缓存;400 抛错不回退;SDK-present 走 SDK 不裸 fetch、事件恰一轮);masterDetailTx.test.ts删applyDetail用例,补 rollup 折入 op0 验收 pin。@object-ui/core89、@object-ui/plugin-form205、@object-ui/data-objectstack89、@object-ui/runner6;5 个受改包build全过。content/docs/guide/data-source.md、docs/adr/0001addendum、rest-data-source.ts示例注释;changeset(minor,通过 fixed-group 校验)。后续(不在本 PR)
🤖 Generated with Claude Code
Generated by Claude Code