# Proyectos

El modulo `Proyectos` de AnimalCharlie. concentra trabajos operativos que pueden vincularse con clientes, empleados, centros de trabajo, calendario, acciones, facturacion y Charlie.

## Carcasa Y Navegación

La cabecera común cambia con la fase activa: `Nuevo proyecto` aparece en `Proyectos` y `Guardar proyecto` solo en `Ficha`. Actualización y documentación se agrupan en `Más`; histórico y archivado también viven allí, únicamente cuando se trabaja con una ficha. El layout `master-detail` sin vista `Ambas` entra por un índice compacto y dedica todo el ancho al formulario al seleccionar o crear un proyecto.

La lógica de esta superficie ya no vive mezclada con los listeners generales de `app.js`. `module-projects.js` monta un controlador único para guardar, listar, seleccionar, abrir el histórico del responsable y archivar. `app.js` conserva los datos compartidos y los adaptadores hacia Clientes, Calendario, Charlie y el backend, de modo que la extracción no cambia endpoints ni permisos.

## Uso operativo

- Acceso: barra lateral, panel inicial, lanzador ERP o `#proyectos`.
- Campos principales: nombre, cliente, estado, responsable, centro, fecha de inicio, fecha de fin, notas y empleados asignados.
- Estados: la UI puede trabajar con proyectos activos, planificados, pausados, cerrados o archivados segun el valor `status`.
- Asignaciones: `assignedEmployees` reemplaza la lista de `project_assignments` del proyecto al guardar.
- Integraciones: `Clientes > Portal` abre o crea proyectos para el cliente activo; Calendario y Acciones pueden seleccionar `project_id`; Facturacion usa `project_id` para imputacion; Charlie puede crear o resumir trabajos.
- Responsable global: el selector de responsable consume `GET /api/module-user-access?module=projects&permission=projects.write&status=active`, muestra usuarios reales con acceso de escritura y empleado vinculado, guarda `lead_employee_id` para mantener compatibilidad con calendario, personal y proyectos existentes, y conserva `links.history`/`userHistoryUrl` para abrir `Usuarios > Auditoria` filtrada a `projects` desde la ficha.

El índice no selecciona automáticamente el primer registro ni muestra campos de edición. Una fila abre y rellena la ficha; `Nuevo proyecto` abre una ficha vacía. Al modificar un registro, la UI usa `PUT /api/projects/{id}` y conserva el estado, las notas y las asignaciones que no forman parte del formulario compacto.

La UI sigue `UI.md`: se trabaja dentro del workspace, con listas compactas, formulario denso y sin rutas paralelas para el mismo trabajo.

## API interna

Todas las rutas privadas requieren sesion con token.

| Ruta | Acceso | Descripcion |
| --- | --- | --- |
| `GET /api/projects` | roles `admin`, `technician`, `reviewer` o permisos `projects.read` / `projects.write` | Lista proyectos. Acepta filtro `status`. |
| `POST /api/projects` | roles `admin`, `technician` o permiso `projects.write` | Crea o actualiza un proyecto cuando el payload incluye `id`. |
| `PUT /api/projects/{id}` | roles `admin`, `technician` o permiso `projects.write` | Actualiza el proyecto indicado. |
| `DELETE /api/projects/{id}` | roles `admin`, `technician` o permiso `projects.write` | Archiva el proyecto indicado con `status='archived'`. |

El permiso `projects.write` tambien permite leer proyectos para que un perfil operativo no tenga que duplicar `projects.read`.
La UI usa `GET /api/module-user-access?module=projects&permission=projects.write&status=active` para construir el selector de responsable. `options[].employeeId` es el valor que se guarda en `leadEmployeeId`; si no hay usuarios vinculados a empleados, se mantiene el fallback de `GET /api/employees` para no bloquear el alta. Cuando `options[].links.history` o `options[].userHistoryUrl` existen, la ficha habilita `Histórico responsable` y navega al historico del usuario sin crear una auditoria paralela.

`Histórico responsable` sigue siempre el valor visible del selector, incluso antes de guardar. Al elegir una persona sin usuario o sin enlace de histórico el botón se deshabilita; al elegir una persona con histórico vuelve a habilitarse y abre exactamente ese usuario, evitando conservar el responsable anterior por memoria de la ficha.

## Payload de proyecto

Campos aceptados por el backend:

| Campo | Uso |
| --- | --- |
| `id` | Identificador opcional. Si no existe en alta, se genera `proj-...`. |
| `name` | Nombre obligatorio del proyecto. |
| `client` | Nombre o referencia de cliente visible en el trabajo. |
| `status` | Estado operativo, por defecto `active`. |
| `leadEmployeeId` / `lead_employee_id` | Responsable principal. Preferentemente sale de `options[].employeeId` de `/api/module-user-access` para que el responsable sea un usuario real con acceso a Proyectos. |
| `locationId` / `location_id` | Centro de trabajo vinculado. |
| `startDate` / `start_date` | Fecha de inicio. |
| `endDate` / `end_date` | Fecha de fin. |
| `notes` | Notas internas. |
| `assignedEmployees` / `assigned` | Lista de empleados asignados; sustituye las asignaciones previas. |

## Auditoria

Proyectos registra actividad normalizada en `audit_log`:

- `project_save` al crear o guardar desde `POST /api/projects`.
- `project_update` al actualizar desde `PUT /api/projects/{id}`.
- `project_archive` al archivar desde `DELETE /api/projects/{id}`.

El modulo queda como `projects` por `entity_type`, por accion `project_*` y por `details.module` cuando otros modulos lo envien de forma explicita. Esto permite que `/api/activity?module=projects` y `GET /api/users/{username}/history?module=projects` agrupen la actividad sin reglas duplicadas en la UI.

## Consumo por otros modulos

Los modulos que necesiten leer trabajos deben pedir `projects.read` o `projects.write`. Los modulos que creen o actualicen trabajos deben enviar el payload anterior a `POST /api/projects` o `PUT /api/projects/{id}` y dejar que el backend aplique permisos, auditoria y persistencia.

Para enlazar un trabajo desde otro modulo, guardar `project_id` en la tabla del modulo consumidor en vez de duplicar campos de proyecto.
