Notas de versión — 10 de abril de 2026
Esta versión implementa el bloqueo por nivel para roles personalizados (RBAC) y corrige un error de colisión de índice único en los roles de espacio de trabajo.
Roles personalizados — Solo ENTERPRISE (RBAC Tier-Gate)
Descripción general
La creación, edición y eliminación de roles de permisos personalizados está ahora restringida al plan Enterprise. Este es el estándar del sector — Clockify y Toggl Track también limitan los roles personalizados a su plan más alto.
Los roles predeterminados (Visor, Miembro, Gestor, Propietario) siguen disponibles en todos los planes sin cambios.
Backend
| Endpoint | Guard |
|---|---|
POST /api/v1/workspace-roles | requireFeature('customRoles') |
PUT /api/v1/workspace-roles/:roleId | requireFeature('customRoles') |
DELETE /api/v1/workspace-roles/:roleId | requireFeature('customRoles') |
Los espacios de trabajo que no sean Enterprise recibirán 403 FEATURE_NOT_AVAILABLE.
Frontend
useFeatureAccess.ts:customRolesestablecido en'enterprise'UnifiedRolesPage.tsx: el botón "Nuevo rol" envuelto en<FeatureGate feature="customRoles">— oculto en planes FREE/PRO
Página de comparación de precios
/api/v1/pricing-comparison ahora devuelve una fila custom-roles en la categoría Equipo y Colaboración:
| FREE | PRO | ENTERPRISE | |
|---|---|---|---|
| Roles personalizados |
Corrección: Colisión de índice único en roles de espacio de trabajo
Problema
Los roles de espacio de trabajo (scope: workspace) tienen unitId: null porque no están vinculados a una unidad específica. El índice único { unitId, scope, name } provocaba un error E11000 DuplicateKey a partir del segundo espacio de trabajo.
Impacto: El endpoint /api/v1/workspace-roles?scope=workspace devolvía una lista vacía para todos los espacios de trabajo excepto el primero.
Corrección
UnifiedRole.model.ts: Dos índices únicos parciales (en lugar de uno)roleCopy.service.ts:insertOne→findOneAndUpdate + upsert(idempotente)- Script de migración ejecutado: 25 bases de datos de unidad reparadas, roles de espacio de trabajo faltantes rellenados
Resumen de cambios
| Capa | Cambio |
|---|---|
Backend tier.types.ts | customRoles añadido a FeatureName |
Backend FeatureGate.service.ts | Mapeo customRoles → team.departments en ambos feature maps |
Backend workspaceRoles.routes.ts | requireFeature('customRoles') en POST / PUT / DELETE |
Backend UnifiedRole.model.ts | unitId: required: false + 2 índices únicos parciales |
Backend pricing.controller.ts | Fila custom-roles en categoría Equipo y Colaboración |
Backend stripe.config.ts | 'Roles personalizados (RBAC)' en lista de funciones ENTERPRISE |
Frontend useFeatureAccess.ts | customRoles: 'enterprise' |
Frontend UnifiedRolesPage.tsx | Botón "Nuevo rol" envuelto en <FeatureGate> |
Disponibilidad: Crear/editar/eliminar roles personalizados — Solo Enterprise. Roles predeterminados — todos los planes.