ValwispDocs
DesarrolladoresGuías

Agregar un permiso al catálogo

Agregar un código al catálogo de permisos no es suficiente para que llegue a los tenants existentes — hay que sembrarlo y limpiar caché.

El error común

Agregar un @CheckPermission('accion', 'modulo') nuevo en un controller, junto con su entrada en permission-catalog.ts, no alcanza automáticamente a los tenants ya existentes. Es fácil asumir que sí, porque DEFAULT_ROLE_PERMISSIONS vive en código — pero ese camino solo se usa como legacy fallback para usuarios sin roleId dinámico. La mayoría de usuarios reales (incluido cualquier Admin de un tenant en producción) usan el camino DB-backed, que ignora por completo esas constantes en tiempo de ejecución — solo las lee un script de seed puntual.

Ver el sistema completo en Autenticación → CaslAbilityFactory.

Cómo aplicarlo correctamente

Cada vez que agregues un código nuevo a PERMISSION_CATALOG/DEFAULT_ROLE_PERMISSIONS y lo despliegues:

  1. Verifica si afecta a tenants ya existentes — casi siempre sí, si el permiso debe estar disponible para roles que ya tienen usuarios activos.
  2. Corre la lógica de seed contra todos los tenantsRolesService.seedPermissions()
    • seedDefaultRoles(tenantId) es lo que alimenta la tabla RolePermission. El endpoint POST /roles/seed solo cubre un tenant a la vez y requiere ser SUPER_ADMIN de ese tenant específico — no sirve para aplicar el cambio a todos de una vez.
  3. Limpia la caché de Redis, o el cambio no se sentirá hasta que expire el TTL de 5 minutos:
    docker exec valwisp-redis redis-cli KEYS 'ability:*' | xargs redis-cli DEL

Por qué importa

Esto no es hipotético: en julio de 2026 se agregó time-entries:record y dio 403 real en producción para el Admin de un tenant, a pesar de que ADMIN debería tener todos los permisos — porque el nuevo código nunca se sembró contra ese tenant. Al revisar, otras adiciones recientes de esa misma sesión (templates:read/update, branches:create) tampoco habían llegado a ningún tenant real.

Pendiente conocido

No existe todavía un endpoint "seed all tenants" (a nivel de plataforma, no por tenant) — hoy se resuelve con un script one-off contra el contenedor de producción. Construir ese endpoint evitaría repetir el proceso manual cada vez.

On this page