# Plan de Desarrollo — Consola de Administración Apache Guacamole

> Implementación del diseño [DISEÑO_SISTEMA.md](../DISEÑO_SISTEMA.md) (Klee Labs) **adaptado a la
> arquitectura real de este framework** (guía IA: [AI_MODULE_DEVELOPMENT_GUIDE.md](AI_MODULE_DEVELOPMENT_GUIDE.md)).
>
> Apache Guacamole es **intocable**. Esta consola lo administra vía su REST API y, para reportes,
> por lectura de solo-lectura a su BD.

---

## 1. Decisiones de alcance (acordadas)

| Decisión | Resultado |
|---|---|
| **Alcance** | Solo la **consola de administración de Guacamole**. La capa organizativa/reservas (sedes, espacios, equipos, citas) **ya existe** en el sistema (Agendas/Activos/Citas con `CodigoGuacamole`) y se reutiliza. No se crean `klee_sedes/laboratorios/equipos/reservas`. |
| **Acceso/roles** | Un solo login. Se reutiliza el sistema existente de **Usuarios + Roles + Permisos**. No se crea `klee_admins`. |
| **Reportes** | Fuente a definir en Fase 3. Se deja una abstracción (`GuacReportRepository`) que sirve igual para REST `/history` o lectura RO de `guacamole_*`. |
| **Base de datos** | **MySQL/InnoDB** (no PostgreSQL). El esquema `klee_*` del diseño se reescribe si llega a necesitarse. |
| **Rutas** | Legacy `?c=<controlador>&a=<acción>` (no REST, no declarativas). |

## 2. El reto arquitectónico

Los datos del dominio Guacamole (usuarios, conexiones, grupos, sesiones) **no viven en el MySQL local**;
viven en Guacamole y se acceden por REST API. Por eso **no usan el `Model`-ORM** (que asume tabla +
`getOptionsAttributes()`). Se modelan como una **capa de servicios sobre la API**, respetando el resto
de la guía IA (rutas `?c=&a=`, `loadAccessControl()`, CSRF, `Menu::setActive()`, permisos, vistas Metronic).

| Capa | Qué es | Dónde |
|---|---|---|
| Cliente HTTP base | `GuacamoleClient`: token en sesión, `request()` genérico, re-login al expirar, log a `storage/logs/api.log` | `core/GuacamoleClient.php` |
| Modelos-servicio (no-ORM) | `Guac*Model`: `all()/find()/create()/update()/delete()/permissions()` devolviendo arrays | `app/models/Guac*Model.php` |
| Controladores | `Guac*Controller extends Controller`, acciones `listAction/createAction/...` | `app/controllers/Guac*Controller.php` |
| Listados | DataTables **client-side**: `dataListAjaxAction()` → `Response::json()`; la vista los pinta | `app/views/guac_*/` |
| Reportes | `GuacReportRepository` con abstracción dual (API ↔ BD-RO) | `app/models/GuacReportRepository.php` |
| Auth/permisos | Reutiliza `PermisosModel`/`RolesModel`; cada acción se valida sola por el framework | — (solo seeders) |

**Token de servicio:** cuenta `GUACAMOLE_USERNAME/PASSWORD` del `.env` (ya existe). Token cacheado en
sesión, re-obtenido al recibir 401/403.

## 3. Mapeo de rutas (diseño → framework)

El mapeo REST completo está en [DISEÑO_SISTEMA.md §6](../DISEÑO_SISTEMA.md). Aquí se traduce a módulos:

| Módulo (diseño) | `MODULE_NAME` | `ViewFolder` | Permiso |
|---|---|---|---|
| Usuarios Guacamole | `guacUsuarios` | `guac_usuarios` | `GuacUsuarios` |
| Grupos de usuario | `guacGruposUsuario` | `guac_grupos_usuario` | `GuacGruposUsuario` |
| Conexiones | `guacConexiones` | `guac_conexiones` | `GuacConexiones` |
| Grupos de conexión | `guacGruposConexion` | `guac_grupos_conexion` | `GuacGruposConexion` |
| Perfiles de compartición | `guacPerfiles` | `guac_perfiles` | `GuacPerfiles` |
| Sesiones activas | `guacSesiones` | `guac_sesiones` | `GuacSesiones` |
| Historial y reportes | `guacHistorial` | `guac_historial` | `GuacHistorial` |
| Esquema / Protocolos | `guacSchema` | `guac_schema` | `GuacSchema` |
| Dashboard (KPIs) | `guacDashboard` | `guac_dashboard` | `GuacDashboard` |

## 4. Fases

### Fase 0 — Fundaciones (en curso)
- `core/GuacamoleClient.php` reutilizando la lógica probada de `CitasController` (token, cURL, verify-ssl, dataSource).
- `bin/guac-smoke`: valida `login()` + `GET users` contra el Guacamole real.
- Convención de capa + manejo global de errores de API.
- Grupo de menú "Administración remota" en `Modules.php` / `Menu.php`.
- **Criterio:** listar usuarios reales de Guacamole en una tabla, logueado con el usuario actual.

### Fase 1 — Usuarios, grupos y permisos (núcleo de valor)
- `guacUsuarios`: list, create, edit, password, view, remove.
- Permisos de sistema (checkboxes) + permisos por objeto (PATCH).
- `guacGruposUsuario`: CRUD + miembros + permisos.
- **Criterio:** crear un usuario en Guacamole desde la consola y asignarle una conexión.

### Fase 2 — Conexiones
- `guacSchema`: protocolos/atributos dinámicos (con cache).
- `guacConexiones`: form dinámico por protocolo (rdp/vnc/ssh), CRUD + parámetros + historial.
- `guacGruposConexion`: árbol + CRUD. `guacPerfiles`: CRUD.
- **Criterio:** crear/editar una conexión RDP completa y verla en Guacamole.

### Fase 3 — Monitoreo y reportes
- `guacSesiones`: activas con auto-refresh + terminar sesión.
- `guacHistorial`: historial de conexiones/usuarios con filtros + export CSV (PhpSpreadsheet) / PDF.
- `guacDashboard`: KPIs + gráficos. **Aquí se decide la fuente de reportes.**
- **Criterio:** dashboard con KPIs reales + monitor de sesiones operativo.

### Fase 4 — Auditoría, seguridad y pulido
- Auditoría de la consola: reutilizar `LogAccionesModel` o `klee_auditoria` (a confirmar).
- Seeders de permisos por rol, manejo de errores endurecido, páginas 403/404/500, smoke + `bin/doctor`.

## 5. Riesgos / pendientes

1. **Fuente de reportes** (definir en Fase 3).
2. **Auditoría**: reutilizar `LogAcciones` vs `klee_auditoria`.
3. **Versión de la API** (1.5.x/1.6.x) — fijar en config y validar tras upgrades.
4. **Refactor de `CitasController`** para usar `GuacamoleClient` común: opcional/posterior, con validación.
5. Confirmar credenciales de cuenta de servicio (`guacadmin`) y `DATA_SOURCE` reales en `.env`.

## 6. Reglas de oro (heredadas del diseño)

- Nunca modificar `guacd`, la webapp ni extensiones de Guacamole.
- Toda escritura va por la **REST API**. SQL directo en `guacamole_*` solo `SELECT` (reportes).
- Nunca guardar el `authToken` de Guacamole en BD (es de sesión).
- CSRF en todo formulario POST; validar rol antes de operaciones sensibles.
