# Paso 6 · Tandas — deuda y notas

Último paso estructural. Migración `2026_07_23_100010_restructure_batches`. Lo aplazado:

## Muere con el motor (no aquí)
- **`batch_steps.min_day/max_day`, `batches.target_duration_days` (campo de request, ya sin columna), `*.quantity` (3 tablas):** tiempo/cantidad que alimenta cálculos vivos (`expected_end_date`, timeline, reschedule). Cuarta vez que el patrón intenta colarse; mueren cuando el motor sustituya el rango por una predicción, no antes.
- **`reschedule()` reescala leyendo `guideStep->min_day` (origen vivo, drift-free).** Hay una tensión real con la autonomía del snapshot (§6.5): si se edita la guía, la ventana reescalada la sigue. No se resuelve aquí porque estas columnas son precisamente las que el motor reemplaza. Deuda del motor.

## Cambio de contrato — API V1 · **INCOMPATIBLE** (2026-07-23, paso 6)
- **`BatchResource`: la clave `review` desapareció; todo cuelga de `flavor_result`.** Ahora `flavor_result` lleva `rating`, `overall_comment`, `is_public` + los 6 ejes + `notes` (antes `review` = rating/comentario/3 niveles y `flavor_result` = 6 ejes, dos objetos que medían lo mismo). **`batch.review.rating` → `batch.flavor_result.rating`.** Endpoint de escritura `POST .../review` sin cambios de firma (mismos campos; escribe una sola fila).
- **NO fue gratis (corrección):** se asumió que la PWA no leía este resource. Sí lo hacía — `fermentos.blade` y `lote-resumen.blade` leían `b.review.rating`/`.overall_comment`, y `lote-resumen` usaba `!b.review` para decidir si ofrecer «evaluar». Al desaparecer la clave, la PWA ofrecía evaluar lotes ya evaluados → 422 al guardar. Arreglado en `b21ea13` (la PWA lee `b.flavor_result`). Lección: antes de romper una clave de API, `grep` de los consumidores reales, no suposición. El día del TWA nativo el coste vuelve a subir — por eso el contrato está en el plan de documentación.
- **Alias `ferment_type` — vencimiento fijado.** `BatchResource` expone la clave `ferment_type` alimentada por `guide` (`whenLoaded('guide')`), aunque la tabla `ferment_types` no existe desde el paso 3 (la guía la absorbió). Se conserva a propósito: renombrarla a `guide` justo antes de desplegar reintroduce la clase de bug de `review`, y la PWA la usa en 8 sitios. **Pero es una clave que nombra una tabla muerta:** sin fecha, dentro de un año alguien la lee en el JSON, busca la tabla y no la encuentra — sedimento que miente sobre el sistema, no código roto. **Muere en el contrato de API (con el TWA):** ahí `ferment_type` → `guide` y el alias desaparece. No renombrar antes; no dejarlo sin fecha después.

## UI / motor (no esquema)
- **Borrador desfasado.** El borrador no caduca; que su guía haya cambiado desde que se formuló es un aviso de la UI ("esta receta se actualizó"), no un estado ni una columna.
- **"Otra igual" vs "otra como aquella".** Rearrancar desde una tanda previa (misma formulación exacta vs. tomarla de base y ajustar) es decisión de UI/motor; el esquema solo necesita que `batch_code` se genere al arrancar.

## Decisión aplicada (flag para veto)
- **Los 6 eventos `mood`** tenían `"mood":null` y cargaban notas de cata a nivel de paso ("Muy ácido", "Reducir azúcar"). En vez de moverlos a `daily_logs` (que habría descolgado la nota de su paso), se **re-tiparon a `taste`**, conservando el contexto de paso. El tipo `mood` desaparece igual del enum de `batch_events`; `daily_logs.mood` queda como único dueño del concepto mood. Desvía de la instrucción literal "migrar a daily_logs" — si el propietario lo prefiere en daily_logs, es una migración `100011`.
