from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from pydantic import BaseModel, ConfigDict, EmailStr from typing import List, Optional import uuid from app.core.database import get_db from app.models.tenant import Tenant, TenantStatus from app.api import deps router = APIRouter() class TenantBase(BaseModel): name: str slug: str domain: Optional[str] = None contact_email: Optional[EmailStr] = None class TenantCreate(TenantBase): pass class TenantUpdate(BaseModel): name: Optional[str] = None slug: Optional[str] = None domain: Optional[str] = None contact_email: Optional[EmailStr] = None status: Optional[TenantStatus] = None class TenantResponse(TenantBase): id: uuid.UUID status: TenantStatus model_config = ConfigDict(from_attributes=True) @router.get("/", response_model=List[TenantResponse]) async def read_tenants( skip: int = 0, limit: int = 100, db: AsyncSession = Depends(get_db), current_user = Depends(deps.get_current_active_superuser) ): query = select(Tenant).offset(skip).limit(limit) result = await db.execute(query) return result.scalars().all() @router.post("/", response_model=TenantResponse) async def create_tenant( tenant: TenantCreate, db: AsyncSession = Depends(get_db), current_user = Depends(deps.get_current_active_superuser) ): # Check existing slug query = select(Tenant).where(Tenant.slug == tenant.slug) result = await db.execute(query) if result.scalar_one_or_none(): raise HTTPException(status_code=400, detail="Tenant slug already exists") db_tenant = Tenant(**tenant.model_dump()) db.add(db_tenant) await db.commit() await db.refresh(db_tenant) return db_tenant @router.get("/{tenant_id}", response_model=TenantResponse) async def read_tenant( tenant_id: uuid.UUID, db: AsyncSession = Depends(get_db), current_user = Depends(deps.get_current_active_superuser) ): tenant = await db.get(Tenant, tenant_id) if not tenant: raise HTTPException(status_code=404, detail="Tenant not found") return tenant @router.put("/{tenant_id}", response_model=TenantResponse) async def update_tenant( tenant_id: uuid.UUID, tenant_in: TenantUpdate, db: AsyncSession = Depends(get_db), current_user = Depends(deps.get_current_active_superuser) ): tenant = await db.get(Tenant, tenant_id) if not tenant: raise HTTPException(status_code=404, detail="Tenant not found") update_data = tenant_in.model_dump(exclude_unset=True) for field, value in update_data.items(): setattr(tenant, field, value) db.add(tenant) await db.commit() await db.refresh(tenant) return tenant