Visión General
El sistema implementa un modelo de permisos granular que permite controlar con precisión qué acciones puede realizar cada rol en cada módulo del sistema.Modelo de Datos
Permission
Modelo:App\Models\Permission
Ubicación: app/Models/Permission.php
Tabla: permissions
Campos:
| Campo | Tipo | Descripción |
|---|---|---|
permission_id | integer | Identificador único del permiso (PK) |
name | string | Nombre único del permiso (ej: ventas.create) |
display_name | string | Nombre legible del permiso (ej: Crear Ventas) |
module | string | Módulo al que pertenece (ej: ventas) |
action | string | Acción que permite (ej: create) |
description | text | Descripción del permiso |
created_at | timestamp | Fecha de creación |
updated_at | timestamp | Fecha de actualización |
Tabla Pivot: role_permission
Tabla:role_permission
Campos:
| Campo | Tipo | Descripción |
|---|---|---|
id | integer | Identificador único (PK) |
rol_id | integer | ID del rol (FK → roles.rol_id) |
permission_id | integer | ID del permiso (FK → permissions.permission_id) |
created_at | timestamp | Fecha de asignación |
updated_at | timestamp | Fecha de actualización |
[rol_id, permission_id] - Un rol no puede tener el mismo permiso duplicado.
Nomenclatura de Permisos
Los permisos siguen el formato:{módulo}.{acción}
Estructura
- Módulo: Área funcional del sistema (ventas, productos, clientes, etc.)
- Acción: Operación permitida (view, create, edit, delete)
Ejemplos
ventas.view→ Ver ventasventas.create→ Crear ventasproductos.edit→ Editar productosclientes.delete→ Eliminar clientes
Permisos del Sistema
El sistema incluye los siguientes permisos por defecto:Módulo: Ventas
| Permiso | Nombre para Mostrar | Descripción |
|---|---|---|
ventas.view | Ver Ventas | Permiso para Ver en el módulo de Ventas |
ventas.create | Crear Ventas | Permiso para Crear en el módulo de Ventas |
ventas.edit | Editar Ventas | Permiso para Editar en el módulo de Ventas |
ventas.delete | Eliminar Ventas | Permiso para Eliminar en el módulo de Ventas |
GET /api/ventas→ventas.viewPOST /api/ventas→ventas.createPUT /api/ventas/{id}→ventas.editDELETE /api/ventas/{id}→ventas.deletePOST /api/ventas/{id}/anular→ventas.deletePOST /api/ventas/{id}/descontar-stock→ventas.editGET /api/ventas/exportar-*→ventas.view
Módulo: Productos
| Permiso | Nombre para Mostrar | Descripción |
|---|---|---|
productos.view | Ver Productos | Permiso para Ver en el módulo de Productos |
productos.create | Crear Productos | Permiso para Crear en el módulo de Productos |
productos.edit | Editar Productos | Permiso para Editar en el módulo de Productos |
productos.delete | Eliminar Productos | Permiso para Eliminar en el módulo de Productos |
GET /api/productos→productos.viewPOST /api/productos→productos.createPUT /api/productos/{id}→productos.editDELETE /api/productos/{id}→productos.deleteGET /api/movimientos-stock→productos.viewPOST /api/productos/leer-excel→productos.createPOST /api/productos/importar-lista→productos.create
Módulo: Clientes
| Permiso | Nombre para Mostrar | Descripción |
|---|---|---|
clientes.view | Ver Clientes | Permiso para Ver en el módulo de Clientes |
clientes.create | Crear Clientes | Permiso para Crear en el módulo de Clientes |
clientes.edit | Editar Clientes | Permiso para Editar en el módulo de Clientes |
clientes.delete | Eliminar Clientes | Permiso para Eliminar en el módulo de Clientes |
GET /api/clientes→clientes.viewPOST /api/clientes→clientes.createPUT /api/clientes/{id}→clientes.editDELETE /api/clientes/{id}→clientes.delete
Módulo: Proveedores
| Permiso | Nombre para Mostrar | Descripción |
|---|---|---|
proveedores.view | Ver Proveedores | Permiso para Ver en el módulo de Proveedores |
proveedores.create | Crear Proveedores | Permiso para Crear en el módulo de Proveedores |
proveedores.edit | Editar Proveedores | Permiso para Editar en el módulo de Proveedores |
proveedores.delete | Eliminar Proveedores | Permiso para Eliminar en el módulo de Proveedores |
GET /api/proveedores→proveedores.viewPOST /api/proveedores→proveedores.createPUT /api/proveedores/{id}→proveedores.editDELETE /api/proveedores/{id}→proveedores.delete
Módulo: Compras
| Permiso | Nombre para Mostrar | Descripción |
|---|---|---|
compras.view | Ver Compras | Permiso para Ver en el módulo de Compras |
compras.create | Crear Compras | Permiso para Crear en el módulo de Compras |
compras.edit | Editar Compras | Permiso para Editar en el módulo de Compras |
compras.delete | Eliminar Compras | Permiso para Eliminar en el módulo de Compras |
GET /api/compras→compras.viewPOST /api/compras→compras.createPUT /api/compras/{id}→compras.editDELETE /api/compras/{id}→compras.deletePOST /api/compras/{id}/anular→compras.delete
Módulo: Cotizaciones
| Permiso | Nombre para Mostrar | Descripción |
|---|---|---|
cotizaciones.view | Ver Cotizaciones | Permiso para Ver en el módulo de Cotizaciones |
cotizaciones.create | Crear Cotizaciones | Permiso para Crear en el módulo de Cotizaciones |
cotizaciones.edit | Editar Cotizaciones | Permiso para Editar en el módulo de Cotizaciones |
cotizaciones.delete | Eliminar Cotizaciones | Permiso para Eliminar en el módulo de Cotizaciones |
GET /api/cotizaciones→cotizaciones.viewPOST /api/cotizaciones→cotizaciones.createPUT /api/cotizaciones/{id}→cotizaciones.editDELETE /api/cotizaciones/{id}→cotizaciones.deletePOST /api/cotizaciones/{id}/estado→cotizaciones.edit
Módulo: Empresas
| Permiso | Nombre para Mostrar | Descripción |
|---|---|---|
empresas.view | Ver Empresas | Permiso para Ver en el módulo de Empresas |
empresas.create | Crear Empresas | Permiso para Crear en el módulo de Empresas |
empresas.edit | Editar Empresas | Permiso para Editar en el módulo de Empresas |
empresas.delete | Eliminar Empresas | Permiso para Eliminar en el módulo de Empresas |
Módulo: Usuarios
| Permiso | Nombre para Mostrar | Descripción |
|---|---|---|
usuarios.view | Ver Usuarios | Permiso para Ver en el módulo de Usuarios |
usuarios.create | Crear Usuarios | Permiso para Crear en el módulo de Usuarios |
usuarios.edit | Editar Usuarios | Permiso para Editar en el módulo de Usuarios |
usuarios.delete | Eliminar Usuarios | Permiso para Eliminar en el módulo de Usuarios |
Módulo: Reportes
| Permiso | Nombre para Mostrar | Descripción |
|---|---|---|
reportes.view | Ver Reportes | Permiso para Ver en el módulo de Reportes |
reportes.create | Crear Reportes | Permiso para Crear en el módulo de Reportes |
reportes.edit | Editar Reportes | Permiso para Editar en el módulo de Reportes |
reportes.delete | Eliminar Reportes | Permiso para Eliminar en el módulo de Reportes |
Middleware CheckPermission
Ubicación:app/Http/Middleware/CheckPermission.php
Registro: bootstrap/app.php:24 como 'permission'
Funcionamiento
Uso en Rutas
Códigos de Respuesta
- 401 Unauthorized: Usuario no autenticado
- 403 Forbidden: Usuario autenticado pero sin el permiso necesario
- 200 OK: Usuario tiene el permiso, la solicitud continúa
Gestión de Permisos
Asignar Permiso a Rol
Asignar Múltiples Permisos
Remover Permiso de Rol
Verificar si Rol Tiene Permiso
Obtener Todos los Permisos de un Rol
Obtener Roles que Tienen un Permiso
Creación de Permisos
Los permisos se crean automáticamente mediante la migración: Archivo:database/migrations/2026_02_24_023530_create_permissions_and_role_permission_tables.php:58-97
Agregar Nuevos Permisos
Para agregar permisos a un nuevo módulo:Verificación en Frontend
Obtener Permisos al Login
Al hacer login, el sistema retorna todos los permisos del usuario:Verificar Permisos en React
Store de Permisos con Zustand
Mejores Prácticas
1. Verificación en Backend
Siempre verifique permisos en el backend, incluso si ya los verificó en frontend:2. Permisos Compuestos
Para operaciones que requieren múltiples permisos:3. Permisos Alternativos
Para operaciones que aceptan permisos alternativos:4. Mensajes Descriptivos
Use mensajes de error claros:5. Logging de Intentos Denegados
Registre intentos de acceso no autorizado para auditoría:Troubleshooting
Permiso no funciona después de asignarlo
Causa: Cache de relaciones o sesión antigua. Solución:- Refrescar la relación:
$rol->load('permissions') - Hacer logout y login nuevamente
- Verificar en base de datos:
SELECT * FROM role_permission WHERE rol_id = X
Admin todavía pasa por verificación de permisos
Causa: El bypass no está antes de la verificación. Solución: Verificar que el check derol_id == 1 esté antes de hasPermission().
403 en todas las rutas
Causa: Usuario sin rol o rol sin permisos. Solución:- Verificar que el usuario tiene
rol_idasignado - Verificar que el rol existe:
SELECT * FROM roles WHERE rol_id = X - Verificar que el rol tiene permisos:
SELECT * FROM role_permission WHERE rol_id = X
Permisos no se retornan en login
Causa: Relación no cargada correctamente. Solución: Verificar implementación enAuthController.php:68-76.
Extensiones Futuras
Permisos a Nivel de Registro
Para restringir acceso a registros específicos:Permisos Temporales
Agregar campos de fecha arole_permission:
Permisos de Solo Lectura
Agregar camporead_only a role_permission para permitir ver pero no editar ciertos datos.