Skip to content

feat: sys_user.primary_business_unit_id projection — pick people by BU (ADR-0057 D12) - #2146

Merged
xuyushun441-sys merged 1 commit into
mainfrom
feat/adr-0057-ps3-primary-bu
Jun 22, 2026
Merged

feat: sys_user.primary_business_unit_id projection — pick people by BU (ADR-0057 D12)#2146
xuyushun441-sys merged 1 commit into
mainfrom
feat/adr-0057-ps3-primary-bu

Conversation

@xuyushun441-sys

Copy link
Copy Markdown
Contributor

Final implementation increment of the ADR-0057 addendum (#2141) — PS-3 / D12. Builds on PS-1 (#2143).

What

Adds a denormalised sys_user.primary_business_unit_id lookup, maintained by plugin-sharing as a projection of sys_business_unit_member.is_primary.

Why

"Pick people by business unit" — the Dataverse filtered lookup / ServiceNow reference qualifier interaction — is a baseline ERP need that requires no hierarchy rollup. But it wasn't expressible: lookup fields filter only on the target object's own columns, sys_user had no BU column, and ObjectQL can't traverse the sys_business_unit_member junction in a single filter. Denormalising the primary BU onto sys_user makes where: { primary_business_unit_id: X } (and thus a lookupFilters picker filter) work with zero query-engine change.

How

  • Field on sys_user (mirrors manager_id, feat(platform-objects): add sys_user.manager_id to back the own_and_reports scope (ADR-0057) #2133) + en/zh/ja/es labels.
  • plugin-sharing binds afterInsert/afterUpdate/afterDelete hooks on sys_business_unit_member that recompute the owner's projection, plus a boot-time backfill for pre-existing rows. afterDelete exposes neither previous nor the deleted row, so user_id is captured in beforeDelete via the shared hookContext.
  • Home = plugin-sharing (always loaded, owns BusinessUnitGraphService), not plugin-org-scoping — that plugin is multi-tenant-only, and BU membership is usable single-tenant. So picker-filtering by BU is an open capability; only hierarchy rollup stays paid.

Notes / scope

  • sys_business_unit_member remains the effective-dated, matrix source of truth; the column is a maintained projection of is_primary, not a second source. Matrix/multi-BU pickers still use the two-step junction expansion.
  • lookupFilters is a client-side picker hint (no server enforcement), so the dogfood proves the server-verifiable deliverable: the column is maintained on insert/update/delete and filterable. Test: insert sets it, query filters by it, primary-flag move follows, delete clears.

Changeset: @objectstack/platform-objects + @objectstack/plugin-sharingminor.

🤖 Generated with Claude Code

…_id projection (ADR-0057 D12)
Denormalise the user's primary business unit onto sys_user, maintained by plugin-sharing from sys_business_unit_member.is_primary (insert/update/delete hooks + a boot-time backfill), so "pick people by BU" (Dataverse filtered lookup / ServiceNow reference qualifier) is expressible as a plain where:{primary_business_unit_id:X} — and thus a lookupFilters picker filter — with zero query-engine change, no junction traversal. Homed in plugin-sharing (always loaded, owns the BU graph) rather than plugin-org-scoping, so it works single-tenant. afterDelete loses the row, so user_id is captured in beforeDelete via the shared hookContext. Adds en/zh/ja/es labels + a dogfood proof (insert sets it, query filters by it, primary-flag move follows, delete clears).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercelBot commented Jun 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
specReadyReadyPreview, CommentJun 22, 2026 1:03am

Request Review

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tests tooling size/m labels Jun 22, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 3 package(s): @objectstack/dogfood, @objectstack/platform-objects, @objectstack/plugin-sharing.

6 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/concepts/packages.mdx(via @objectstack/platform-objects, @objectstack/plugin-sharing)
  • content/docs/concepts/setup-app.mdx(via @objectstack/platform-objects)
  • content/docs/guides/cheatsheets/permissions-matrix.mdx(via packages/plugins/plugin-sharing)
  • content/docs/guides/packages.mdx(via @objectstack/platform-objects, @objectstack/plugin-sharing)
  • content/docs/guides/security.mdx(via @objectstack/plugin-sharing)
  • content/docs/protocol/objectql/security.mdx(via packages/plugins/plugin-sharing)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@xuyushun441-sys
xuyushun441-sys merged commit 30c0313 into mainJun 22, 2026
17 checks passed
@xuyushun441-sys
xuyushun441-sys deleted the feat/adr-0057-ps3-primary-bu branch June 22, 2026 01:38
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@xuyushun441-sys@os-zhuang