Concepts
Organizations
The org tree, ancestors, descendants, and scope resolution.
Organizations are the backbone of Multi-OrBAC. morbac.orgs is a tree:
every org has a unique name, an optional parent_id, and free-form JSONB
metadata. Deleting an org cascades to its subtree, its roles and its rules.
INSERT INTO morbac.orgs (name) VALUES ('Groupe Hospitalier Valmont');
INSERT INTO morbac.orgs (name, parent_id)
SELECT 'Clinique Valmont Nord', id FROM morbac.orgs WHERE name = 'Groupe Hospitalier Valmont';
INSERT INTO morbac.orgs (name, parent_id)
SELECT 'Pharmacie Valmont Nord', id FROM morbac.orgs WHERE name = 'Clinique Valmont Nord';Traversal functions
| Function | Returns |
|---|---|
get_org_ancestors(org) | the org and every ancestor, with depth (0 = self) |
get_org_descendants(org) | the org and every descendant, with depth |
get_org_scope(org, scope, max_depth) | a named slice of the tree (below) |
SELECT o.name, s.depth
FROM morbac.get_org_scope(
(SELECT id FROM morbac.orgs WHERE name = 'Clinique Valmont Nord'),
'subtree', NULL) s
JOIN morbac.orgs o ON o.id = s.org_id;
-- Clinique Valmont Nord (0), Pharmacie Valmont Nord (1), Cardiologie Valmont Nord (1)Scope names
Rules carry a scope that is resolved against the tree at query time, so new
organizations are covered the moment they are created:
| Scope | Meaning |
|---|---|
self | exactly this org (default) |
children | direct children only |
descendants | all descendants, excluding self |
subtree | self plus all descendants |
parent | direct parent only |
ancestors | all ancestors, excluding self |
lineage | self plus all ancestors |
root | the topmost ancestor only |
A rule written at Groupe Hospitalier Valmont with scope subtree applies to both
hospitals, every department, and any clinic acquired next year, with no
further writes. See the org hierarchies recipe.
Design guidance
- Model authority boundaries, not org charts. If Pharmacie Valmont Nord never needs its own roles or rules, it does not need to be an org.
- Org names are globally unique. Use qualified names (
Pharmacie Valmont Nord, notPharmacy) rather than relying on the tree for disambiguation. metadatais yours: store display labels, external ids, feature flags. The engine never reads it.