Repository navigation
fix(studio): show, keep and author a controlled-by-parent object's optional master - #31202
Merged
Merged
Conversation
…master ADR-0055 §1 as amended lets a controlled_by_parent object's only master_detail be declared required: false. Studio now names that master in the OWD overview (via the spec's controlledByParentMasterOf), keeps an explicit required: false on save, and lets the field inspector clear Required on the only master_detail, with help text on the null-master owner rule. Claude-Session: https://claude.ai/code/session_01FEkQ5mJLhZasj7G83LSvsv Co-Authored-By: Claude <noreply@anthropic.com>
The diff adds one key to @object-ui/i18n's published studio catalogue, which widens it. Claude-Session: https://claude.ai/code/session_01FEkQ5mJLhZasj7G83LSvsv Co-Authored-By: Claude <noreply@anthropic.com>
Contributor
Author
|
domain:ui#1 · os-project-manager · session_01FEkQ5nLA7wiVY5YWjT9Svr Contract reviewServed-tier: The lane seat's own review of record, owed by the ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS |
Contributor
Author
|
domain:ui#1 · os-project-manager · session_01FEkQ5nLA7wiVY5YWjT9Svr 席位核对 · ACCEPT · 2026-11-07T17:48Z · head
|
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.
Requested by Leehom · project thread
Fixes #30974
Clause-②: yes (widening)
Metadata-protocol: none
维护者速读
required: false的唯一主从字段显示为主对象;Studio 保存不再把作者写的required: false改成true;字段检查器里唯一主从字段的「必填」可以取消(写成required: false),下方说明无主记录只有所有者和「查看所有记录」可见。ui/packages/app-shell的 Studio 代码和一条 i18n 文案,不改 spec、不改运行时;回滚即还原本 PR。省略required的主字段仍按必填处理,两个以上主从字段时锁定照旧。owd-sharing.ts(主字段改由 spec 的controlledByParentMasterOf判定,保存只补省略的required)、ObjectFieldInspector.tsx(cbpOptionalMasterAllowed一段)、owd-sharing.test.ts(被 feat(spec,security): a controlled_by_parent object may declare an optional master #30940 改标的那一行翻回一致)。pnpm --dir ui exec vitest run packages/app-shell/src/views/studio-design/owd-sharing.test.ts,预期全绿,其中 "one master without required" 与 "one optional master (required: false)" 两行都显示主对象crm_account。What changes
ADR-0055 §1 as amended by #30905 ruling A lets a
controlled_by_parentobject's ONLYmaster_detailbe declaredrequired: false, an optional master whose records may name none. Studio still treated every master as required. This PR covers the card's three items:owd-sharing.ts,deriveMasterObject). Which field is the master is now the spec's own answer,controlledByParentMasterOffrom@objectstack/spec/data, so an optional master is shown as the master and the two-master shapes stay as the spec rules them (Studio does not re-decide them). An omittedrequiredon the object's onlymaster_detailis read as required first, as the spec's stored-row conversioncbp-master-detail-required-defaultedreads it, which is ruling A's "Studio still defaults it to required".owd-sharing.ts,requireCbpMasterDetails, used byPackageOwdOverviewPanel.tsxandObjectSettingsPanel.tsx). Switching to Controlled by parent still setsrequired: trueon eachmaster_detailthat writes norequired(the builder's force), and now keeps an explicitrequired: false. The overview's 409 prerequisite list (cbpPrerequisite) reads the same predicate,cbpMasterDetailDefaultsRequired.ObjectFieldInspector.tsx). On a cbp object's onlymaster_detailthe Required box is no longer locked on: clearing it writesrequired: false(never a dropped key, which would be defaulted back to required), and the help text under it, new keydesigner.field.requiredCbpOptionalMaster(en, zh), says a record that names no master is visible only to its owner and to View All Records on the object. Beside anothermaster_detailthe old lock and text stand, because the spec admits no optional master there (builder andrelationship/master-detail-requiredrefuse it).Why
Triage graded it p2: a Studio save silently turned an author's optional master into a required one, which rewrites the access model they chose.
Tests
owd-sharing.test.tsand inPackageOwdOverviewPanel.cbpRequiredMaster-12326.test.tsxnow namecrm_account, and the spec parse accepts the shape. The per-row "parses" override column is gone: every row's parse verdict now equals "a master is named".required: false), arequired: falsemaster-detail beside the required one, twomaster_detailfields none required.requireCbpMasterDetailskeeps an explicitrequired: false(map, array, and mixed with an omitted one); the overview save keeps it, through the rendered dial and Save button.required: falseand ticked back; beside another master-detail the box stays locked with the old reason.Run on head 3c18a37 (the code head; f7f9807 after it changes only the changeset): the three files, 3/3 files, 38/38 tests passed.
Ablations (each mutation through scripts/ablation-replace.mjs; every restore proven blob == HEAD and `git diff HEAD` empty)
deriveMasterObjectwithout the omitted-required defaultrequired === truecount instead ofcontrolledByParentMasterOfrequired !== truev || undefinedcbpMasterDetail && required === trueAcceptance notes
requiredshows an unticked Required box (the box shows what is written), while the overview names it as the master. Ticking writesrequired: true; switching the model to Controlled by parent writes it too.ObjectSettingsPanel.tsxgets a comment-only edit: its comment said the save forces everymaster_detailrequired, which this change makes false.content/docs/frontend/page describes the inspector's Required lock; the cbp docs belong to controlled_by_parent admits an optional master (3/3): docs and the authoring skills teach it instead of a copied owner field #30907.Verification
All local readings on head f7f9807 unless noted; CI runs the rest of the farm.
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack): 36 families, every one exit 0.--ranreconciliation: "36 derived famil(ies) accounted for — 36 run, 0 NOT-MEASURED (a DERIVED zero — all 36 recorded an exit code and none of them is 3)". The loop ran on 3c18a37; the four changeset families were re-run on f7f9807 (exit 0), andpnpm check:type-check-debt, which first answered exit 3 (it queued behind my own lock hold, nothing measured), was re-run under the lock on f7f9807: exit 0.pnpm --filter @object-ui/app-shell run type-check: exit 0.pnpm --filter @object-ui/i18n run type-check: exit 0.pnpm --dir ui exec vitest run packages/app-shell/src/views/studio-design/ packages/app-shell/src/views/metadata-admin/inspectors/ packages/i18n/: 659/659 files, 7206 passed, 14 skipped. The whole app-shell suite (2,210 files) is left to CI's sharded Test UI.pnpm --dir ui exec eslinton the nine changed ui files: exit 0, 0 errors; the 17 warnings are all on lines this PR does not touch.pnpm --dir ui run check:new-line-citations: "0 new citation(s)", exit 0.@objectstack/spec,formula,client,lint,sdui-parserclosures, then@object-ui/app-shell^..., both lock VERDICT command-exit 0.Human Minimum
packages/specholds no runtime logic.pnpm lintpasses. (The changed ui files were linted locally, exit 0; the repo-wide run is CI's.)main, one pull request.packages/spectouched: its generated artifacts are regenerated and committed. (Not touched.)content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.Generated by Claude Code