# 🔐 Arquitectura de Permisos del Sistema AAT

## 📋 Índice
1. [Visión General](#visión-general)
2. [Estructura de Permisos](#estructura-de-permisos)
3. [Roles del Sistema](#roles-del-sistema)
4. [Módulos y Permisos](#módulos-y-permisos)
5. [Implementación](#implementación)
6. [Uso y Mantenimiento](#uso-y-mantenimiento)

---

## 🎯 Visión General

El sistema AAT implementa un sistema de autorización robusto basado en **Spatie Laravel Permission**, siguiendo el **principio de menor privilegio** (Least Privilege Principle) y **Clean Code principles**.

### Características Clave:
- ✅ Control de acceso basado en roles (RBAC)
- ✅ Permisos granulares por acción y módulo
- ✅ Middleware de autorización en rutas
- ✅ Verificación en componentes Livewire
- ✅ Auditoría de accesos con logging

---

## 📐 Estructura de Permisos

### Nomenclatura de Permisos

Todos los permisos siguen la estructura:

```
admin.{module}.{action}
```

#### Acciones CRUD Estándar:
- `index` → Ver lista
- `show` → Ver detalle
- `create` → Crear nuevo
- `edit` → Editar existente
- `destroy` → Eliminar

#### Acciones Especiales:
Cada módulo puede tener acciones adicionales específicas, por ejemplo:
- `admin.assets.import` → Importar activos
- `admin.assets.regenerate-qr` → Regenerar código QR
- `admin.permits.approve` → Aprobar permiso
- `admin.dynamic-forms.publish` → Publicar formulario

### Ejemplos de Permisos:

```php
// Permisos de Usuarios
'admin.users.index'    // Ver lista de usuarios
'admin.users.create'   // Crear usuario
'admin.users.edit'     // Editar usuario
'admin.users.destroy'  // Eliminar usuario

// Permisos de Formularios Dinámicos
'admin.dynamic-forms.index'       // Ver lista
'admin.dynamic-forms.create'      // Crear formulario
'admin.dynamic-forms.edit'        // Editar formulario
'admin.dynamic-forms.destroy'     // Eliminar formulario
'admin.dynamic-forms.duplicate'   // Duplicar formulario
'admin.dynamic-forms.publish'     // Publicar formulario

// Permisos de Capacitaciones
'admin.training-topics.index'        // Ver temas
'admin.training-topics.create'       // Crear tema
'admin.training-topics.toggle-status' // Cambiar estado
```

---

## 👥 Roles del Sistema

### Roles Administrativos

#### 1. Super_Admin
- **Descripción:** Acceso total e irrestricto al sistema
- **Permisos:** TODOS los permisos
- **Uso:** Desarrollo, mantenimiento del sistema

#### 2. Admin
- **Descripción:** Administrador general del sistema
- **Permisos:** TODOS los permisos
- **Uso:** Administración general

### Roles por Área Funcional

#### 3. Admin_RRHH
- **Descripción:** Administrador de Recursos Humanos
- **Módulos:**
  - ✅ Empleados (employees)
  - ✅ Identificaciones de Usuario (user-identifications)
  - ✅ Hijos (offsprings)
  - ✅ Permisos de Empleados (permits)
  - ✅ Asistencia (attendance)
  - ✅ Reportes de Asistencia (attendance-reports)

#### 4. Supervisor_RRHH
- **Descripción:** Supervisor de Recursos Humanos
- **Módulos:** employees, permits, attendance
- **Acciones:** index, show, approve (solo lectura y aprobación)

#### 5. Admin_Inventario
- **Descripción:** Administrador de Inventario
- **Módulos:**
  - ✅ Activos (assets)
  - ✅ Categorías (categories)
  - ✅ Subcategorías (subcategories)
  - ✅ Productos (products)
  - ✅ Actas de Entrega (delivery-records)

#### 6. Operador_Inventario
- **Descripción:** Operador de Inventario
- **Módulos:** assets, delivery-records
- **Acciones:** index, show, create, edit (sin eliminar)

#### 7. Admin_Mantenimiento
- **Descripción:** Administrador de Mantenimiento
- **Módulos:**
  - ✅ Programas de Mantenimiento (maintenance-programs)
  - ✅ Registros de Mantenimiento (maintenance-records)
  - ✅ Programas SGI (sgi-programs)
  - ✅ Reportes de Anomalías (anomaly-reports)
  - ✅ Inspecciones Diarias (daily-inspections)

#### 8. Tecnico_Mantenimiento
- **Descripción:** Técnico de Mantenimiento
- **Módulos:** maintenance-records, anomaly-reports, daily-inspections
- **Acciones:** index, show, create, edit

#### 9. Director_HSEQ
- **Descripción:** Director de HSEQ
- **Módulos:**
  - ✅ Reportes ORAC (report-orac)
  - ✅ PQRSD (pqrsd)
  - ✅ Programas SGI (sgi-programs)
  - ✅ Reportes de Anomalías (anomaly-reports)

#### 10. Responsable_ORAC
- **Descripción:** Responsable de ORAC
- **Módulos:** report-orac

#### 11. Admin_Capacitaciones
- **Descripción:** Administrador de Capacitaciones
- **Módulos:**
  - ✅ Líneas de Capacitación (training-lines)
  - ✅ Cargos de Capacitación (training-charges)
  - ✅ Módulos de Capacitación (training-modules)
  - ✅ Niveles de Capacitación (training-levels)
  - ✅ Temas de Capacitación (training-topics)
  - ✅ Preguntas de Capacitación (training-questions)
  - ✅ Evaluaciones de Capacitación (training-evaluations)
  - ✅ Asignaciones (training-user-modules)

#### 12. Instructor
- **Descripción:** Instructor de Capacitaciones
- **Módulos:** training-topics, training-questions, training-evaluations

#### 13. Admin_Seguridad
- **Descripción:** Administrador de Seguridad
- **Módulos:**
  - ✅ Visitantes (visitors)
  - ✅ Asistencia (attendance)
  - ✅ Dispositivos de Asistencia (attendance-devices)
  - ✅ Permisos de Empleados (permits)

#### 14. Vigilante
- **Descripción:** Personal de Vigilancia
- **Módulos:** visitors
- **Acciones:** index, show, terminal

#### 15. Admin_Formularios
- **Descripción:** Administrador de Formularios Dinámicos
- **Módulos:**
  - ✅ Formularios Dinámicos (dynamic-forms)
  - ✅ Campos de Formulario (form-fields)

#### 16. Admin_Sistema
- **Descripción:** Administrador del Sistema
- **Módulos:**
  - ✅ Usuarios (users)
  - ✅ Roles (roles)
  - ✅ Permisos (permissions)

### Roles de Usuarios Finales

#### 17. Usuario_PQRSD
- **Descripción:** Usuario de PQRSD
- **Módulos:** pqrsd
- **Acciones:** index, show, create

#### 18. Empleado
- **Descripción:** Empleado Regular
- **Módulos:** permits, attendance
- **Acciones:** index, show, create

---

## 📦 Módulos y Permisos

### Módulo: Formularios Dinámicos

**Roles con Acceso:**
- Super_Admin
- Admin
- Admin_Formularios

**Permisos:**
```php
// CRUD Básico
'admin.dynamic-forms.index'
'admin.dynamic-forms.create'
'admin.dynamic-forms.show'
'admin.dynamic-forms.edit'
'admin.dynamic-forms.destroy'

// Acciones Especiales
'admin.dynamic-forms.duplicate'   // Duplicar formulario
'admin.dynamic-forms.publish'     // Publicar formulario
'admin.dynamic-forms.fields'      // Gestionar campos
'admin.dynamic-forms.settings'    // Configuración
'admin.dynamic-forms.analytics'   // Analíticas
'admin.dynamic-forms.report'      // Generar reporte
'admin.dynamic-forms.export'      // Exportar
'admin.dynamic-forms.import'      // Importar
```

**Rutas Protegidas:**
```php
Route::resource('dynamic-forms', AdminDynamicFormController::class)
    ->middleware('role_or_permission:Super_Admin|Admin|Admin_Formularios|admin.dynamic-forms.index');
```

**Componentes Livewire con Autorización:**
- `DynamicFormIndex` → Verifica `admin.dynamic-forms.index`
- `DynamicFormCreate` → Verifica `admin.dynamic-forms.create`
- `DynamicFormEdit` → Verifica `admin.dynamic-forms.edit`

---

## 🛠️ Implementación

### 1. En Rutas (`routes/admin.php`)

#### Proteger Recurso Completo:
```php
Route::resource('dynamic-forms', AdminDynamicFormController::class)
    ->middleware('role_or_permission:Super_Admin|Admin|Admin_Formularios|admin.dynamic-forms.index');
```

#### Proteger Grupo de Rutas:
```php
Route::middleware('role_or_permission:Super_Admin|Admin|Admin_Capacitaciones|admin.training-lines.index')->group(function () {
    Route::resource('training-lines', TrainingLineController::class);
    Route::resource('training-topics', TrainingTopicController::class);
    // ... más rutas
});
```

#### Proteger Ruta Individual:
```php
Route::get('/dashboard', [DashboardController::class, 'index'])
    ->name('dashboard')
    ->middleware('permission:admin.dashboard');
```

### 2. En Controladores

```php
namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;

class DynamicFormController extends Controller
{
    public function __construct()
    {
        // Aplicar middleware de permisos
        $this->middleware('permission:admin.dynamic-forms.index')->only(['index']);
        $this->middleware('permission:admin.dynamic-forms.create')->only(['create', 'store']);
        $this->middleware('permission:admin.dynamic-forms.edit')->only(['edit', 'update']);
        $this->middleware('permission:admin.dynamic-forms.destroy')->only(['destroy']);
    }
    
    public function create()
    {
        // Verificación adicional en el método
        if (!Auth::user()->can('admin.dynamic-forms.create')) {
            abort(403, 'No tienes permiso para crear formularios.');
        }
        
        return view('admin.dynamic-forms.create');
    }
}
```

### 3. En Componentes Livewire

```php
namespace App\Livewire\Admin\DynamicForms;

use Livewire\Component;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;

class DynamicFormCreate extends Component
{
    public function mount()
    {
        // Verificar autorización
        if (!Auth::user()->can('admin.dynamic-forms.create') && 
            !Auth::user()->hasAnyRole(['Super_Admin', 'Admin', 'Admin_Formularios'])) {
            abort(403, 'No tienes permiso para crear formularios dinámicos.');
        }
        
        // Logging de auditoría
        Log::info('Usuario accedió a creación de formulario', [
            'user_id' => Auth::id(),
            'user_email' => Auth::user()->email,
        ]);
    }
    
    public function render()
    {
        return view('livewire.admin.dynamic-forms.dynamic-form-create');
    }
}
```

### 4. En Vistas Blade

#### Mostrar/Ocultar Elementos según Permisos:

```blade
@can('admin.dynamic-forms.create')
    <a href="{{ route('admin.dynamic-forms.create') }}" class="btn btn-primary">
        Crear Nuevo Formulario
    </a>
@endcan

@can('admin.dynamic-forms.edit')
    <a href="{{ route('admin.dynamic-forms.edit', $form) }}" class="btn btn-secondary">
        Editar
    </a>
@endcan

@can('admin.dynamic-forms.destroy')
    <button wire:click="delete({{ $form->id }})" class="btn btn-danger">
        Eliminar
    </button>
@endcan
```

#### Verificar Roles:

```blade
@role('Super_Admin')
    <div class="admin-panel">
        <!-- Contenido solo para Super Admin -->
    </div>
@endrole

@hasanyrole('Super_Admin|Admin|Admin_Formularios')
    <a href="{{ route('admin.dynamic-forms.index') }}">
        Gestionar Formularios
    </a>
@endhasanyrole
```

---

## 📚 Uso y Mantenimiento

### Ejecutar el Seeder

Para crear/actualizar todos los roles y permisos:

```bash
php artisan db:seed --class=ComprehensiveRolePermissionSeeder
```

### Asignar Rol a Usuario

```php
use App\Models\User;

$user = User::find(1);
$user->assignRole('Admin_Formularios');
```

### Dar Permiso Directo a Usuario

```php
use Spatie\Permission\Models\Permission;

$permission = Permission::findByName('admin.dynamic-forms.create');
$user->givePermissionTo($permission);
```

### Verificar Permisos en Código

```php
use Illuminate\Support\Facades\Auth;

// Verificar permiso específico
if (Auth::user()->can('admin.dynamic-forms.create')) {
    // Puede crear formularios
}

// Verificar rol
if (Auth::user()->hasRole('Admin_Formularios')) {
    // Es administrador de formularios
}

// Verificar cualquier rol
if (Auth::user()->hasAnyRole(['Super_Admin', 'Admin', 'Admin_Formularios'])) {
    // Tiene alguno de estos roles
}

// Verificar todos los roles
if (Auth::user()->hasAllRoles(['Admin', 'Admin_Formularios'])) {
    // Tiene todos estos roles
}
```

### Agregar Nuevo Permiso

1. **Agregar en el Seeder** (`ComprehensiveRolePermissionSeeder.php`):

```php
private const SPECIAL_PERMISSIONS = [
    'dynamic-forms' => [
        'duplicate', 
        'publish', 
        // ... permisos existentes
        'archive', // ← NUEVO PERMISO
    ],
];
```

2. **Ejecutar el Seeder:**

```bash
php artisan db:seed --class=ComprehensiveRolePermissionSeeder
```

3. **Proteger la Ruta:**

```php
Route::post('dynamic-forms/{dynamicForm}/archive', [AdminDynamicFormController::class, 'archive'])
    ->name('dynamic-forms.archive')
    ->middleware('permission:admin.dynamic-forms.archive');
```

4. **Usar en Vista:**

```blade
@can('admin.dynamic-forms.archive')
    <button wire:click="archive">Archivar</button>
@endcan
```

### Auditoría y Logging

Todos los accesos a módulos críticos deben ser registrados:

```php
use Illuminate\Support\Facades\Log;

Log::info('Usuario accedió a módulo de formularios', [
    'user_id' => Auth::id(),
    'user_email' => Auth::user()->email,
    'action' => 'create',
    'module' => 'dynamic-forms',
    'ip' => request()->ip(),
    'timestamp' => now(),
]);
```

---

## 🔍 Verificación de Permisos

### Lista de Verificación para Nuevos Módulos

- [ ] Permisos CRUD creados en el seeder
- [ ] Permisos especiales agregados si es necesario
- [ ] Middleware aplicado en las rutas
- [ ] Autorización en componentes Livewire
- [ ] Directivas `@can` en las vistas
- [ ] Logging de accesos implementado
- [ ] Roles asignados correctamente
- [ ] Pruebas con usuario sin permisos
- [ ] Documentación actualizada

---

## 🚨 Seguridad

### Principios a Seguir:

1. **Menor Privilegio:** Dar solo los permisos mínimos necesarios
2. **Defensa en Profundidad:** Verificar en rutas, controladores Y vistas
3. **Fallar Seguro:** Por defecto, denegar acceso
4. **Auditoría:** Registrar todos los accesos a módulos críticos
5. **Revisión Regular:** Auditar permisos periódicamente

### Acciones Prohibidas:

❌ **NO** dar rol `Super_Admin` a usuarios regulares  
❌ **NO** crear permisos sin documentar  
❌ **NO** saltarse middlewares de autorización  
❌ **NO** confiar solo en ocultar elementos en la UI  
❌ **NO** usar permisos genéricos como `admin.*`

---

## 📞 Soporte

Para dudas o problemas con permisos:
1. Revisar esta documentación
2. Verificar logs: `storage/logs/laravel.log`
3. Consultar Seeder: `database/seeders/ComprehensiveRolePermissionSeeder.php`
4. Revisar rutas: `routes/admin.php`

---

**Última Actualización:** 2025-01-12  
**Versión:** 1.0.0  
**Mantenido por:** Equipo de Desarrollo AAT

