Coverage for src/lexigram/admin/di/sub_providers/tenancy.py: 72%

25 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-21 14:56 +0800

1"""Admin tenancy sub-provider — wires multi-tenancy into the admin panel.""" 

2 

3from __future__ import annotations 

4 

5from typing import TYPE_CHECKING, Any 

6 

7from lexigram.admin.multitenancy.adapter import TenantProviderRegistry 

8from lexigram.contracts.core.health import HealthCheckResult, HealthStatus 

9from lexigram.logging import get_logger 

10 

11if TYPE_CHECKING: 

12 from lexigram.admin.config import AdminConfig 

13 from lexigram.contracts.core.di import ( 

14 ContainerRegistrarProtocol, 

15 ContainerResolverProtocol, 

16 ) 

17 

18logger = get_logger(__name__) 

19 

20 

21class AdminTenancySubProvider: 

22 """Manages tenant resolution, registry, and data source scoping.""" 

23 

24 def __init__(self, config: AdminConfig) -> None: 

25 self._config = config 

26 

27 async def register(self, container: ContainerRegistrarProtocol) -> None: 

28 """Register tenant registry and middleware in the DI container.""" 

29 if not self._config.tenancy.enabled: 

30 logger.debug("admin.tenancy_disabled") 

31 return 

32 

33 registry = TenantProviderRegistry() 

34 container.singleton(TenantProviderRegistry, registry) 

35 logger.debug("admin.tenancy_registered") 

36 

37 async def boot(self, container: ContainerResolverProtocol) -> None: 

38 """Tenancy boot — no additional init required.""" 

39 

40 async def shutdown(self) -> None: 

41 """Tenancy shutdown.""" 

42 

43 def get_middleware(self) -> tuple[type, dict[str, Any]] | None: 

44 """Return the tenant middleware tuple if tenancy is enabled. 

45 

46 Returns (AdminTenantMiddleware, {config}) or None. 

47 """ 

48 if not self._config.tenancy.enabled: 

49 return None 

50 from lexigram.admin.middleware.tenant import AdminTenantMiddleware 

51 

52 return (AdminTenantMiddleware, {"config": self._config.tenancy}) 

53 

54 async def health_check(self, timeout: float = 5.0) -> HealthCheckResult: 

55 """Report tenancy sub-provider health.""" 

56 return HealthCheckResult( 

57 component="admin.tenancy", 

58 status=HealthStatus.HEALTHY, 

59 details={ 

60 "enabled": self._config.tenancy.enabled, 

61 }, 

62 )