# US-MGN-001-002-002: Asignar Permisos CRUD a Roles por Modelo

**RF Asociado:** [RF-MGN-001-002](../../02-modelado/requerimientos-funcionales/mgn-001/RF-MGN-001-002-gestion-roles.md)
**Módulo:** MGN-001 - Fundamentos
**Epic:** Autenticación y Seguridad
**Prioridad:** P0 (MVP)
**Story Points:** 5
**Sprint:** Sprint 1
**Estado:** Ready for Development
**Fecha:** 2025-11-24

---

## User Story

**Como** administrador del sistema,
**Quiero** asignar permisos CRUD (create, read, update, delete) a roles por modelo del sistema,
**Para** controlar granularmente qué acciones puede realizar cada rol sobre cada entidad.

---

## Descripción Detallada

Esta user story implementa la asignación granular de permisos a roles. El sistema debe:
1. Listar todos los modelos disponibles (sale.order, account.invoice, etc.)
2. Permitir seleccionar un rol y un modelo
3. Permitir marcar/desmarcar permisos individuales: create, read, update, delete
4. Guardar permisos en auth.permissions (role_id, model_id, can_create, can_read, can_update, can_delete)
5. Aplicar cambios inmediatamente (sin logout requerido)

Los modelos se registran automáticamente en auth.models al iniciar el sistema (decorador/metadata).

---

## Criterios de Aceptación

### Escenario 1: Asignar permisos completos (CRUD)
**Dado que** existe un rol "Contador",
**Cuando** asigno permisos CRUD completos sobre modelo "account.invoice",
**Entonces** el sistema crea registro en auth.permissions con can_create=true, can_read=true, can_update=true, can_delete=true.

### Escenario 2: Asignar permisos parciales (solo lectura)
**Dado que** existe un rol "Auditor",
**Cuando** asigno solo permiso de lectura (read) sobre modelo "sale.order",
**Entonces** usuarios con rol Auditor pueden ver órdenes de venta pero no crearlas, editarlas ni eliminarlas.

### Escenario 3: Modificar permisos existentes
**Dado que** un rol "Vendedor" tiene permisos read/create sobre "sale.order",
**Cuando** agrego permiso update,
**Entonces** el sistema actualiza el registro de auth.permissions y los vendedores pueden ahora editar órdenes.

### Escenario 4: Revocar todos los permisos de un modelo
**Dado que** un rol tiene permisos sobre "account.payment",
**Cuando** desmarco todos los checkboxes de permisos,
**Entonces** el sistema elimina el registro de auth.permissions para ese rol+modelo.

### Escenario 5: Listar permisos actuales de un rol
**Dado que** selecciono un rol "Contador",
**Cuando** veo la matriz de permisos,
**Entonces** veo todos los modelos del sistema con checkboxes indicando qué permisos tiene (marcados/desmarcados).

### Escenario 6: Herencia de permisos visualizada
**Dado que** rol "Vendedor Senior" hereda de rol "Vendedor",
**Cuando** veo la matriz de permisos,
**Entonces** veo permisos heredados en gris (read-only) y permisos propios editables.

---

## Reglas de Negocio

- **RN-1:** Un rol puede tener 0 o más permisos sobre múltiples modelos.
- **RN-2:** Permisos son granulares: cada CRUD (create, read, update, delete) es independiente.
- **RN-3:** Permisos heredados del rol padre no pueden editarse en el hijo (solo agregar, no quitar).
- **RN-4:** Rol Administrator tiene is_admin=true y bypass de validación de permisos.
- **RN-5:** Cambios de permisos se aplican inmediatamente sin logout.
- **RN-6:** Modelos se registran automáticamente en auth.models al inicio del sistema.
- **RN-7:** No se puede asignar permisos sobre modelos inexistentes.

---

## Tareas Técnicas (Checklist de Implementación)

### Backend
- [ ] Crear endpoint: `POST /api/v1/auth/roles/:roleId/permissions` - Asignar permisos
- [ ] Crear endpoint: `GET /api/v1/auth/roles/:roleId/permissions` - Listar permisos del rol
- [ ] Crear endpoint: `PATCH /api/v1/auth/roles/:roleId/permissions/:modelId` - Actualizar permisos
- [ ] Crear endpoint: `DELETE /api/v1/auth/roles/:roleId/permissions/:modelId` - Revocar permisos
- [ ] Crear endpoint: `GET /api/v1/auth/models` - Listar modelos disponibles
- [ ] Implementar método: `PermissionsService.assignPermissions(roleId, modelId, permissions)`
- [ ] Implementar método: `PermissionsService.getRolePermissions(roleId)` con herencia
- [ ] Implementar método: `PermissionsService.updatePermissions(roleId, modelId, permissions)`
- [ ] Implementar método: `ModelsService.registerModel(modelName, description)` (decorador)
- [ ] Crear DTO: `AssignPermissionsDto` con validaciones
- [ ] Crear DTO: `PermissionsMatrixDto` para respuesta con matriz completa
- [ ] Implementar caché de permisos en Redis (invalidar al cambiar)
- [ ] Agregar unit tests (10 test cases)
- [ ] Agregar integration tests (8 test cases)
- [ ] Documentar endpoints en Swagger
- [ ] Seed data: registrar modelos del sistema en auth.models

### Frontend
- [ ] Crear página: `RolePermissionsPage.tsx` con matriz de permisos
- [ ] Crear componente: `PermissionsMatrix.tsx` (tabla modelo x CRUD)
- [ ] Crear componente: `ModelSelector.tsx` (dropdown de modelos)
- [ ] Implementar checkboxes interactivos para CRUD
- [ ] Mostrar permisos heredados en gris (disabled)
- [ ] Crear API client: `permissionsApi.assign/get/update/revoke`
- [ ] Implementar búsqueda/filtrado de modelos por nombre/módulo
- [ ] Agregar feedback visual al guardar (toast notification)
- [ ] Implementar "bulk actions": asignar mismo permiso a múltiples modelos
- [ ] Agregar component tests (6 test cases)
- [ ] Agregar e2e test: "should assign and revoke permissions"

### Database
- [ ] Verificar tabla: `auth.permissions` (role_id, model_id, can_create, can_read, can_update, can_delete)
- [ ] Verificar tabla: `auth.models` (name, description, module, category)
- [ ] Crear índice: `idx_permissions_role_model` (UNIQUE on role_id + model_id)
- [ ] Crear índice: `idx_models_name` (UNIQUE)
- [ ] Validar foreign keys: role_id → auth.roles, model_id → auth.models
- [ ] Crear seed data: registrar modelos del sistema (sale.order, account.invoice, etc.)

---

## Mockups / Wireframes

**Página de Permisos de Rol:**
- Header: "Permisos del Rol: [Nombre Rol]"
- Selector: "Seleccione un rol" (dropdown)
- Filtros: búsqueda de modelos, agrupar por módulo (Sales, Accounting, Inventory)
- Matriz de permisos (tabla):
  - Columnas: Modelo | Create | Read | Update | Delete
  - Filas: un row por modelo (ej: sale.order, account.invoice)
  - Checkboxes interactivos (disabled si es permiso heredado)
  - Icono de info: tooltip explicando qué hace cada modelo
- Permisos heredados: texto "(Heredado de [Rol Padre])" en gris
- Botón "Guardar Cambios" (sticky al hacer scroll)
- Botón "Restablecer" (descartar cambios)

**Estados:**
- **Loading:** Skeleton de tabla con shimmer effect
- **Success:** Toast "Permisos actualizados correctamente"
- **Error:** Alert rojo con mensaje de error

---

## Casos de Prueba (Test Scenarios)

### Pruebas Funcionales
1. **TC-001: Asignar permisos completos**
   - **Input:** roleId=Contador, modelId=account.invoice, CRUD all true
   - **Expected:** Registro creado en permissions

2. **TC-002: Asignar permisos parciales**
   - **Input:** roleId=Auditor, modelId=sale.order, solo read=true
   - **Expected:** can_read=true, resto false

3. **TC-003: Actualizar permisos**
   - **Input:** agregar update=true a permiso existente
   - **Expected:** Registro actualizado

4. **TC-004: Revocar permisos**
   - **Input:** desmarcar todos los checkboxes
   - **Expected:** Registro eliminado de permissions

5. **TC-005: Herencia de permisos**
   - **Input:** Rol hijo con parent_role_id
   - **Expected:** getRolePermissions retorna permisos propios + heredados

6. **TC-006: Modelo inexistente**
   - **Input:** modelId=99999 (no existe)
   - **Expected:** Error 404 "Model not found"

7. **TC-007: Permisos de Administrator**
   - **Input:** roleId=Administrator
   - **Expected:** Bypass (no necesita permisos explícitos)

8. **TC-008: Caché de permisos**
   - **Input:** actualizar permisos de rol
   - **Expected:** Caché invalidado, próxima request trae permisos actualizados

### Pruebas No Funcionales
1. **Performance:**
   - Lista de 50 modelos x 10 roles en < 300ms
   - Validación de permisos en middleware < 10ms (usando caché)
2. **Usabilidad:**
   - Checkboxes responden < 100ms
   - Búsqueda de modelos en tiempo real
3. **Seguridad:**
   - Solo usuarios con 'auth.permissions.manage' pueden acceder

---

## Dependencias

- **User Stories bloqueantes:**
  - US-MGN-001-002-001 (Crear y Gestionar Roles)
- **Módulos requeridos:** Sistema de modelos registrado
- **Datos maestros necesarios:** Modelos del sistema registrados en auth.models

---

## Notas de Implementación

- Implementar decorador `@RegisterModel('sale.order', 'Sales Order')` en entidades
- En startup, escanear entidades decoradas y registrar en auth.models
- Caché de permisos en Redis:
  - Key: `permissions:user:{userId}`
  - Value: JSON con permisos resueltos (incluyendo herencia)
  - TTL: 1 hora
- Invalidar caché al actualizar permisos de un rol
- Middleware de permisos:
  ```typescript
  @UseGuards(PermissionsGuard)
  @RequirePermission('sale.order.create')
  async createOrder() {}
  ```

---

## Estimación Detallada

| Tarea | Estimación |
|-------|------------|
| Backend Development | 3 horas |
| Frontend Development | 4 horas |
| Testing (Unit + Integration + E2E) | 2 horas |
| Code Review | 1 hora |
| **TOTAL** | **10 horas** |

**Equivalente:** 5 Story Points

---

## Definition of Done (DoD)

- [ ] Código backend implementado según ET-BACKEND-MGN-001-002
- [ ] Código frontend implementado según ET-FRONTEND-MGN-001-002
- [ ] Unit tests escritos y pasando (cobertura > 80%)
- [ ] Integration tests escritos y pasando
- [ ] E2E test "should assign and revoke permissions" pasando
- [ ] Code review completado y aprobado
- [ ] Documentación Swagger actualizada
- [ ] Caché de permisos implementado y testeado
- [ ] Seed data de modelos creado
- [ ] Merge a branch `develop` completado
- [ ] QA manual completado

---

## Referencias

- [RF-MGN-001-002: Gestión de Roles y Permisos](../../02-modelado/requerimientos-funcionales/mgn-001/RF-MGN-001-002-gestion-roles.md)
- [ET-BACKEND-MGN-001-002](../../02-modelado/especificaciones-tecnicas/backend/mgn-001/ET-BACKEND-MGN-001-002-gestion-roles.md)
- [ET-FRONTEND-MGN-001-002](../../02-modelado/especificaciones-tecnicas/frontend/mgn-001/ET-FRONTEND-MGN-001-002-gestion-roles.md)
- [TRACEABILITY-MGN-001.yaml](../../02-modelado/trazabilidad/TRACEABILITY-MGN-001.yaml)
- [Auth Schema DDL](../../02-modelado/database-design/schemas/auth-schema-ddl.sql)
