Files
service_manager/backend/app/api/v1/endpoints/tenants.py
icamarillo 517297e89a feat: Version 1.10.0 - Refactorizacion, optimizacion UI y mejoras de seguridad
- Extraccion de helpers en backend: audit_helpers.py, helpers.py
- Modularizacion de schemas en archivos individuales por dominio
- Reduccion de audit.py en 953 lineas (74% del archivo)
- Reduccion de tickets.py en 655 lineas (60% del archivo)
- Expansion de auth.py con recuperacion de contrasenia y tokens
- Nuevos modulos: core/email.py, core/cache.py
- Reorganizacion de scripts a backend/scripts/
- Frontend: refactorizacion de audit page con array-driven components
- Frontend: correccion de 11 errores ortograficos en tickets page
- Frontend: proxy Docker corregido en vite.config.js
- Frontend: nuevas rutas forgot-password, reset-password, organization, profile
- Nuevas utilidades TS: colorUtils.ts, dateFormats.ts
- 5 nuevos archivos de tests unitarios en backend/tests/unit/
- Eliminacion de 3 scripts temporales de prueba
- Documentacion tecnica: CAMBIOS_v1.10.0.md, OPTIMIZACIONES_RENDIMIENTO.md
2026-02-19 13:48:21 -07:00

95 lines
3.1 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)
):
# 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)
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"}