Skip to content

feat(relations): read an object's tree along its declared parent property - #4656

Merged
rubenvdlinde merged 1 commit into
developmentfrom
feat/object-relation-tree
Oct 15, 2026
Merged

rubenvdlinde merged 1 commit into
developmentfrom
feat/object-relation-tree

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Decision 250: an organisation's parent/subsidiary tree is a generic OpenRegister relation, and apps read it the same way.

What this adds

  • ObjectTreeService::tree() returns the descendants, ancestors or both of one object along the parent property its schema already declares: x-openregister-hierarchy.parent, else x-openregister-party.parentProperty. No new annotation. An organisation group uses the party declaration, so no access flows down the tree.
  • Each node carries uuid, name, level (ancestors negative, root 0), parent and any requested fields.
  • Bounds: the declared maxDepth, the requested depth, and the node cap (relationGraphMaxNodes). truncatedBy says which one stopped the walk (depth, cap or unreadable), and is only set when there really is more.
  • Cycles: a uuid is never added twice.
  • RBAC: every level goes through MagicMapper::filterReadableUuids(). An unreadable node is left out along with its subtree, and the walk up stops at the first unreadable ancestor. In-process callers that scope their own reads can pass _rbac: false.
  • GET /api/objects/{register}/{schema}/{id}/tree?direction=descendants|ancestors|both&depth=&fields=a,b: the root is resolved through ObjectReadAccess, so an unreadable root gets a 404 and nothing is walked.
  • OpenSpec change object-tree-read: what a party organisation is in this fleet, the design, and REQ-OTR-001/002.

Verified locally

  • New tests: ObjectTreeServiceTest (10 tests) uses a real organisation fragment that passes both save-time validators and covers levels, a cycle, the depth bound, the declared cap, the node cap, RBAC pruning down and up, and the hierarchy declaration. ObjectRelationsControllerTreeTest (4 tests). As a control, I switched off the RBAC filter and the two RBAC tests failed.
  • phpcs 0 and phpmd 0 on the changed lib files. phpstan 0. psalm (--threads=1) 0.
  • Full PHPUnit --no-coverage: 26,237 tests, 15 errors, all in tests/Unit/Db/* SQLite-migration tests that need Nextcloud core (OC\DB\Schema\Table not loadable). That is environment, not this change.

Follow-ups (other repos)

  • dossiq kvkCompany needs a parentCompany property and an x-openregister-party block before any group shows live.
  • portaliq reads this tree in PortalPartyTreeResolver.
  • KvK cannot fill the relation. Its APIs (Zoeken, Basisprofiel, Vestigingsprofiel, Naamgeving, Mutatieservice) carry no group relations, and "Concernrelaties" is an ordered product, not an API. See proposal.md.

…erty

ObjectTreeService walks descendants, ancestors or both along the parent
property a schema already declares (x-openregister-hierarchy.parent, else
x-openregister-party.parentProperty), one query per level, with levels,
cycle protection, the declared depth, the requested depth and the node
cap, and the caller's read access on every node. Exposed as
GET /api/objects/{register}/{schema}/{id}/tree. Decision 250.
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/openregister @ 1cc896b

Check PHP Vue Security License Tests
lint ✅
phpcs ✅
phpmd ✅
psalm ✅
phpstan ✅
phpmetrics ✅
eslint ✅
stylelint ✅
build ✅
check-specs ✅
test-l10n ✅
test-l10n-parity ✅
format ✅
check-schema-l10n ✅
composer ✅ ✅ 173/173
npm ✅ ✅ 648/648
app:check-code ⏭️
info.xml ✅
REUSE ✅
lockfile sync ✅
PHPUnit ✅ 26212/26212 · 25 skipped
Newman ✅ 714/714
Playwright ⏭️ deferred: E2E runs locally and on the promotion path only. This pull request targets development, so the suite is asked once per promotion into beta and main rather than once per push per open pull request. Run it locally with npx playwright test, or from the Actions tab on a branch with no open pull request into development.
Hydra gates ✅

Quality workflow — 2026-10-15 18:42 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde
rubenvdlinde merged commit 5296caf into development Oct 15, 2026
48 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant