# 01 — Visión General del Proyecto

> Documento derivado del análisis del código fuente en `/home/heimar/Repositorios/kuorum` (rama `main`).
> Todo lo que no pudo confirmarse en el código se marca como `[NO DETERMINADO EN EL CÓDIGO]`.

---

## 1. Identidad del sistema

| Dato | Valor | Origen en el código |
|---|---|---|
| Nombre comercial | **Kuorum** (también aparece como "HR Kuorum") | `app/config/Config.php` → `$appName`, `$appId`, `$nombre_institucion`; `.env.example` → `APP_NAME` |
| Propietario / autor | Klee Software (`kleesoftware.com`) | `composer.json` → `description`, `homepage` |
| Licencia declarada | BSD-3-Clause | `composer.json` |
| Tipo | Aplicación web monolítica de gestión humana (HRIS / HCM) | Estructura completa de `app/` |
| Framework | **Framework propietario "Klee"** (MVC legado, sin dependencias de framework externo) | `core/` |
| Versión declarada en runtime | `VERSION = '3.0'`, `FECHA_VERSION = '2020-05'` | `core/AutoLoad.php` (constantes) |
| Idioma de la interfaz | Español (Colombia) | `setlocale(LC_ALL, "es_CO.utf8")`, `date_default_timezone_set('America/Bogota')` en `core/AutoLoad.php` |

> ⚠️ Las constantes `VERSION`/`FECHA_VERSION` de `core/AutoLoad.php` están desactualizadas respecto al historial de commits (2026). Son un residuo del framework base, no la versión del producto.

---

## 2. Propósito y problema que resuelve

Kuorum es una **plataforma integral de gestión del talento humano** para empresas colombianas. Cubre el ciclo de vida completo del colaborador, desde la vacante hasta el desarrollo de carrera, en una sola base de datos y una sola aplicación.

Problemas concretos que resuelve, verificables en el código:

1. **Dispersión de información de personal.** Centraliza la ficha del colaborador (`colaboradores`) y la vincula con 40+ tablas de dominio: asistencia, nómina, vacaciones, beneficios, capacitación, evaluaciones, tickets, carrera.
2. **Procesos de RR. HH. en hojas de cálculo.** Implementa flujos de aprobación con estados persistidos y bitácora para vacaciones, adelantos de nómina, beneficios, ausencias, metas, reconocimientos y tickets.
3. **Falta de autoservicio del empleado.** Expone un **Portal del Colaborador** (layout `metronic_public`) donde el empleado consulta y gestiona sus propios datos sin pasar por RR. HH.
4. **Evaluación de desempeño manual.** Motor de Evaluación 360 con pesos configurables por periodo, consolidación automática y cálculo de Mapa de Talento 9-Box.
5. **Canal ético inexistente o no anónimo.** Módulo de Línea de Ética con radicación **anónima** (código + PIN hasheado con `password_hash`), sin necesidad de sesión.
6. **Cálculo de nómina fuera del sistema.** Motor de liquidación parametrizable por conceptos, fórmulas y novedades.

---

## 3. Tipos de usuario

Los roles viven en la tabla `roles`. En la base de datos actual existen tres:

| Id | Nombre | Código | Inicio | Grupo | Descripción |
|---|---|---|---|---|---|
| 1 | Administrador | `ADM` | `home` | `core` | Administrador del sistema |
| 2 | Analista | `ANA` | `home` | `rrhh` | Analista de RRHH |
| 5 | Colaborador | `COL` | `public` | `public` | Colaborador del portal público |

Además, el sistema distingue **dos identidades de autenticación completamente separadas** (ver `09_AUTHENTICATION_AUTHORIZATION.md`):

| Identidad | Tabla | Punto de entrada | Layout | Sesión |
|---|---|---|---|---|
| **Usuario de backoffice** | `usuarios` | `?c=login&a=admin` → `LoginController::validateAction()` | `metronic` | `$_SESSION[APP_ID]['User']` + `['UserType']` |
| **Colaborador (portal)** | `colaboradores` | `?c=public&a=index` → `PublicController::validateAction()` | `metronic_public` | Igual, más la marca `['ColaboradorPublic'] = true` |

Un tercer "modo" es el **Modo Demo** (`DemoController`), que crea una sesión suplantando a un colaborador real y relaja la autorización; requiere `DEMO_MODE_ENABLED=true` en `.env`.

Rol funcional adicional, no persistido como rol: **Líder de equipo**. Se determina por la columna `colaboradores.LiderEquipo = 1` (`ColaboradoresModel::esLiderEquipo()`) y habilita el módulo "Mi Equipo" y "Planes del Equipo" en el portal.

---

## 4. Funcionalidades principales

Agrupadas como aparecen en el menú (`app/config/Menu.php`):

### Talento
- **Atracción de Talento** — Reclutamiento y selección con vacantes, candidatos, postulaciones, pipeline configurable (kanban), entrevistas, ofertas, contratos y scoring automático de candidatos.
- **Desempeño y Desarrollo** — Metas (OKR-like con pesos que deben sumar 100 %), Planes de Desarrollo, Capacitación (LMS con lecciones, quiz y certificados), Evaluación 360, Competencias, Preguntas de evaluación, Mapa de Talento 9-Box.
- **Carrera y Talento** — Planes de Carrera (rutas y etapas por cargo), Altos Potenciales (HiPo), Sucesión (puestos clave, planes y candidatos), Reconocimientos.

### Tiempo y Compensación
- **Vacaciones** — Solicitudes con validación de cruces, saldos por año y política, y festivos colombianos.
- **Nómina** — Periodos, conceptos parametrizables, novedades, liquidación con motor de fórmulas, comprobante y exportación CSV.
- **Adelanto de Nómina** — Solicitudes con política de elegibilidad (antigüedad, tope por salario, cupos mensuales), desembolsos y plan de cuotas.
- **Control de Asistencia** — Marcación de entrada/salida, turnos, tolerancias, horas extra, ausencias y reporte mensual.

### Beneficios
- **Gestión de Beneficios** — Catálogo con reglas de elegibilidad, cupos y presupuesto; solicitudes con flujo de aprobación; asignaciones directas o masivas.

### Soporte al Empleado
- **Servicio al Colaborador** — Mesa de ayuda con categorías/subcategorías, prioridades, SLA por prioridad, comentarios, historial y encuesta de satisfacción; Centro de Ayuda (base de conocimiento).
- **Línea de Ética** — Canal anónimo de denuncias con seguimiento por código + PIN, tipificación, prioridad, bitácora y notas internas.
- **Comunicación Interna** — Noticias con audiencias, murales digitales, notificaciones y mensajería interna 1-a-1.

### Configuración
General, Roles, Permisos, Usuarios, Alertas, Alertas por correo, Periodos, Sedes, Tipos de contrato, Cargos, Dependencias (áreas), Categorías de metas, Escalas de evaluación, IPs autorizadas.

### Portal del Colaborador
Inicio, Mi Perfil, Mis Metas, Mi Evaluación 360, Mis Planes de Desarrollo, Mi Plan de Carrera, Mi Desempeño, Mi Equipo (solo líderes), Mi Asistencia, Mis Vacaciones, Mis Solicitudes de Beneficios, Mis Recibos de Nómina, Mis Tickets, Centro de Ayuda, Mis Cursos.

---

## 5. Funcionalidades secundarias / transversales

| Funcionalidad | Implementación |
|---|---|
| **Asistente IA conversacional** | `AsistenteIAController` + `services/asistente_ia/*` + `services/llm/OllamaProvider.php`. Traduce preguntas en lenguaje natural a SQL de solo lectura contra la BD de la aplicación, mediante un modelo Ollama local. |
| **Búsqueda rápida (quick-search)** | `ApiController::quickSearchAction()` + `QuickSearchModel` + `public/assets/js/quick-search.js`. Catálogo de acciones en `app/config/QuickActionsConfig.php`, filtrado por permisos. |
| **Gestión de documentos** | `ElFinderController::conectorAction()` monta el conector de elFinder sobre `files/`. |
| **Auditoría** | `log_acceso`, `log_urls`, `log_modules` (diff old/new en JSON) y `bitacora_auditoria`. Activables por `LOG_ACCESS`, `LOG_ACTIONS`, `LOG_MODULES`. |
| **Envío de correo programado** | `AlertasEmailController::sendCronAction()` y `sendCronSolicitudAdminAction()`, protegidos por `CRON_TOKEN`. |
| **Modo Demo** | `DemoController`: siembra datos, crea sesión de demostración y restringe rutas/escrituras. |
| **Sincronización académica (legado)** | `SincronizacionController` (1 255 líneas) — importaciones de estudiantes/docentes/materias heredadas de otro producto. Ver `18_KNOWN_ISSUES.md`. |

---

## 6. Tecnologías

### Backend
| Componente | Versión / detalle | Origen |
|---|---|---|
| PHP | 8.5.4 en el entorno actual; el código usa sintaxis compatible con PHP 5.x/7.x (`array()`, sin tipado estricto generalizado) | `php -v`; estilo del código |
| Framework | Propietario, sin dependencias de framework | `core/` |
| Acceso a datos | PDO con subclases propias: `MysqlPDO`, `OraclePDO`, `LdapPDO`, todas implementando `KleePDO` | `core/db/` |
| Motor de BD activo | MySQL / MariaDB (`utf8mb4`, `utf8mb4_0900_ai_ci`) | `.env`, `mysqldump` |
| Servidor web | Apache (uso de `.htaccess`, `mod_authz_core`) | `.htaccess`, `public/.htaccess` |

### Dependencias Composer (`composer.json`)
| Paquete | Versión | Uso real en el código |
|---|---|---|
| `symfony/http-foundation` | ^5.4 | **Declarada pero sin uso detectado** en `app/`, `core/` ni `services/` |
| `phpmailer/phpmailer` | ^6.8 | `AlertasEmailController`, `PlanesCarreraController` |
| `sgraaf/chatgpt-php` | ^0.1.0 | Referenciada junto a `OPENAI_API_KEY` desde `SincronizacionController` |
| `mpdf/mpdf` | ^8.2 | `CapacitacionPortalController` (certificados PDF) |
| `studio-42/elfinder` | ^2.1.70 | `ElFinderController` |
| `phpunit/phpunit` (dev) | ^9.6 | `tests/` |
| `fakerphp/faker` (dev) | ^1.23 | **Declarada; sin uso detectado en `tests/`** |

### Frontend
| Componente | Detalle |
|---|---|
| Plantilla | **Metronic 8.0.23 – Demo 1** (`public/metronic_html_v8.0.23_demo1/`) |
| CSS base | `plugins.bundle.css`, `style.bundle.css`, `datatables.bundle.css` + `public/assets/kuorum-metronic-demo1.css` |
| JS base | `plugins.bundle.js`, `scripts.bundle.js`, `datatables.bundle.js` (incluyen jQuery, Bootstrap 5, Select2, KTApp) |
| Tablas | DataTables en modo **server-side**, generado desde PHP por `core/ListaAjax.php` |
| Iconos | Bootstrap Icons (`bi bi-*`) |
| Tipografía | Poppins vía Google Fonts |
| Gráficas | ApexCharts (incluido en el bundle de Metronic) |
| Build tooling | **Ninguno.** No hay `package.json`, ni bundler, ni transpilación. Los assets son estáticos. |

### Sin dependencias de
No hay Composer autoload PSR-4 para el código propio (se usa un classmap manual), ni ORM, ni sistema de plantillas (las vistas son PHP plano), ni router declarativo, ni contenedor de inyección de dependencias, ni sistema de colas, ni Redis/Memcached (la caché es en ficheros).

---

## 7. Estado actual del proyecto

**En desarrollo activo, con deuda técnica reconocida y una auditoría de seguridad en curso.**

Evidencia:

- El historial reciente de commits (`fix: validar entradas dinámicas de ajax`, `fix: proteger mutaciones heredadas`, `feat: endurecer aplicación y estandarizar datos demo`) muestra un endurecimiento de seguridad en curso.
- El código contiene comentarios que citan hallazgos de una auditoría formal: **HR-007, HR-008, HR-010, HR-014, HR-025, HR-026** (buscar `Fase 0 auditoría`). El documento de auditoría en sí **no está en el repositorio** → `[NO DETERMINADO EN EL CÓDIGO]`.
- Existen módulos legados sin uso claro en el dominio de RR. HH.: `SincronizacionController` (académico), `TestController`, vistas `_test/`, `app/views/perfil_cargo/` sin controlador asociado.
- Coexisten **dos nomenclaturas de modelos de reclutamiento** (inglés `Recruitment*Model` y alias en español `Reclutamiento*Model`), producto de una migración incompleta.
- La base de datos tiene **36 migraciones aplicadas** de **41 ficheros** presentes. Verificar con `php bin/migrate status`.
- La cobertura de pruebas es de **13 ficheros PHPUnit** enfocados en contratos de semillas, layouts y regresiones de seguridad; **no hay pruebas de lógica de negocio de dominio**.

---

## 8. Arquitectura general en una frase

Monolito PHP MVC con enrutamiento por *query string* (`?c=Controlador&a=accion`), un `Controller` base que resuelve autorización antes de despachar, modelos anémicos con metadatos de columna auto-descriptivos (`getOptionsAttributes()`), vistas PHP planas envueltas en layouts de Metronic, y acceso a datos mediante SQL construido por concatenación de cadenas sobre PDO.

Ver `02_ARCHITECTURE.md` para el detalle.

---

## 9. Para un desarrollador que nunca ha visto el proyecto

Si vienes de Laravel, Symfony o Rails, estas son las cinco diferencias que más te van a sorprender:

1. **No hay rutas.** La URL `?c=Metas&a=list` significa: instancia `MetasController`, ejecuta `listAction()`. El "router" (`core/Router.php`) solo **construye** URLs; el despacho ocurre en `core/AutoLoad.php`.
2. **No hay ORM.** `MetasModel::getAll(['*'], $criteria)` construye SQL con concatenación. `$criteria` es un array con la forma `['WHERE' => [['name'=>'Estado','value'=>1,'operator'=>'=']], 'ORDER_BY' => ..., 'LIMIT' => ...]`.
3. **Los formularios usan nombres con espacio de nombres.** Un input se llama `MetasModel[Objetivo]`, no `objetivo`. El modelo lee `$_POST[get_class($this)][$nombreAtributo]` desde `Atributo::receiveData()`.
4. **Los permisos se resuelven en el constructor del controlador**, no en un middleware. `loadAccessControl()` declara qué acciones existen y con qué nivel (`'*'` público, `'@'` autenticado + permiso en BD); `Controller::process()` valida y despacha.
5. **Hay dos aplicaciones en una.** El backoffice (tabla `usuarios`) y el portal del colaborador (tabla `colaboradores`) comparten sesión, permisos y controladores, pero tienen login, layout y menú distintos.

**Orden sugerido de lectura del código real**, después de esta base de conocimiento:

```
public/index.php  →  core/AutoLoad.php  →  core/Controller.php  →  core/Model.php
      →  core/db/MysqlPDO.php  →  app/config/Config.php  →  app/config/Menu.php
      →  app/controllers/CompetenciasController.php   (ejemplo CRUD canónico, 130 líneas)
      →  app/models/CompetenciasModel.php + app/views/competencias/
```

---

## 10. Métricas del código (medidas, no estimadas)

| Métrica | Valor |
|---|---|
| Controladores | 75 |
| Modelos y servicios en `app/models/` | 139 ficheros (127 modelos + 12 clases de servicio/helper) |
| Ficheros de vista PHP | 291 |
| Layouts | 8 principales + 4 familias de parciales (`menus/`, `shortcuts/`, `flashes/`, `logs/`) |
| Clases del core | 44 (`core/`) incluyendo 26 tipos de atributo |
| Servicios en `services/` | 7 ficheros (asistente IA, LLM, prompt) |
| Acciones de controlador (pares controlador×acción) | 458 |
| Nombres de acción distintos | 259 |
| Tablas base en BD | 124 (incluye `migrations` y `graficas`) |
| Vistas SQL | 62 |
| Claves foráneas declaradas | 75 |
| Migraciones (ficheros / aplicadas) | 41 / 36 |
| Semillas | 39 + 4 clases de soporte |
| Pruebas PHPUnit | 13 ficheros |

---

## Documentos relacionados
- [00_INDEX.md](00_INDEX.md) — punto de entrada
- [02_ARCHITECTURE.md](02_ARCHITECTURE.md) — cómo fluye una petición
- [04_MODULES.md](04_MODULES.md) — detalle de cada módulo
- [18_KNOWN_ISSUES.md](18_KNOWN_ISSUES.md) — problemas detectados
