diff --git a/src/govoplan_tenancy/backend/api/v1/routes.py b/src/govoplan_tenancy/backend/api/v1/routes.py index df8219c..14c1636 100644 --- a/src/govoplan_tenancy/backend/api/v1/routes.py +++ b/src/govoplan_tenancy/backend/api/v1/routes.py @@ -1,5 +1,6 @@ from __future__ import annotations +from collections.abc import Mapping, Sequence from typing import Any from fastapi import APIRouter, Body, Depends, HTTPException, Query, status @@ -33,6 +34,7 @@ from govoplan_core.tenancy.service import ( assert_tenant_governance_override_allowed, effective_tenant_governance, tenant_counts, + tenant_counts_many, ) from govoplan_tenancy.backend.db.models import Tenant from govoplan_tenancy.backend.lifecycle import ( @@ -125,7 +127,12 @@ def _tenant_or_404(session: Session, tenant_id: str) -> Tenant: return tenant -def _tenant_item(session: Session, tenant: Tenant) -> TenantAdminItem: +def _tenant_item( + session: Session, + tenant: Tenant, + *, + counts: Mapping[str, int] | None = None, +) -> TenantAdminItem: governance = effective_tenant_governance(session, tenant) return TenantAdminItem( id=tenant.id, @@ -143,16 +150,36 @@ def _tenant_item(session: Session, tenant: Tenant) -> TenantAdminItem: "allow_api_keys": governance.allow_api_keys, }, is_active=tenant.is_active, - counts=tenant_counts( - session, - tenant.id, - module_ids=("campaigns", "files"), + counts=( + dict(counts) + if counts is not None + else tenant_counts( + session, + tenant.id, + module_ids=("campaigns", "files"), + ) ), created_at=tenant.created_at, updated_at=tenant.updated_at, ) +def _tenant_items(session: Session, tenants: Sequence[Tenant]) -> list[TenantAdminItem]: + counts_by_tenant = tenant_counts_many( + session, + [tenant.id for tenant in tenants], + module_ids=("campaigns", "files"), + ) + return [ + _tenant_item( + session, + tenant, + counts=counts_by_tenant.get(tenant.id, {}), + ) + for tenant in tenants + ] + + def _tenant_deletion_plan(session: Session, tenant: Tenant, principal: ApiPrincipal, *, mode: str = "retire") -> TenantDeletionPlanResponse: issues: list[TenantLifecycleIssue] = [] counts = tenant_counts(session, tenant.id) @@ -480,7 +507,7 @@ def list_tenants( page_size=page_size, ) return TenantListResponse( - tenants=[_tenant_item(session, tenant) for tenant in tenants], + tenants=_tenant_items(session, tenants), **pagination, ) @@ -504,7 +531,7 @@ def _full_tenant_list_delta_response( ) has_more = page < pagination["pages"] return TenantListDeltaResponse( - tenants=[_tenant_item(session, tenant) for tenant in tenants], + tenants=_tenant_items(session, tenants), deleted=[], watermark=( _tenant_full_cursor( @@ -544,7 +571,7 @@ def list_tenants_delta( tenants = session.query(Tenant).filter(Tenant.id.in_(changed_ids)).order_by(Tenant.name.asc()).all() visible_tenant_ids = {tenant.id for tenant in tenants} return TenantListDeltaResponse( - tenants=[_tenant_item(session, tenant) for tenant in tenants], + tenants=_tenant_items(session, tenants), deleted=_tenant_list_deleted_entries(entries, visible_tenant_ids), watermark=_tenant_list_response_watermark(session, entries=entries, has_more=has_more), has_more=has_more,