# Calidad Lechera

`Calidad lechera` gestiona informes de visita a explotación. La visita es el contenedor principal y el CMT es uno de sus bloques opcionales, no un requisito para generar, editar, guardar, aprobar o exportar el informe. La ruta visual es `#calidad-lechera` y el módulo interno es `milk_quality`.

## Flujo de trabajo

La ruta predeterminada es una `Visita guiada`. No presenta el esquema del informe ni obliga al técnico a conocer sus bloques internos. Las seis preguntas se reparten en tres momentos estables, siempre en el mismo orden y con dos decisiones por pantalla:

- `Contexto`: explotación y tipo de visita.
- `Revisión`: áreas comprobadas y objetivo.
- `Cierre`: criterio profesional y próxima revisión.

Las preguntas mantienen el orden en el que se prepara la visita de campo:

1. `¿En qué explotación estás?`: selecciona la explotación; la fecha de hoy y el técnico autenticado se proponen automáticamente.
2. `¿Qué tipo de visita es?`: tarjetas grandes para inicial, seguimiento, incidencia, revisión periódica u otra.
3. `¿Qué has revisado?`: tarjetas táctiles para producción, salud de ubre, rendimiento, máquina, rutina y bienestar, secado y CMT.
4. `¿Por qué haces esta visita?`: una frase breve con el objetivo real.
5. `¿Qué has visto y qué recomiendas?`: nota principal del veterinario, escribible, pegable o dictable.
6. `¿Cuándo hay que volver?`: fecha de seguimiento opcional.

Las seis áreas habituales nacen activas. El veterinario desmarca únicamente lo que no comprobó. CMT nace desactivado y solo abre su captura específica cuando se marca. El anexo de fuentes y el orden técnico no aparecen como decisiones de campo.

Cada opción de explotación muestra `explotación · REGA · cliente`. Al elegirla, AnimalCharlie presenta esos tres datos como un resumen automático y carga los registros normalizados de AnimalCharlie, DataHub, CEGCOL y LIGAL sin pedir que se vuelvan a escribir. Cliente, explotación y REGA solo son editables desde `Personalizar > Secado y recomendaciones > Rellenar datos`, junto con los datos profesionales de cierre, para corregir una excepción sin convertirlos en campos principales.

La cabecera mantiene una sola acción primaria contextual. En `Contexto` y `Revisión` es `Continuar`; en `Cierre` pasa a `Generar informe`. Si el técnico marca la tarjeta `CMT` y todavía no hay lecturas, en `Cierre` cambia a `Completar CMT` y abre su editor dentro de `Personalizar`; desde allí puede importar lecturas o generar el informe con CMT pendiente. No existe un tercer paso separado.

`Contexto` muestra un progreso breve (`Paso 1 de 3`) y protege los dos datos que identifican la visita. `Continuar` no avanza mientras exista un catálogo de explotaciones y no se haya elegido una, ni mientras falte el tipo de visita. La pregunta pendiente se marca junto al propio control y recibe el foco; no se muestra un error distante ni se genera un informe anónimo por accidente. Si el usuario no tiene explotaciones accesibles, la validación no bloquea el borrador manual.

El dictado de la nota principal usa el reconocimiento de voz disponible en el navegador y persiste el texto mediante el mismo campo `summary.executiveConclusion`. Si el navegador o el permiso de micrófono no lo permiten, muestra una explicación y conserva la escritura y el pegado manual sin bloquear el informe.

Las funciones menos frecuentes permanecen disponibles en segundo plano:

- `Más opciones del informe`: contiene `Cambiar bloques y orden`; se abre cuando el técnico necesita decidir la composición o rellenar datos concretos por bloque.
- `Reabrir o recargar visita`: permite abrir una visita guardada o forzar la recarga de integraciones.
- `Personalizar`: cada uno de los ocho bloques dispone de `Rellenar datos`. El botón abre debajo de la lista un editor inline y muestra únicamente sus campos y colecciones de `milk-quality-visit/v3`.
- `CMT`: conserva texto, TXT, audio y WhatsApp, pero su captura se abre como editor del bloque dentro de `Personalizar`; también permite generar el informe con lecturas pendientes.

El navegador interno `Visita / Personalizar` permanece oculto mientras solo existe la visita guiada. Aparece al entrar deliberadamente en la personalización o al completar CMT, sin convertir los campos de cada bloque en otro asistente por pasos.

El layout exterior conserva `Entrada / Informe` y no comprime ambas fases en una vista paralela.

`Informe` mantiene tres vistas:

- `Prioridades`: composición elegida, estado de datos y, solo si procede, lecturas y hallazgos CMT. Cada bloque es accionable y abre exactamente su editor dentro de `Personalizar` para completar un pendiente.
- `Documento`: informe editable mediante el motor compartido `AnimalCharlieDocumentEditor` con perfil `clinical`.
- `Aprobación`: resumen para WhatsApp y confirmación externa. `Enviar WhatsApp` sustituye a `Guardar informe` como única acción primaria de esta fase.

## Compositor modular opcional

El catálogo inicial es ordenable y extensible:

| ID | Bloque | Predeterminado |
| --- | --- | --- |
| `production` | Calidad de producción | Sí |
| `udder_health` | Salud de ubre | Sí |
| `milking` | Rendimiento de ordeño | Sí |
| `machine` | Máquina de ordeño | Sí |
| `routine` | Rutina y bienestar | Sí |
| `dry_off` | Secado y recomendaciones | Sí |
| `cmt` | CMT por vaca | No |
| `sources` | Anexo de fuentes | No |

La configuración predeterminada incluye los seis bloques habituales y deja CMT y fuentes como opcionales. Cada fila muestra si tiene datos, permite incluirla mediante checkbox, dispone de controles para subir o bajar su posición y ofrece `Rellenar datos`. Al pulsarlo, la fila queda resaltada y se abre un único editor debajo del catálogo; cambiar de bloque reemplaza sus campos sin salir de `Personalizar`, sin ventanas y sin duplicar inputs.

El editor distribuye el modelo así:

| Bloque | Datos mostrados |
| --- | --- |
| Calidad de producción | Tanque actual, analíticas, conclusión e histórico |
| Salud de ubre | Índices, conclusión, animales revisados y animales problema |
| Rendimiento de ordeño | Horarios, duración, animales, rendimiento y conclusión |
| Máquina de ordeño | Vacío, pulsación, equipo, observaciones, conclusión y puntos |
| Rutina y bienestar | Higiene, ordeñadores, rutina, bienestar, fotografías y conclusiones |
| Secado y recomendaciones | Identidad de cierre, alcance, resumen, secado, acciones y firmas |
| CMT por vaca | Audio, TXT, WhatsApp, texto y lecturas por cuarterones |
| Anexo de fuentes | Texto manual y procedencia AnimalCharlie, DataHub, CEGCOL y LIGAL |

Las trece colecciones repetibles siguen siendo un único modelo, pero solo se renderizan dentro del bloque al que pertenecen. El orden se respeta en el documento, Markdown, PDF y `payload.sections`. Desactivar un bloque no borra los datos introducidos durante la sesión: simplemente lo excluye de la salida. `Rellenar datos` también permite revisar un bloque desactivado y el encabezado avisa de que no se incluirá hasta marcarlo.

## Datos de la visita

La interfaz diferencia tres niveles de entrada:

| Nivel | Qué ve el usuario |
| --- | --- |
| Visita guiada | Explotación, fecha y técnico propuestos, tipo mediante tarjetas, áreas revisadas, objetivo, nota principal con dictado y próxima revisión |
| Datos automáticos | Explotación, REGA, cliente, históricos, controles, animales, bacteriología y procedencia |
| Edición por sección | Identidad corregible, teléfono, interlocutor, mediciones, observaciones, conclusiones y colecciones repetibles filtradas por el bloque activo |

| Grupo | Campos |
| --- | --- |
| Identidad | Cliente, explotación, REGA, fecha, técnico, teléfono, interlocutor y colegiado |
| Encargo de visita | Tipo, motivo, objetivo y alcance real de las comprobaciones |
| Resumen técnico | Conclusión ejecutiva, fortalezas, riesgos prioritarios, limitaciones y próxima revisión |
| Calidad de producción | Tipo y código de producción, bacterias, células, punto crioscópico, grasa, proteína, urea, sólidos e inhibidores |
| Salud de ubre | Índices generales y de secado por periodo, Linear Score, días en leche y producción |
| Rendimiento de ordeño | Inicio, fin, duración, número de animales y animales por hora |
| Máquina | Vacío, pulsación, relación, equipo de medición, observaciones y conclusión técnica |
| Animales revisados | Identificador, número de explotación, clase, RCS histórico, producción, DEL, partos, reproducción y aislamientos LIGAL |
| Animales problema | Veredicto, prioridad, observaciones, reproducción, evolución y bacteriología individual |
| Higiene | Valoración, checklist, observaciones, fotografías y conclusión del técnico |
| Ordeñadores | Nombre, valoración, checklist completo y observaciones |
| Rutina y bienestar | Preparación, ambiente, manejo, hallazgos, animales o lotes afectados, fotografías y conclusiones separadas |
| Máquina | Parámetros y hasta 32 puntos de pulsación con estado y observación |
| Secado | Animales, RCS, fechas, tratamiento, estado, seguimiento y conclusión técnica |
| Recomendaciones | Prioridad, acción, detalle, responsable, fecha y estado |
| Firmas | Rol, nombre, colegiado, fecha y estado de conformidad |
| CMT opcional | Animal, DI, DD, TI, TD, contexto individual y observaciones |
| Procedencia | Fuente, fecha, tipo de entidad y estado para AnimalCharlie, DataHub, CEGCOL, LIGAL o entrada manual |

Los campos pueden completarse manualmente o alimentarse desde LIGAL, CEGCOL, DataHub, Explotaciones, reproductivo, tratamientos o máquina de ordeño. Cada bloque muestra únicamente sus colecciones repetibles: cada fila se puede añadir, modificar o eliminar y conserva su origen. Un dato vacío no bloquea el borrador y queda visible como pendiente en el bloque seleccionado.

La captura diferencia tres niveles que no deben mezclarse:

- `Dato automático`: resultados, históricos, animales y procedencia cargados desde AnimalCharlie, DataHub, CEGCOL o LIGAL.
- `Observación de campo`: medición, comprobación o hecho registrado por el técnico durante la visita, sin interpretación añadida.
- `Criterio profesional`: conclusión ejecutiva y valoración específica de tanque, salud de ubre, rendimiento, máquina, higiene, rutina, bienestar y secado.

Las conclusiones manuales tienen prioridad durante una recarga de la misma explotación. `Cargar datos de la explotación` puede actualizar resultados integrados, pero no sustituye el motivo, objetivo, alcance, resumen ni las valoraciones redactadas por el técnico. Cambiar expresamente a otra explotación inicia una visita nueva y limpia el contexto anterior.

Cuando existe contenido redactado por el técnico, `visitData.provenance` incorpora una entrada `manual` denominada `Valoración técnica y observaciones`, diferenciada de las fuentes automáticas.

Los huecos se conservan como huecos: al guardar o reabrir no se crea una fecha, una muestra ni un periodo de salud de ubre si no existe un valor real. La fecha de hoy solo se propone al iniciar una visita nueva y el usuario puede vaciarla. Los valores importados tampoco se sustituyen por cadenas vacías procedentes del formulario.

`GET /api/milk-quality/context` acepta `farmId`, `rega` o `farm`. Sin filtros devuelve el catálogo de explotaciones accesibles y visitas guardadas; con una explotación devuelve `visitData` normalizado. La UI usa siempre `farmId` al seleccionar una opción, invalida respuestas pendientes si el usuario cambia rápidamente de explotación y borra el contexto estructurado anterior antes de cargar el nuevo. La precarga usa:

- AnimalCharlie para identidad y ficha de explotación;
- LIGAL para histórico de tanque, bacteriología, RCS individual, microorganismos y antibiograma enlazado;
- CEGCOL para controles, partos, inseminaciones, lactación, clasificación individual e índices de salud de ubre;
- DataHub como almacén materializado y trazable de esos registros.

No se convierte el HTML editado en fuente primaria. El documento es una representación de `visitData`; los valores que solo existan en la visita se guardan como filas manuales estructuradas.

## Persistencia y compatibilidad

Los informes nuevos se guardan en `/api/reports` con:

```json
{
  "schema": "milk-quality-visit/v3",
  "module": "milk_quality",
  "workflow": { "visitStage": "close" },
  "sections": [
    { "id": "production", "enabled": true },
    { "id": "cmt", "enabled": false }
  ],
  "meta": {},
  "rows": [],
  "visitData": {
    "identity": {},
    "visit": { "type": "", "reason": "", "objective": "", "scope": "" },
    "summary": { "executiveConclusion": "", "strengths": "", "risks": "", "limitations": "", "nextReview": "" },
    "tank": { "current": {}, "history": [], "conclusion": "" },
    "udderHealth": { "periods": [], "rules": {}, "threshold": {}, "conclusion": "" },
    "milking": { "conclusion": "" },
    "reviewedAnimals": [],
    "problemAnimals": [],
    "cmt": [],
    "hygiene": { "rating": "", "notes": "", "conclusion": "", "checks": [], "photos": [] },
    "routine": { "notes": "", "conclusion": "" },
    "milkers": [],
    "machine": { "notes": "", "conclusion": "", "points": [] },
    "welfare": { "notes": "", "conclusion": "", "findings": [], "photos": [] },
    "dryOff": { "notes": "", "conclusion": "", "animals": [] },
    "recommendations": [],
    "signatures": [],
    "provenance": []
  },
  "sourceText": "",
  "stats": {
    "sections": 1,
    "cmtIncluded": false
  }
}
```

`sections` conserva orden y activación. `workflow.visitStage` conserva el momento activo (`context`, `review` o `close`) y se restaura al reabrir; los informes históricos sin ese dato se abren en `Cierre`. `visitData` es el modelo canónico. `rows` permanece como compatibilidad CMT y refleja `visitData.cmt`; ambos pueden estar vacíos. El nombre de versión es `Informe de visita`, `formData.certificationType` es `milk_quality_visit` y el fichero usa el sufijo `-visita.md`.

El Markdown guardado no es un resumen reducido: refleja las colecciones `v3` activas, incluidos históricos de tanque, índices, animales revisados y problema, puntos de pulsación, higiene, ordeñadores, bienestar, secado, plan de acción, firmas y procedencia. Las celdas conservan saltos de línea y caracteres de tabla de forma segura.

Los informes históricos `milk-quality-visit/v2` y `milk-quality-cmt/v1` siguen siendo legibles. La UI los normaliza a `v3`: conserva metadatos, bloques, CMT, HTML y texto fuente, y crea las colecciones equivalentes sin inventar información. Las visitas `v3` se pueden reabrir con todos sus datos estructurados y continuar editando.

## Documento y PDF

La portada siempre contiene explotación, fecha, técnico, colegiado, interlocutor, REGA y número de bloques. Cuando existen, añade tipo, motivo, objetivo y alcance de la visita. Un resumen técnico independiente presenta conclusión ejecutiva, fortalezas, riesgos, limitaciones y próxima revisión. Después se generan únicamente los bloques activos y en el orden elegido. El cierre y las firmas permanecen al final.

El informe usa la plantilla técnica Herba de las visitas veterinarias:

- cabecera compacta con marca Herba, explotación, REGA y fecha;
- pie confidencial con trazabilidad de AnimalCharlie;
- secciones verdes numeradas según el orden elegido en `Contenido`;
- tablas densas con tipografía monoespaciada para resultados, referencias y animales;
- cuadrículas de parámetros para portada, índices y rendimiento;
- gráficas técnicas generadas únicamente cuando existen datos estructurados;
- fichas compactas de animales problema con contexto, observación y CMT;
- checklists derivados de notas de campo con estados `OK`, `REVISAR`, `CRÍTICO` o `NOTA`;
- slots fotográficos editables para rutina, higiene, bienestar e instalaciones;
- revisión estructurada de hasta 32 puntos de pulsación; como compatibilidad, las notas antiguas aún pueden identificar puntos concretos;
- plan de acción numerado y firmas identificadas.
- una valoración del técnico explícita en cada bloque, separada de tablas, integraciones y observaciones de campo;
- un cierre profesional que reutiliza la conclusión ejecutiva y la fecha de seguimiento, sin generar diagnósticos ni tratamientos por defecto.

No se copian las dependencias externas de una maqueta HTML. El documento no usa Google Fonts, `doc-page.js`, `image-slot.js` ni rutas de logos ajenas: la marca del propio informe es tipográfica y autocontenida para que no se rompa en PDF, y la paginación se apoya en `AnimalCharlieDocumentEditor.mount(...)` y `AnimalCharliePdfEngine.shared()`.

La plantilla no inventa históricos ni resultados. Si un bloque está activo pero no dispone de serie temporal, fotografías, lecturas, revisión punto a punto o datos de integración, muestra un estado pendiente editable. Las referencias de tanque son una guía visual y deben interpretarse según laboratorio, contrato y normativa aplicable.

Cada bloque usa páginas A4 independientes con cabecera y pie. Los históricos de tanque con más de veinte muestras se dividen en páginas de hasta 24 filas sin truncar resultados; los animales revisados se agrupan de 24 en 24 y los animales problema de cinco en cinco. CMT puede producir varias páginas de animales revisados, mosaico por cuarterones y animales problema. Si el bloque está activo pero aún no tiene lecturas, se genera una página explícita `CMT pendiente` en lugar de impedir la visita.

El contenido se edita con `AnimalCharlieDocumentEditor.mount(...)`. Formato, historial, tablas, imágenes, zoom, vista previa, pantalla completa e IA sobre selección siguen siendo comunes con Genaro y Certificación. La acción `Archivos e imágenes` abre `AnimalCharlieAssetLibrary`: el técnico puede subir una fotografía o documento una sola vez, reutilizarlo desde la biblioteca e insertarlo en el informe; las imágenes quedan autocontenidas para PDF y los documentos aparecen como referencias descargables dentro de AnimalCharlie. La importación TXT/Markdown de CMT usa también `AnimalCharlieAssetLibrary.mountFileInput(...)`, de modo que un texto ya guardado entra por el mismo procesado que un archivo local. El contrato común está en `ASSET_LIBRARY_ENGINE.md`; Calidad lechera no mantiene otro cargador. `Descargar PDF` usa `AnimalCharliePdfEngine.shared()`, `/api/pdf/render`, módulo `milk_quality`, `renderMode: "milk_quality_screen"` y la misma composición visible. `/api/milk-quality/pdf` permanece como alias compatible.

## CMT opcional

Las lecturas mantienen el orden:

| Campo | Cuarterón |
| --- | --- |
| `DI` | Delantero izquierdo |
| `DD` | Delantero derecho |
| `TI` | Trasero izquierdo |
| `TD` | Trasero derecho |

Escala operativa: `0` negativo, `1` trazas, `2` positivo leve, `3` revisar, `4` mamitis clínica, `5` seco y `6` sangre.

El parser acepta, entre otros:

```text
Vaca 856: 0-0-3-0.
Vaca 842: negativo.
788 1-0-4-0, trasero izquierdo con secreción serosa.
Vaca 20, 44, 1, 0, 0, 1.
Vaca 15, 0, 2, 2, 4, 0, 0.
```

Los formatos compactos reconstruyen primero el número de explotación: `20, 44, 1, 0, 0, 1` se interpreta como vaca `2044` y CMT `1-0-0-1`.

## Audio, TXT y WhatsApp

El bloque CMT reutiliza los endpoints protegidos del módulo:

- `POST /api/milk-quality/whatsapp-messages`: lista audios entrantes recientes.
- `POST /api/milk-quality/whatsapp-media`: recupera el audio seleccionado.
- `POST /api/charlie/transcribe-audio-jobs`: crea la transcripción asíncrona.
- `GET /api/charlie/transcribe-audio-jobs/{id}`: consulta el progreso.
- `whatsapp.messages.send` con `confirmWrite: true`: envía el resumen de aprobación.

Los endpoints propios de consulta se limitan a audios entrantes recientes y rechazan adjuntos no audio o mensajes salientes aunque se conozca su identificador.

La lista permite filtrar por fecha o remitente y transcribir varios audios. La selección múltiple concatena las transcripciones antes de reconstruir las lecturas. Los trabajos se serializan para evitar duplicar Whisper y la UI puede reencolar una vez si el backend pierde un job tras reiniciarse.

Formatos admitidos: `.opus`, `.ogg`, `.oga`, `.m4a`, `.mp3`, `.wav`, `.aac`, `.webm`, `.flac` y `.mp4`, además de TXT y Markdown.

## Charlie y MCP

Charlie ve el módulo como `animal-charlie.milk_quality`. `milk_quality_review_queue` devuelve visitas de calidad, número de bloques y si incluyen CMT. Solo agrega vacas positivas o CMT 4+ cuando esa sección existe. El contexto de entidad expone `Bloques` e `Incluye CMT` además del estado y la explotación.

Límites de IA:

- Respetar bloques activados y orden documental.
- No inferir que se hizo CMT cuando `cmtIncluded` es falso.
- No diagnosticar ni prescribir tratamientos.
- No inventar resultados, dosis o tiempos de espera.
- Recomendar contraste veterinario y trazabilidad cuando existan datos clínicos.

## Verificación

`verify.js` cubre el catálogo, el esquema `milk-quality-visit/v3`, la normalización de `milk-quality-visit/v2` y `milk-quality-cmt/v1`, la precarga `/api/milk-quality/context`, las colecciones repetibles, los campos profesionales del técnico, el guardado sin vacas y la presencia de CMT opcional.

`tools/verify_milk_quality_ui.py` valida en PC 1920×1080, PC 1280×800, Galaxy Tab A9+ e iPad Air horizontal y vertical:

- inicio en `Visita`;
- tres momentos memorizables con dos preguntas de campo cada uno, sin exponer al inicio la estructura documental;
- fecha y técnico propuestos automáticamente;
- selección táctil de tipo de visita y áreas realmente revisadas;
- dictado de la nota principal y persistencia en `visitData`;
- resumen automático de explotación, REGA y cliente;
- catálogo de explotaciones, recarga y reapertura conservados como opciones secundarias;
- acción primaria contextual `Continuar / Generar informe / Completar CMT`;
- navegador interno oculto en la ruta simple y visible solo para tareas avanzadas;
- acceso opcional al compositor y sincronización bidireccional de las tarjetas con sus bloques;
- ocho botones `Rellenar datos`, cambio directo de bloque y cierre del editor sin salir de `Personalizar`;
- filtrado del editor para que solo aparezcan los campos y colecciones de producción, ubre, ordeño, máquina, rutina, secado, CMT o fuentes;
- editor estructurado de históricos, animales, higiene, ordeñadores, pulsadores, bienestar, secado, acciones y firmas sin IDs ni modelos duplicados;
- persistencia de motivo, objetivo, alcance, resumen y conclusiones del técnico después de recargar datos automáticos;
- compositor con CMT desactivado;
- reordenación y ocultación de bloques;
- generación y documento sin CMT;
- reapertura con el momento activo y todos los campos de visita conservados;
- apertura exacta del bloque pendiente desde `Prioridades` y una sola primaria en `Aprobación`;
- activación de CMT dentro del editor inline, sin tercer paso, importación de cuatro vacas y prioridades;
- presencia de la plantilla técnica Herba, secciones numeradas, parámetros y gráficas CMT reales;
- carga larga con 64 muestras, 105 animales revisados y 38 animales problema, comprobando todas las filas, paginación A4 y un PDF real de 20 páginas;
- ausencia de overflow y de IDs duplicados;
- ausencia de solape entre el selector `Entrada / Informe` y el progreso de la visita;
- conservación de `display: table-row` en filas CMT `ok`, `notice`, `warning` y `alert`, cuyos tonos usan atributos propios para no heredar componentes globales como `.notice`;
- evidencia visual mediante el capturador común y `capture-manifest.json`, con cinco estados reales: visita, datos de producción, rutina, captura CMT y `Prioridades` ya generadas con sus hallazgos.
