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

xuyushun441-sys merged 1 commit into
mainfrom
feat/adr-0057-ps3-primary-bu

Conversation

@xuyushun441-sys

Copy link
Copy Markdown
Collaborator

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-sharing minor.

🤖 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

vercel Bot commented Jun 22, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jun 22, 2026 1:03am

Request Review

@github-actions github-actions Bot 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants