117 lines
3.8 KiB
Python
117 lines
3.8 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy import select
|
|
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
|
|
from app.api.schemas.tenant import TenantBase, TenantCreate, TenantUpdate, TenantResponse
|
|
|
|
router = APIRouter()
|
|
|
|
@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)
|
|
):
|
|
from app.models.permission import TenantPermission, DEFAULT_PERMISSIONS
|
|
from datetime import datetime
|
|
|
|
# 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")
|
|
|
|
data = tenant.model_dump()
|
|
data['slug'] = data['slug'].lower().strip()
|
|
db_tenant = Tenant(**data)
|
|
db.add(db_tenant)
|
|
await db.flush() # genera el id sin hacer commit
|
|
|
|
# Inicializar permisos por defecto para el nuevo tenant
|
|
now = datetime.utcnow()
|
|
for role, perms in DEFAULT_PERMISSIONS.items():
|
|
for permission, granted in perms.items():
|
|
db.add(TenantPermission(
|
|
id=uuid.uuid4(),
|
|
tenant_id=db_tenant.id,
|
|
user_id=None,
|
|
role=role,
|
|
permission=permission,
|
|
granted=granted,
|
|
created_at=now,
|
|
updated_at=now,
|
|
))
|
|
|
|
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)
|
|
if "status" in update_data:
|
|
# Convertir string a enum TenantStatus
|
|
status_value = update_data.pop("status")
|
|
if isinstance(status_value, str):
|
|
tenant.status = TenantStatus(status_value)
|
|
else:
|
|
tenant.status = status_value
|
|
|
|
for field, value in update_data.items():
|
|
setattr(tenant, field, value)
|
|
|
|
await db.commit()
|
|
await db.refresh(tenant)
|
|
return tenant
|
|
|
|
@router.delete("/{tenant_id}", status_code=status.HTTP_204_NO_CONTENT)
|
|
async def delete_tenant(
|
|
tenant_id: uuid.UUID,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user = Depends(deps.get_current_active_superuser)
|
|
):
|
|
"""Eliminar un cliente (tenant) por ID."""
|
|
tenant = await db.get(Tenant, tenant_id)
|
|
if not tenant:
|
|
raise HTTPException(status_code=404, detail="Tenant not found")
|
|
|
|
await db.delete(tenant)
|
|
await db.commit()
|
|
return {"message": "Tenant deleted successfully"}
|