# SIGE

El modulo `SIGE` de AnimalCharlie. gestiona expedientes de explotacion, revision documental y portal privado para explotaciones.

## Uso operativo

- Acceso: barra lateral, panel inicial, lanzador ERP o `#sige`.
- Campos principales: nombre, cliente, explotacion, REGA, especie, produccion, sistema, UGM, grupo, region, veterinario, estado, revision prevista y datos por seccion.
- UI operativa: `Expedientes / Ficha SIGE` es una navegación enfocada sin vista `Ambas`. El índice contiene un único directorio filtrable por cliente, REGA, explotación o estado; cada fila completa abre o crea el expediente y no repite botones de portal, apertura o archivado. El antiguo historial reciente se elimina porque duplicaba los mismos registros.
- Ficha enfocada: `#sigeWorkspaceNav` separa `Datos`, `Informe` y `Documentos`. Solo una superficie participa en el layout; `#sigeOverview` resume expediente, estado, progreso y portal dentro de Datos, `#sigeReportEditor` ocupa Informe y los adjuntos con Charlie viven en Documentos.
- Creacion tecnica e informe: el menu de cliente conserva abrir/crear como acción directa y mantiene `Nuevo para cliente`, `Duplicar base` y `Editar informe` (`#sigeFocusReportBtn`) en `Opciones`. El técnico cambia de bloque desde `#sigeSectionQuickSelect`; `#sigeSectionMap` conserva los botones de todas las secciones dentro de un plegable cerrado por defecto.
- Portal y acciones secundarias: SIGE ya no mantiene usuario, contraseña ni marca propios. Publicar en el portal único, archivar con confirmación, actualizar y documentación viven en `Más`; `Guardar SIGE` es la única acción principal visible en la ficha.
- Veterinario global: el campo `Veterinario de explotación` mantiene texto libre, pero sugiere usuarios reales con `sige.write` desde `GET /api/module-user-access?module=sige&permission=sige.write&status=active` para reutilizar la capa global de usuarios sin perder colegiados o nombres historicos. Si el texto coincide con una opcion que trae `links.history`/`userHistoryUrl`, `Histórico veterinario` abre `Usuarios > Auditoria` filtrada a `sige`.
- Portal cliente: `POST /api/sige/{id}/share` exige un cliente o explotación vinculados, reutiliza la cuenta canónica de `users`, devuelve `/portal?view=customer-sige&sige={id}` y marca el expediente como `client_review` cuando estaba en borrador.
- Sesión del portal: SIGE usa el bearer global de `/portal`; `GET /api/portal/sige/{id}` y los comentarios comprueban que el expediente pertenece al `client_id` de la sesión. La sesión SIGE separada queda solo para enlaces legacy `/sige/{token}`.
- Adjuntos SIGE: `Adjuntos SIGE` permite subir PDF, DOCX, XLSX, CSV, TSV, TXT o MD al expediente activo. `Desde biblioteca` usa `AnimalCharlieAssetLibrary.mountFileInput(...)`, filtra esos formatos y entrega el recurso al mismo flujo de subida, extracción y análisis. Al terminar, Charlie procesa automaticamente los documentos, extrae datos para campos generales y secciones del informe SIGE, y el usuario decide que propuestas rellenar antes de guardar.
- Relacion con otros modulos: `Clientes > Portal` puede abrir o crear SIGE para el cliente activo con `customer_id` y `farm_id`; el menu de creacion SIGE lee clientes y explotaciones del CRM, Calendario puede vincular eventos con `sige_id`, Prado Vivo publica los SIGE asociados al cliente y Charlie puede resumir o preparar acciones relacionadas.

La UI sigue `UI.md`: directorio único, ficha a ancho completo, tres vistas mutuamente excluyentes, scroll contenido y publicación sin credenciales paralelas. `tools/verify_sige_ui.py` comprueba este recorrido en PC, Galaxy Tab A9+ e iPad Air. Si la instalación no contiene expedientes activos, crea por la API un expediente temporal sin cliente ni explotación enlazados para comprobar edición; la publicación exige después enlazarlo a un cliente real o de prueba.

## API interna

Todas las rutas privadas requieren sesion con token.

| Ruta | Acceso | Descripcion |
| --- | --- | --- |
| `GET /api/sige` | roles `admin`, `technician`, `reviewer` o permisos `sige.read` / `sige.write` | Lista expedientes, con filtro opcional `status`. |
| `POST /api/sige` | roles `admin`, `technician`, `reviewer` o permiso `sige.write` | Crea o actualiza un expediente cuando el payload incluye `id`. |
| `GET /api/sige/{id}` | roles `admin`, `technician`, `reviewer` o permisos `sige.read` / `sige.write` | Devuelve expediente con comentarios internos. |
| `PUT /api/sige/{id}` | roles `admin`, `technician`, `reviewer` o permiso `sige.write` | Actualiza el expediente indicado. |
| `DELETE /api/sige/{id}` | roles `admin`, `technician` o permiso `sige.write` | Archiva el expediente indicado. |
| `POST /api/sige/{id}/share` | roles `admin`, `technician`, `reviewer` o permiso `sige.write` | Publica o refresca el portal privado de SIGE. |
| `GET /api/sige/{id}/attachments` | roles `admin`, `technician`, `reviewer` o permisos `sige.read` / `sige.write` | Lista adjuntos vinculados al expediente. |
| `POST /api/sige/{id}/attachments` | roles `admin`, `technician`, `reviewer` o permiso `sige.write` | Sube un adjunto, lo guarda en `data/evidence/`, lo vincula a `entity_type=sige` y extrae texto si el formato lo permite. |
| `GET /api/sige/{id}/attachments/{attachmentId}` | roles `admin`, `technician`, `reviewer` o permisos `sige.read` / `sige.write` | Descarga o abre el adjunto autenticado. |
| `DELETE /api/sige/{id}/attachments/{attachmentId}` | roles `admin`, `technician`, `reviewer` o permiso `sige.write` | Borra el adjunto y su fichero. |
| `POST /api/sige/{id}/attachments/analyze` | roles `admin`, `technician`, `reviewer` o permisos `sige.read` / `sige.write` | Ejecuta Charlie sobre adjuntos con texto y devuelve sugerencias sin guardar cambios de campos. |
| `GET /api/module-user-access?module=sige&permission=sige.write&status=active` | acceso efectivo a SIGE, `audit.read` o `users.manage` | Devuelve usuarios operativos de SIGE para sugerir veterinarios o responsables sin duplicar reglas de permisos, incluyendo `options[].links.history` y `options[].userHistoryUrl`. |

El permiso `sige.write` tambien permite leer expedientes para que un perfil operativo no tenga que duplicar `sige.read`.

Los intentos fallidos del portal SIGE usan `PORTAL_LOGIN_*`, se auditan y terminan en `429 too_many_attempts` al superar el límite. Una sesión emitida para un expediente no permite comentar, reconocer secciones ni leer el portal de otro SIGE.

## Payload de expediente

Campos aceptados por el backend:

| Campo | Uso |
| --- | --- |
| `id` | Identificador opcional. Si no existe en alta, se genera `sige-...`. |
| `name` | Nombre obligatorio del expediente. |
| `customerId` / `customer_id` | Cliente CRM vinculado. Si se informa, el backend normaliza `client` con `customers.name`. |
| `farmId` / `farm_id` | Explotacion CRM vinculada. Si se informa, el backend normaliza explotacion, REGA, especie, produccion, UGM y region desde `customer_farms` cuando falten en el payload. |
| `client` | Cliente o titular. |
| `farmName` / `farm_name` | Nombre de explotacion. |
| `rega` | Codigo REGA. |
| `species` | Especie, por defecto `bovino`. |
| `productionType` / `production_type` | Tipo de produccion. |
| `systemType` / `system_type` | Sistema productivo. |
| `capacityUgm` / `capacity_ugm` | Capacidad UGM. |
| `groupName` / `group_name` | Grupo o agrupacion. |
| `region` | Provincia o region. |
| `veterinarian` | Veterinario responsable. La UI puede rellenarlo desde usuarios con `sige.write`, pero persiste texto para conservar colegiado, nombre externo o historicos; el boton `Histórico veterinario` solo se habilita si coincide con una opcion global trazable. |
| `status` | Estado SIGE: `draft`, `in_progress`, `review`, `client_review`, `approved`, `issued` o `archived`. |
| `reviewDue` / `review_due` | Proxima revision prevista. |
| `data` | Datos estructurados por seccion. |
| `portalUsername` / `portal_username` | Compatibilidad legacy para `/sige/{token}`; la UI actual no lo edita y `/portal` usa la cuenta canónica del cliente vinculado. |
| `portalPassword` / `portal_password` | Compatibilidad legacy para renovar la clave de `/sige/{token}`; no crea una segunda contraseña en el portal unificado. |
| `portalBrand` | Marca legacy de la vista `/sige/{token}`; el portal unificado usa su shell común. |

## Adjuntos y Charlie

Los adjuntos SIGE se almacenan en la tabla `evidence` con estas columnas de enlace:

| Campo | Uso |
| --- | --- |
| `entity_type` | Valor `sige` para adjuntos del modulo SIGE. |
| `entity_id` | Id del expediente SIGE. |
| `section_key` | Seccion SIGE activa al subir el archivo, si aplica. |
| `extraction_status` | `ready`, `empty`, `needs_ocr`, `unsupported` o detalle de error. |
| `extracted_text` | Texto extraido para analisis IA. |
| `analysis_json` | Ultima propuesta estructurada generada por Charlie. |

La accion Charlie `sige_fill_from_attachments` lee los adjuntos del expediente y devuelve `suggestions[]` con `target`, `field` o `sectionKey/itemKey`, `value`, `confidence`, `source` y `reason`.

La UI no aplica nada de forma directa: muestra cada propuesta con el valor actual, el valor extraido y la fuente. Tras subir documentos se lanza el analisis automaticamente; tambien puede repetirse con `Procesar documentos`. Solo los elementos seleccionados rellenan el informe al pulsar `Rellenar informe`; al aplicar propuestas de seccion, la UI abre el primer bloque afectado en `#sigeReportEditor`. Para persistir hay que pulsar `Guardar SIGE`.

## Auditoria

SIGE registra actividad normalizada en `audit_log`:

- `sige_save` al crear o guardar desde `POST /api/sige`.
- `sige_update` al actualizar desde `PUT /api/sige/{id}`.
- `sige_share` al generar o refrescar portal.
- `sige_archive` al archivar desde `DELETE /api/sige/{id}`.
- `sige_attachment_upload`, `sige_attachment_download`, `sige_attachment_delete` y `sige_attachment_analyze` para adjuntos leidos por Charlie.

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

## Consumo por otros modulos

Los modulos que necesiten leer expedientes deben pedir `sige.read` o `sige.write`. Los modulos que creen, actualicen, publiquen o archiven expedientes deben usar `sige.write` y llamar a las rutas anteriores, dejando que el backend aplique permisos, auditoria, portal y persistencia.

Para enlazar SIGE con Clientes o Prado Vivo, guardar `customer_id` y `farm_id` dentro del propio expediente SIGE. El backend conserva compatibilidad con expedientes antiguos: si esos IDs faltan, `customer_payload()` todavia intenta asociarlos por `client`, `farm_name` o `rega`, pero las nuevas altas deben enviar los IDs. Los expedientes SIGE archivados no se publican en la ficha de cliente ni en Prado Vivo.

Para enlazar SIGE desde otro modulo consumidor, guardar `sige_id` en la tabla consumidora en vez de duplicar campos del expediente.
Si un modulo necesita sugerir veterinarios, revisores o responsables de SIGE, debe consumir `GET /api/module-user-access?module=sige&permission=sige.write` y usar `options[]` como fuente de usuarios, manteniendo `sige_records.veterinarian` como texto persistido cuando sea necesario. Si quiere abrir historicos, debe reutilizar `options[].links.history` o `options[].userHistoryUrl` y acotar la lectura con `module=sige`.
