letsbe-orchestrator/app/routes/tenants.py

86 lines
2.2 KiB
Python
Raw Normal View History

"""Tenant management endpoints."""
import uuid
from fastapi import APIRouter, HTTPException, status
from sqlalchemy import select
from app.db import AsyncSessionDep
from app.models.tenant import Tenant
from app.schemas.tenant import TenantCreate, TenantResponse
router = APIRouter(prefix="/tenants", tags=["Tenants"])
# --- Helper functions (embryonic service layer) ---
async def create_tenant(db: AsyncSessionDep, tenant_in: TenantCreate) -> Tenant:
"""Create a new tenant in the database."""
tenant = Tenant(
name=tenant_in.name,
domain=tenant_in.domain,
)
db.add(tenant)
await db.commit()
await db.refresh(tenant)
return tenant
async def get_tenants(db: AsyncSessionDep) -> list[Tenant]:
"""Retrieve all tenants from the database."""
result = await db.execute(select(Tenant).order_by(Tenant.created_at.desc()))
return list(result.scalars().all())
async def get_tenant_by_id(db: AsyncSessionDep, tenant_id: uuid.UUID) -> Tenant | None:
"""Retrieve a tenant by ID."""
result = await db.execute(select(Tenant).where(Tenant.id == tenant_id))
return result.scalar_one_or_none()
# --- Route handlers (thin controllers) ---
@router.post("", response_model=TenantResponse, status_code=status.HTTP_201_CREATED)
async def create_tenant_endpoint(
tenant_in: TenantCreate,
db: AsyncSessionDep,
) -> Tenant:
"""
Create a new tenant.
- **name**: Unique tenant name (required)
- **domain**: Optional domain for the tenant
"""
return await create_tenant(db, tenant_in)
@router.get("", response_model=list[TenantResponse])
async def list_tenants_endpoint(db: AsyncSessionDep) -> list[Tenant]:
"""
List all tenants.
Returns a list of all registered tenants.
"""
return await get_tenants(db)
@router.get("/{tenant_id}", response_model=TenantResponse)
async def get_tenant_endpoint(
tenant_id: uuid.UUID,
db: AsyncSessionDep,
) -> Tenant:
"""
Get a tenant by ID.
Returns the tenant with the specified UUID.
"""
tenant = await get_tenant_by_id(db, tenant_id)
if tenant is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Tenant {tenant_id} not found",
)
return tenant