Uh oh!
There was an error while loading. Please reload this page.
feat(app-shell,plugin-detail): permission sets — Studio designs, Setup assigns (ADR-0056) - #2403
Merged
Conversation
…pability multi-select (ADR-0056 P2) Replace the raw JSON textarea for sys_permission_set.system_permissions with a structured capability picker over the live sys_capability registry — scope-grouped, labelled chips with the capability description on hover. - New CapabilityMultiSelectField, registered field:capability-multiselect (@object-ui/fields). Value round-trips BYTE-EQUIVALENT to the JSON-string-array storage (parse on load, JSON.stringify(names) on save); unknown/legacy names are preserved. - Stamped onto the field at the single getObjectSchema choke point (ObjectStackAdapter) so BOTH the record form (ObjectForm) and the detail-page inline edit (DetailView/DetailSection) show the picker. Field storage type unchanged. ObjectForm auto-gen now carries field.widget; DetailSection enriches + honors widget in its inline-edit switch. ADR-0056 P2 / epic #2398. First step toward retiring Setup's permission JSON textareas for structured Studio editors. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ry + Studio deep-link (ADR-0056 P1) The six sys_permission_set authorization facets (object/field/system/RLS/tab/ admin_scope) rendered in Setup as raw [Object]/JSON textareas. In the pure model they are *designed* in Studio's structured editors and only *assigned* (to users) in Setup, so Setup must show them read-only. New `permission-facet-link` widget renders each facet as a compact summary (counts, or capability chips for system_permissions) plus a "Design in Studio →" deep-link to /apps/:appName/metadata/permission/:setName (env scope; the existing PermissionMatrixEditPage). The widget is stamped onto all six fields via the single ObjectStackAdapter.getObjectSchema choke point; DetailSection's read + inline-edit branches honor it (mirroring the capability-multiselect path), and it is registered as field:permission-facet-link so the record form resolves it too. Storage types are untouched. Verified live: sales_rep shows '10 objects' / '4 field rules' / capability chips + deep-links (no [Object]/JSON); the link opens the env-scope matrix editor (10 objects / 4 field overrides, matching the summary). ADR-0056 epic #2398 P1.
…record page (ADR-0056 P1b) In the pure model, assigning users to a permission set is a Setup (admin) act. The set's facets now render read-only as summary + Studio deep-link (P1); this adds the add/remove-users panel directly to the Setup sys_permission_set record page so admins manage membership without leaving Setup. New RecordPermissionAssignmentsRenderer wraps the existing AssignedUsersSection (add/remove via sys_user_permission_set, shows position-held grants), reading the set's api-name from the record context. Rendered directly in RecordDetailView (mirroring RecordAttachmentsPanel) inside RecordContextProvider, gated on objectName === 'sys_permission_set' — not via a page slot, because the render-time page rebuild (renderedPage) only forwards assignedSlots. Verified live: sales_rep record page shows '已分配用户 0 人' + 添加用户 with the real assignment component (matches the matrix editor's panel). ADR-0056 epic #2398 P1b.
…matrix (ADR-0056 P2) Adds a 'System Capabilities' section to the Studio / env-scope permission matrix editor (PermissionMatrixEditPage), reusing CapabilityMultiSelectField: the live sys_capability registry as scope-grouped, labelled chips (studio.access, manage_users, …). In the pure model, capabilities are *designed* here like every other facet; Setup shows them read-only (PermissionFacetLink, P1). Wired to PermissionSetDraft.systemPermissions (string[]) — the picker round-trips via a JSON string, so we parse back into the array the draft uses. Persisted by the editor's existing whole-record Save at environment scope; respects the read-only (allowOrgOverride) gate. Capability rows are read via useAdapter (data), distinct from the metadata client that owns the draft. i18n keys added (en/zh). Verified live: sales_rep editor shows the 6 platform capabilities; toggling Studio Access on + Save persists (survives editor reload); toggled back off. KNOWN GAP (framework companion): env-scope metadata saves of systemPermissions do not project onto the sys_permission_set *data record* the Setup detail page reads, so a Studio capability edit isn't reflected in Setup's read-only summary until the projection refreshes. Enforcement reads the authoritative metadata (ADR-0090); this is a display-freshness concern tracked for a framework follow-up. ADR-0056 epic #2398 P2.
…s in Studio (ADR-0056 P3)
The three remaining permission facets — row_level_security, tab_permissions,
admin_scope — were authorable only as raw JSON in Setup. New
PermissionAdvancedFacets adds structured editors for them to the Studio /
env-scope permission matrix, as collapsed-by-default sections below the object
matrix so they don't crowd it:
- Row-Level Security: per-policy rows (name · object · operation · enabled) with
CEL USING/CHECK textareas; add/remove.
- Tab Visibility: per-tab key → visible | hidden | default_on | default_off.
- Delegated Admin Scope: business-unit + include-subtree, manage-assignments /
manage-bindings / author-env-sets toggles, and an assignable-permission-sets
allowlist (multi-select over all sets, loaded via client.list('permission')).
Each reads/writes the draft's parsed camelCase field (rowLevelSecurity /
tabPermissions / adminScope), tolerating a JSON string on load so legacy rows
survive, and is persisted by the editor's existing whole-record Save. Shapes
mirror the framework spec (sampled from live data). i18n en/zh added.
Verified live: organization_admin renders its 18 RLS policies as structured rows
with CEL predicates; showcase_field_ops_delegate shows businessUnit 'Field
Operations', the correct toggles, and assignable sets showcase_contributor +
showcase_manager; toggling manageBindings + Save persists across reload (then
reverted). Same env-scope metadata store as P2 (display-in-Setup freshness is the
tracked framework follow-up).
ADR-0056 epic #2398 P3.…itor (ADR-0056 P4) Completes the pure-model separation: the permission matrix editor is now purely a *design* surface (object/field matrix + system capabilities + RLS/tab/admin facets), and *assigning* users is a Setup act handled on the sys_permission_set record page (RecordPermissionAssignmentsRenderer, P1b). Removes the embedded AssignedUsersSection from PermissionMatrixEditor; the component itself is unchanged and still used by the Setup record page. With P1 rendering all six facets read-only (summary + Studio deep-link) in Setup, no permission concern is editable as free-text JSON anywhere in Setup — verified: the Setup create form shows identity fields + read-only 'Design in Studio' facet hints (no JSON textareas), the record page shows summaries + deep-links + the assignment panel, and the editor shows the matrix + capabilities + advanced facets with no assignment. ADR-0056 epic #2398 P4.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
Uh oh!
There was an error while loading. Please reload this page.
os-zhuang added a commit
that referenced
this pull request
Jul 13, 2026
Drops the Option-B `system_permissions`-in-Setup exception: all six facets are designed in the structured permission editor (reached from both Studio and Setup's env-scope metadata route), and Setup renders every facet read-only (summary + Studio deep-link) plus user assignment. Updates the decision, the facet table, the phase list (P1/P1b/P2/P3/P4 as shipped), resolves open Q6, adopts alternative A2 (bootstrap knot resolved via the Setup-side entry point), and adds the metadata↔data-record projection-freshness gap as open Q7 / a framework follow-up. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
os-zhuang added a commit
that referenced
this pull request
Jul 13, 2026
…ps assignment (#2399) * docs(adr): ADR-0056 — permission editing belongs in Studio, Setup keeps assignment A permission set (sys_permission_set) has two editing surfaces over the SAME record: Setup's six raw-JSON textareas and Studio's structured PermissionMatrixEditor (objects + fields only). Raw JSON authz metadata is invisible to the ADR-0090 explain engine + publish linter, unvalidated, duplicated, and a silent-incident footgun. Decision (Option B): permission editing → Studio (structured editors); Setup keeps user management + permission-set assignment; system_permissions (incl. studio.access) stays in Setup as a sys_capability picker. Phased P1–P5, tracked in #2398. Design-review PR — Status: Proposed. Open questions (RLS editor depth, deep-link UX/scope, legacy-JSON backward-compat) are called out for reviewers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(adr): revise ADR-0056 to the pure model (implemented in #2403) Drops the Option-B `system_permissions`-in-Setup exception: all six facets are designed in the structured permission editor (reached from both Studio and Setup's env-scope metadata route), and Setup renders every facet read-only (summary + Studio deep-link) plus user assignment. Updates the decision, the facet table, the phase list (P1/P1b/P2/P3/P4 as shipped), resolves open Q6, adopts alternative A2 (bootstrap knot resolved via the Setup-side entry point), and adds the metadata↔data-record projection-freshness gap as open Q7 / a framework follow-up. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This was referenced Jul 13, 2026
Merged
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 freeto 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.
What
Implements the pure separation model for permission-set editing (ADR-0056 / epic #2398): an app developer designs every facet in Studio; a system admin assigns users in Setup, where every facet is read-only — no
[Object], no JSON. Supersedes the earlier "capability picker in Setup" approach (#2400).Fixes the reported bug: the Setup
sys_permission_setrecord page showed对象权限 [Object],字段权限 [Object], and raw-JSON textareas for the other four facets.Phases (all browser-verified against the live app-showcase backend)
P1 — Setup: kill
[Object]/JSON → summary + Studio deep-link. The six facets (object_permissions,field_permissions,system_permissions,row_level_security,tab_permissions,admin_scope) render read-only as a compact summary (counts, or capability chips) + a "Design in Studio →" deep-link to/apps/:appName/metadata/permission/:setName(env scope). Newpermission-facet-linkwidget, stamped onto the six fields via the singleObjectStackAdapter.getObjectSchemachoke point and honored by DetailSection (read + inline-edit) and the record form.sales_repshows "10 objects" / "4 field rules" + deep-links; the link opens the env-scope matrix (10 objects / 4 field overrides — matching).P1b — Setup: surface user assignment. The add/remove-users panel (
AssignedUsersSection, viasys_user_permission_set) now renders directly on the Setup record page.sales_reprecord page shows the "已分配用户" panel with the real component.P2 — Studio: System Capabilities editor. The permission matrix editor gains a capability multi-select over the live
sys_capabilityregistry (scope-grouped, labelled chips), wired toPermissionSetDraft.systemPermissions.P3 — Studio: RLS / tab-visibility / admin-scope editors. Structured editors for the three JSON-only facets, as collapsed-by-default sections below the object matrix: RLS per-policy rows with CEL USING/CHECK; tab visibility
visible|hidden|default_on|default_off; delegated admin scope (business-unit + subtree, manage toggles, assignable-sets allowlist).organization_adminrenders its 18 RLS policies as structured rows with CEL predicates;showcase_field_ops_delegateshows businessUnit "Field Operations", correct toggles, and assignable setsshowcase_contributor+showcase_manager; amanageBindingstoggle + Save persisted across reload (reverted).P4 — move assignment out of the design editor. With assignment on the Setup record page (P1b), it's removed from the matrix editor — which is now purely a design surface.
Storage / compatibility
Storage columns and field
types are unchanged. Editors read/write the draft's existing parsed fields (systemPermissions,rowLevelSecurity,tabPermissions,adminScope) and tolerate a JSON string on load so legacy rows survive.Known follow-up (framework)
Env-scope metadata saves of these facets do not yet project onto the queryable
sys_permission_setdata record that the Setup read-only summary reads, so a fresh Studio edit isn't reflected in Setup's summary until the projection refreshes. Enforcement reads the authoritative metadata (ADR-0090), so this is display-freshness only — tracked as a framework companion in #2398.Notes
CapabilityMultiSelectField+ widget-override plumbing are reused here, re-homed to Studio.🤖 Generated with Claude Code