Files

61 lines
2.3 KiB
Python

"""
Tenant Model - ServiceManagerWeb
Modelo para organizaciones cliente (multi-tenancy)
"""
from sqlalchemy import String, Integer, Text, Boolean, JSON
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy.dialects.postgresql import UUID, ENUM, ARRAY as PG_ARRAY
from typing import List, Optional
import enum
import uuid
from app.core.database import Base
class TenantStatus(str, enum.Enum):
"""Estados de un tenant."""
ACTIVE = "active"
SUSPENDED = "suspended"
INACTIVE = "inactive"
class Tenant(Base):
"""Modelo de Tenant (Organización cliente)."""
__tablename__ = "tenants"
# Información básica
name: Mapped[str] = mapped_column(String(255), nullable=False)
slug: Mapped[str] = mapped_column(String(100), unique=True, nullable=False)
domain: Mapped[Optional[str]] = mapped_column(String(255))
logo_url: Mapped[Optional[str]] = mapped_column(String(500))
# Contacto
contact_email: Mapped[Optional[str]] = mapped_column(String(320))
contact_phone: Mapped[Optional[str]] = mapped_column(String(20))
address: Mapped[Optional[str]] = mapped_column(Text)
# Configuración regional
timezone: Mapped[str] = mapped_column(String(50), default="UTC")
locale: Mapped[str] = mapped_column(String(10), default="es-ES")
# Límites y configuración
max_users: Mapped[int] = mapped_column(Integer, default=50)
max_storage_mb: Mapped[int] = mapped_column(Integer, default=1024)
allowed_file_types: Mapped[List[str]] = mapped_column(
JSON().with_variant(PG_ARRAY(String), "postgresql"),
default=["pdf", "jpg", "jpeg", "png", "doc", "docx", "xls", "xlsx", "txt"]
)
# Estado
status: Mapped[TenantStatus] = mapped_column(
String(20),
default=TenantStatus.ACTIVE
)
# Relaciones
users: Mapped[List["User"]] = relationship("User", back_populates="tenant")
tickets: Mapped[List["Ticket"]] = relationship("Ticket", back_populates="tenant")
categories: Mapped[List["Category"]] = relationship("Category", back_populates="tenant") # ✅ CORREGIDO: Era "TicketCategory"
client_profile: Mapped[Optional["ClientProfile"]] = relationship("ClientProfile", back_populates="tenant", uselist=False)
def __repr__(self) -> str:
return f"<Tenant(id={self.id}, name='{self.name}', slug='{self.slug}')>"