This commit is contained in:
2026-03-03 14:02:18 -07:00
parent f10b15d91b
commit 3b46f48655
13 changed files with 1041 additions and 99 deletions

View File

@@ -0,0 +1,63 @@
"""
Definición y helpers de roles para el sistema multi-tenant.
Fuente única: UserRole en app.models.user.
Este módulo expone conjuntos de roles y helpers de verificación
para usarse en deps.py y en los endpoints.
Roles globales (staff interno — alcance multi-tenant):
ADMIN → control total sobre todos los tenants
SUPPORT_MANAGER → gestiona equipos y SLAs de todos los tenants
AGENT → atiende tickets de cualquier tenant
AUDITOR → auditoría de solo lectura en todos los tenants
Roles de cliente (alcance limitado al propio tenant):
CLIENT_ADMIN → administra organización: usuarios, configuración, tickets
CLIENT_USER → crea y sigue sus propios tickets
"""
from app.models.user import UserRole
# ── Conjuntos de roles ──────────────────────────────────────────────────────
GLOBAL_ROLES: frozenset[UserRole] = frozenset({
UserRole.ADMIN,
UserRole.SUPPORT_MANAGER,
UserRole.AGENT,
UserRole.AUDITOR,
})
CLIENT_ROLES: frozenset[UserRole] = frozenset({
UserRole.CLIENT_ADMIN,
UserRole.CLIENT_USER,
})
# ── Permisos por rol ────────────────────────────────────────────────────────
ROLE_PERMISSIONS: dict[UserRole, list[str]] = {
# Staff global
UserRole.ADMIN: ["manage_all", "view_all", "audit_all"],
UserRole.SUPPORT_MANAGER: ["manage_teams", "view_all_tickets", "manage_sla"],
UserRole.AGENT: ["view_all_tickets", "update_any_ticket"],
UserRole.AUDITOR: ["view_all", "audit_all"],
# Clientes (acotados al tenant)
UserRole.CLIENT_ADMIN: ["manage_tenant", "manage_tenant_users", "view_tenant_tickets"],
UserRole.CLIENT_USER: ["create_ticket", "view_own_tickets"],
}
# ── Helpers ─────────────────────────────────────────────────────────────────
def is_global_staff(role: UserRole) -> bool:
"""Retorna True si el rol tiene alcance global (staff interno)."""
return role.is_global
def is_client_role(role: UserRole) -> bool:
"""Retorna True si el rol está acotado al tenant del usuario."""
return role.is_client
def has_permission(role: UserRole, permission: str) -> bool:
"""Verifica si un rol tiene un permiso específico."""
return permission in ROLE_PERMISSIONS.get(role, [])