""" Servizio tenant – gestione organizzazioni (solo super_admin). """ import uuid from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.core.exceptions import ConflictError, NotFoundError from app.core.security import hash_password from app.models.tenant import Tenant from app.models.user import User from app.schemas.tenant import TenantCreateRequest, TenantUpdateRequest class TenantService: def __init__(self, db: AsyncSession) -> None: self.db = db async def create_tenant(self, data: TenantCreateRequest) -> tuple[Tenant, User]: """Crea un nuovo tenant con il suo utente admin iniziale.""" # Verifica slug univoco existing = await self.db.execute( select(Tenant).where(Tenant.slug == data.slug) ) if existing.scalar_one_or_none(): raise ConflictError(f"Slug '{data.slug}' già in uso") tenant = Tenant( slug=data.slug, name=data.name, plan=data.plan, max_mailboxes=data.max_mailboxes, max_users=data.max_users, ) self.db.add(tenant) await self.db.flush() # ottieni tenant.id # Crea utente admin iniziale admin = User( tenant_id=tenant.id, email=data.admin_email.lower(), password_hash=hash_password(data.admin_password), full_name=data.admin_full_name, role="admin", ) self.db.add(admin) await self.db.flush() return tenant, admin async def get_tenant(self, tenant_id: uuid.UUID) -> Tenant: tenant = await self.db.get(Tenant, tenant_id) if not tenant: raise NotFoundError("tenant") return tenant async def list_tenants(self) -> list[Tenant]: result = await self.db.execute( select(Tenant).order_by(Tenant.created_at.desc()) ) return list(result.scalars().all()) async def update_tenant( self, tenant_id: uuid.UUID, data: TenantUpdateRequest ) -> Tenant: tenant = await self.get_tenant(tenant_id) if data.name is not None: tenant.name = data.name if data.plan is not None: tenant.plan = data.plan if data.is_active is not None: tenant.is_active = data.is_active if data.max_mailboxes is not None: tenant.max_mailboxes = data.max_mailboxes if data.max_users is not None: tenant.max_users = data.max_users return tenant