feat: expose organization hierarchy catalog

This commit is contained in:
2026-07-30 03:59:58 +02:00
parent 84ca4f39ae
commit 5ebdffc0ec
2 changed files with 53 additions and 0 deletions

View File

@@ -14,6 +14,7 @@ from govoplan_core.core.organizations import (
OrganizationFunctionRef, OrganizationFunctionRef,
OrganizationFunctionTypeRef, OrganizationFunctionTypeRef,
OrganizationFunctionTypeResolution, OrganizationFunctionTypeResolution,
OrganizationHierarchyCatalogRef,
OrganizationHierarchyDirection, OrganizationHierarchyDirection,
OrganizationHierarchyDirectory, OrganizationHierarchyDirectory,
OrganizationHierarchyEdgeRef, OrganizationHierarchyEdgeRef,
@@ -279,6 +280,35 @@ class SqlOrganizationDirectory(
return None return None
return _unit_type_ref(item) return _unit_type_ref(item)
def hierarchy_catalog(
self,
tenant_id: str,
) -> OrganizationHierarchyCatalogRef:
with self._session() as session:
structures = (
session.query(OrganizationStructure)
.filter(OrganizationStructure.tenant_id == tenant_id)
.order_by(OrganizationStructure.name, OrganizationStructure.id)
.all()
)
relation_types = (
session.query(OrganizationRelationType)
.filter(OrganizationRelationType.tenant_id == tenant_id)
.order_by(
OrganizationRelationType.structure_id,
OrganizationRelationType.name,
OrganizationRelationType.id,
)
.all()
)
return OrganizationHierarchyCatalogRef(
tenant_id=tenant_id,
structures=tuple(_structure_ref(item) for item in structures),
relation_types=tuple(
_relation_type_ref(item) for item in relation_types
),
)
def get_function_type( def get_function_type(
self, self,
tenant_id: str, tenant_id: str,

View File

@@ -240,6 +240,29 @@ class OrganizationHierarchyDirectoryTests(unittest.TestCase):
project.matches[0].path[0].relation_type.id, project.matches[0].path[0].relation_type.id,
) )
def test_hierarchy_catalog_is_tenant_scoped_and_preserves_structure_links(
self,
) -> None:
catalog = self.directory.hierarchy_catalog("tenant-1")
empty = self.directory.hierarchy_catalog("tenant-2")
self.assertEqual(
{self.employer.id, self.project.id},
{item.id for item in catalog.structures},
)
self.assertEqual(
{
(self.employer_parent.id, self.employer.id),
(self.project_parent.id, self.project.id),
},
{
(item.id, item.structure_id)
for item in catalog.relation_types
},
)
self.assertEqual((), empty.structures)
self.assertEqual((), empty.relation_types)
def test_bounded_paths_report_depth_and_cycles(self) -> None: def test_bounded_paths_report_depth_and_cycles(self) -> None:
bounded = self.directory.resolve_hierarchy_relatives( bounded = self.directory.resolve_hierarchy_relatives(
"tenant-1", "tenant-1",