""" Tenant management endpoints. Provides tenant list and management functionality. """ import logging from typing import Annotated from fastapi import APIRouter, Depends from fastapi.responses import JSONResponse from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.core.database import get_session from app.core.exceptions import MissingTenantIdException from app.core.middleware import parse_tenant_id from app.core.tenant import get_tenant_id from app.models import ErrorResponse from app.models.entities import Tenant logger = logging.getLogger(__name__) router = APIRouter(prefix="/admin/tenants", tags=["Tenants"]) def get_current_tenant_id() -> str: """Dependency to get current tenant ID or raise exception.""" tenant_id = get_tenant_id() if not tenant_id: raise MissingTenantIdException() return tenant_id @router.get( "", operation_id="listTenants", summary="List all tenants", description="Get a list of all tenants from the system.", responses={ 200: {"description": "List of tenants"}, 401: {"description": "Unauthorized", "model": ErrorResponse}, 403: {"description": "Forbidden", "model": ErrorResponse}, }, ) async def list_tenants( session: Annotated[AsyncSession, Depends(get_session)], ) -> JSONResponse: """ Get a list of all tenants from the tenants table. Returns tenant ID and display name (first part of tenant_id). """ logger.info("Getting all tenants") # Get all tenants from tenants table stmt = select(Tenant).order_by(Tenant.created_at.desc()) result = await session.execute(stmt) tenants = result.scalars().all() # Format tenant list with display name tenant_list = [] for tenant in tenants: name, year = parse_tenant_id(tenant.tenant_id) tenant_list.append({ "id": tenant.tenant_id, "name": f"{name} ({year})", "displayName": name, "year": year, "createdAt": tenant.created_at.isoformat() if tenant.created_at else None, }) logger.info(f"Found {len(tenant_list)} tenants: {[t['id'] for t in tenant_list]}") return JSONResponse( content={ "tenants": tenant_list, "total": len(tenant_list) } )