# Reproducibilidad del esquema y forma del aplanado final

> Restricción descubierta durante el paso 2 del refactor del Mentor. No es
> urgente (no hay despliegue nuevo desde cero), pero condiciona el aplanado
> final de migraciones y conviene tenerla escrita antes de que se olvide.

## El problema

El estado actual de la base **solo es alcanzable ejecutando las migraciones
contra los datos que ya existían**. Varias migraciones del refactor son
**migraciones de datos** (retax de clasificaciones, backfill de guías, backfill
de los 40 `batch_steps` legacy, NULL de columnas obsoletas) que operan sobre
filas concretas.

Los **seeders**, en cambio, corren **después** de todas las migraciones en un
`migrate:fresh --seed`. Cuando una migración de datos se ejecuta sobre una
instalación limpia, las filas que espera **aún no existen** (las crea el seeder
más tarde), así que no hace nada.

**Consecuencia:** una instalación limpia (`migrate:fresh --seed`) produce un
estado **distinto** del de producción:

- Clasificaciones: los seeders siembran la taxonomía vieja; el retax ya corrió en
  vacío. Quedan slugs y estantes que no coinciden con los 4 actuales.
- Guías sin `fermentation_category_id` (el backfill corrió antes de que existieran).
- `ferment_types.fermentation_category_id` según el seeder, no el NULL acordado.

El proyecto ya **no es reproducible desde cero**, y lo es un poco menos con cada
migración de datos que se añade.

## La forma obligada del aplanado

Cuando se aplanen las migraciones (paso final del refactor, cuando el esquema
esté estable), el resultado **no puede ser** «esquema + migraciones de datos».
Tiene que ser:

> **esquema (una migración de creación limpia) + SEEDERS que produzcan el estado
> real.**

Porque los seeders son los que sí corren después de crear el esquema. Toda la
lógica de datos que hoy vive en migraciones (las 4 clasificaciones actuales, las
guías con su estante, los tipos con categoría a NULL, los snapshots completos)
debe reescribirse como estado sembrado, no como transformaciones incrementales.

Dicho de otro modo: el aplanado no es solo «juntar migraciones». Es **reconciliar
los seeders con el estado post-refactor** para que `migrate:fresh --seed` vuelva
a dar exactamente lo que hay en producción.

## Checklist para ese momento (paso final)

- [ ] Seeder de clasificaciones = los 4 estantes actuales (no la taxonomía micro)
- [ ] `FermentationGuidesSeeder` siembra `fermentation_category_id` de cada guía
- [ ] `FermentTypesSeeder` deja `fermentation_category_id` a NULL (ya hecho) o la
      columna ya no existe (muere en paso 3)
- [ ] Los seeders de pasos crean `batch_steps`/snapshots completos (title,
      step_number NOT NULL) — sin filas legacy que rellenar
- [ ] Verificar: `migrate:fresh --seed` en limpio == estado de producción
