""" TenantPermission Model - ServiceManagerWeb Permisos dinámicos por tenant. - Si user_id es None → aplica al rol completo (default del tenant) - Si user_id tiene valor → override individual para ese usuario """ from sqlalchemy import String, Boolean, ForeignKey, UniqueConstraint from sqlalchemy.orm import Mapped, mapped_column, relationship from typing import Optional import uuid from app.core.database import Base, GUID CLIENT_PERMISSIONS = [ # Permisos funcionales "view_tickets", "create_tickets", "close_tickets", "view_reports", "manage_tenant_users", "create_issues", # Permisos de navegación - cliente "nav:tickets", "nav:organization", "nav:usuarios", ] INTERNAL_PERMISSIONS = [ # Permisos de navegación - interno "nav:tickets", "nav:users", "nav:tenants", "nav:categories", "nav:systems", "nav:sla", "nav:audit", "nav:reports", ] DEFAULT_PERMISSIONS = { "CLIENT_ADMIN": { # Funcionales — todo ON "view_tickets": True, "create_tickets": True, "close_tickets": True, "view_reports": True, "manage_tenant_users": True, "create_issues": True, # Navegación cliente — todo ON "nav:tickets": True, "nav:organization": True, "nav:usuarios": True, }, "CLIENT_USER": { # Funcionales "view_tickets": True, "create_tickets": True, "close_tickets": False, "view_reports": False, "manage_tenant_users": False, "create_issues": False, # Navegación cliente "nav:tickets": True, "nav:organization": False, "nav:usuarios": False, }, "ADMIN": { # Navegación interna — todo ON "nav:tickets": True, "nav:users": True, "nav:tenants": True, "nav:categories": True, "nav:systems": True, "nav:sla": True, "nav:audit": True, "nav:reports": True, }, "SUPPORT_MANAGER": { "nav:tickets": True, "nav:users": True, "nav:tenants": False, "nav:categories": True, "nav:systems": True, "nav:sla": True, "nav:audit": True, "nav:reports": True, }, "AGENT": { "nav:tickets": True, "nav:users": False, "nav:tenants": False, "nav:categories": False, "nav:systems": False, "nav:sla": False, "nav:audit": False, "nav:reports": False, }, "AUDITOR": { "nav:tickets": True, "nav:users": False, "nav:tenants": False, "nav:categories": False, "nav:systems": False, "nav:sla": False, "nav:audit": True, "nav:reports": True, }, } class TenantPermission(Base): __tablename__ = "tenant_permissions" tenant_id: Mapped[uuid.UUID] = mapped_column( GUID(), ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False, ) user_id: Mapped[Optional[uuid.UUID]] = mapped_column( GUID(), ForeignKey("users.id", ondelete="CASCADE"), nullable=True, ) role: Mapped[str] = mapped_column(String(50), nullable=False) permission: Mapped[str] = mapped_column(String(100), nullable=False) granted: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True) tenant: Mapped["Tenant"] = relationship("Tenant") user: Mapped[Optional["User"]] = relationship("User") __table_args__ = ( UniqueConstraint( "tenant_id", "role", "user_id", "permission", name="uq_tenant_permission" ), ) def __repr__(self) -> str: scope = f"user:{self.user_id}" if self.user_id else f"role:{self.role}" return f""