The Artificer by Loopit
Ensayo de Arquitectura

La Mise en Place: Por qué tus transformaciones de datos son una bomba de relojería

Por Santiago Coca · 13 min de lectura · Entrega 04 de 15
Encimera de cocina con ingredientes preparados en boles, luz lateral dramática
Mise en place: cada transformación con nombre único, linaje claro y una sola fuente de verdad por concepto.

La semana pasada abrimos la despensa. Vimos que guardar los datos de forma permanente y organizada — separando la identidad del estado — es lo que permite responder a una auditoría en minutos y reprocesar sin depender de nadie.

Pero hay algo que no conté.

Tener la despensa perfecta no significa que puedas servir un solo plato.

“Tenemos todos los datos. No tenemos ninguna respuesta.”

En un proyecto de banca, el equipo había hecho las cosas bien. Los datos crudos estaban organizados, etiquetados, con histórico completo. La despensa era impecable. Cuando el regulador pidió el dato del 15 de marzo, lo encontraron en segundos.

Pero entonces llegó una petición distinta: “Necesitamos el saldo medio diario de cada cuenta durante el último trimestre.”

Silencio.

No porque no tuvieran los datos. Los tenían todos: cada saldo, cada día, cada cuenta. El problema era otro. Los saldos no llegaban todos los días. Algunos días, algunas cuentas no tenían movimiento. ¿El saldo de ese día era cero? No — era el mismo que el día anterior. Pero en los datos, ese día simplemente no existía. Era un hueco.

Y el saldo medio no es una media aritmética. No puedes sumar los saldos que tienes y dividir entre el número de registros, porque estarías ignorando los días sin registro. Un cliente que tuvo saldo de 100.000€ durante 89 días y un movimiento de 1€ el día 90 no tiene un saldo medio de 50.000€. Tiene un saldo medio de ~98.889€. Pero si solo tienes los dos registros (100.000 y 1), la media aritmética dice 50.000.

El equipo tenía un ingeniero senior que conocía el problema. Escribió un script de 400 líneas en SQL que generaba un calendario completo, rellenaba los huecos con el último valor conocido, y luego calculaba la media ponderada por los días reales. Funcionaba. Para una cuenta.

Pero tenían 200.000 cuentas. Con 15 indicadores cada una. Y el regulador lo necesitaba para 6 trimestres.

El script tardaba 4 horas en ejecutarse. Nadie más en el equipo entendía la lógica. Y cuando tres meses después el regulador cambió la definición (“ahora el saldo medio se calcula con días naturales, no hábiles”), el ingeniero tuvo que reescribir 200 de las 400 líneas.

Pero eso no fue lo peor. Lo peor fue que, mientras tanto, otro equipo en la misma empresa necesitaba calcular el saldo medio de otro tipo de indicador. Como no sabían que ya existía un script, escribieron el suyo. 350 líneas. Con una lógica ligeramente distinta. ¿Intencionadamente distinta o por error? Nadie lo sabe. Ahora había dos versiones del “saldo medio” en producción, con resultados diferentes, y nadie podía decir cuál era la correcta.

Los datos estaban ahí. La respuesta, no.

Tener los ingredientes en la despensa no significa que puedas servir un plato. Necesitas preparar esos ingredientes. Eso es la mise en place.

La mise en place: el trabajo invisible que lo cambia todo

En un restaurante profesional, nadie pela cebollas durante el servicio. Nadie filetea un salmón cuando el camarero grita “¡mesa 7!” Nadie mide las especias con el plato en el fuego.

Todo eso se hace antes. Es la mise en place: la preparación silenciosa que ocurre antes de que llegue el primer cliente. Cada verdura lavada y cortada. Cada salsa reducida y lista. Cada proteína porcionada y etiquetada. Todo en sus boles, medido, preparado, a punto.

Es el trabajo menos glamuroso de la cocina. Nadie saca fotos de la mise en place en Instagram. Pero preguntadle a cualquier chef: sin mise en place, el servicio es un caos. Con mise en place, el servicio fluye. La diferencia entre una cocina que saca 200 platos en una noche y una que colapsa en la mesa 15 es la preparación que nadie ve.

En datos, la mise en place es exactamente eso: el paso donde los ingredientes crudos de la despensa se transforman en información que Negocio puede usar. Donde el saldo del día 15 se convierte en saldo medio del trimestre. Donde la prima bruta se convierte en prima neta. Donde las filas de movimientos se convierten en la cartera asignada por sucursal.

Es la capa donde se aplican las reglas de negocio. Y es la capa donde, en la mayoría de las empresas, todo se rompe.

El antipatrón: la mise en place encadenada

Dejadme que os describa cómo funciona la mise en place en la mayoría de data warehouses que he visto.

Dominós etiquetados Extracción, Limpieza, Cálculo cayendo en cascada hacia un informe de negocio
Un eslabón roto en la cadena derriba todo el informe — aunque cada paso pareciera correcto.

Hay un pipeline. Empieza en la extracción de datos del sistema origen. Esos datos pasan a una tabla temporal. De ahí, un script los limpia y los deja en otra tabla. Otro script coge esa tabla, aplica una fórmula de negocio y genera una tercera tabla. Otro script agrega, pivota, y deja el resultado en una vista que alimenta el informe.

Cada paso depende del anterior. Cada tabla es la entrada del siguiente script. Es una cadena lineal, como fichas de dominó.

Y funciona. Hasta que alguien toca la primera ficha.

Un viernes, el equipo de sistemas origen añade un campo nuevo a la tabla de saldos. No cambia nada existente — solo añade una columna. “Es retrocompatible”, dicen. Y técnicamente lo es.

Pero el script de limpieza tiene un SELECT * que ahora trae una columna más. La tabla temporal cambia de esquema. El script de cálculo, que esperaba exactamente 47 columnas, falla. El de agregación ni arranca porque su entrada no existe. El informe del lunes sale vacío.

Un campo nuevo. Retrocompatible. Y la cadena entera se rompe.

El problema no es el SELECT * (que sí, es mala práctica). El problema es el acoplamiento. Cada eslabón de la cadena conoce los detalles internos del anterior. Si el anterior cambia — aunque sea de forma “compatible” — el siguiente puede romperse. Es un castillo de naipes disfrazado de pipeline.

Y lo peor no es que se rompa. Lo peor es que no sabes qué se va a romper hasta que se rompe. Porque las dependencias son implícitas. No están declaradas en ningún sitio. Viven en los SELECT, en los JOIN, en los WHERE de scripts que nadie documenta y que solo entiende la persona que los escribió.

He visto equipos que dedican más tiempo a arreglar las roturas de su mise en place que a construir cosas nuevas. Cada lunes empieza con la misma pregunta: “¿Qué se ha roto este fin de semana?” No porque los datos sean malos. Sino porque la cadena de transformación es frágil.

¿Recordáis el 40% de tiempo reactivo que mencionamos en la Semana 1 (dato de Monte Carlo Data, 2023)? Una parte importante de ese tiempo se va en esto: investigar qué se rompió, dónde, por qué, y arreglarlo antes de que alguien abra un informe y vea números absurdos. No es trabajo de ingeniería. Es fontanería. Y es consecuencia directa de tener una mise en place encadenada.

Tu mise en place es un castillo de dominós. Y cada lunes es un terremoto.

Funciones, no cadenas

Volvamos a la cocina. Y pensad en qué pasa cuando un cocinero empieza a cocinar directamente, sin preparación previa.

Encimera con boles independientes de relleno temporal, saldo medio y reorganización
Un bol nuevo no toca los demás: cada transformación con entradas y salida declaradas.

Echa la zanahoria, el tomate y la cebolla en la olla. Empieza a sofreír. Hasta aquí, bien. Pero de repente llega un pedido nuevo: el mismo plato, pero sin tomate. ¿Qué hace? No puede sacar el tomate de la olla. Ya está mezclado. Ya está acoplado. Tiene que empezar de cero con otra olla.

Eso es exactamente lo que pasa cuando acoplas las transformaciones al principio del pipeline. Si tu primer script mezcla extracción, limpieza y cálculo en una sola cadena, cualquier variación te obliga a empezar de cero. ¿Otro equipo necesita los mismos datos pero con un cálculo diferente? No puede reutilizar tu olla. Tiene que montar la suya desde el principio. Y ahí nacen las 10 versiones del saldo medio.

En cambio, si tienes la zanahoria en un bol, el tomate en otro y la cebolla en otro, puedes combinarlos como quieras. Plato con tomate: coges tres boles. Plato sin tomate: coges dos. Los boles no cambian. Las combinaciones sí.

En una mise en place profesional, el bol de cebolla cortada no sabe que existe el bol de salsa. El bol de salsa no sabe que existe el bol de carne porcionada. Cada preparación es independiente. Tiene su ingrediente de entrada, su proceso, y su resultado. Si mañana el chef decide cambiar el corte de la cebolla de brunoise a juliana, la salsa no se entera. Porque la salsa no depende del corte de la cebolla. Depende de sus propios ingredientes.

Y si el chef quiere añadir un bol nuevo — unas verduras encurtidas que antes no estaban en el menú — lo pone en la mesa junto a los demás. No necesita reorganizar la mise en place entera. No toca los boles que ya existen. Simplemente añade uno.

Puedes añadir preparaciones nuevas sin modificar las existentes. Y cada preparación es una función independiente: recibe entradas definidas, produce una salida definida, y no tiene efectos sobre el resto.

¿Por qué en datos no hacemos esto?

Pensad en nuestro saldo medio. ¿Qué necesita como entrada? Una serie temporal de saldos. ¿Qué produce? Un saldo medio por período. No necesita saber de dónde vienen los saldos. No le importa si son de un banco o de una aseguradora. No le importa si la fuente tiene 10 columnas o 200. Solo necesita: una columna de fecha, una columna de importe, y una clave que identifique la cuenta.

Es una función. Entradas → proceso → salida. Y si mañana necesitas calcular el saldo medio de otro indicador, no reescribes el script de 400 líneas. Usas la misma función con otros parámetros.

Lo mismo con el relleno de huecos temporales. ¿Qué necesita? Una serie temporal con posibles huecos. ¿Qué produce? Una serie completa, sin huecos, con una política de relleno definida (repetir el último valor, poner cero, interpolar). No le importa qué representan los datos. Es una función.

Y se componen: primero rellenas los huecos, luego calculas el saldo medio sobre la serie completa. Dos funciones. Cada una independiente. Conectadas por un contrato simple: “la salida de la primera es una serie temporal completa, y la segunda espera exactamente eso.”

Si mañana cambias la política de relleno de “repetir último valor” a “interpolar linealmente”, el cálculo de saldo medio no se entera. Porque no depende de cómo se rellenaron los huecos. Solo de que la serie sea completa.

Y si pasado mañana necesitas un cálculo nuevo — por ejemplo, la variación máxima intradía — añades un tercer componente que recibe la misma serie completa. No tocas los dos anteriores. No necesitas coordinarte con nadie. No rompes nada. Simplemente añades un bol a la mesa.

Y ahora pensad en el problema del principio: dos equipos con dos versiones del saldo medio. ¿Recordáis que no sabíamos si la diferencia era intencionada o un error?

Con boles independientes, la respuesta es clara. Si el segundo equipo necesita un saldo medio calculado de forma diferente — por ejemplo, con días naturales en vez de días hábiles, o con una política de relleno distinta — no modifica el componente que ya existe. Crea uno nuevo. Con sus propios parámetros. Con su propio contrato. Con su propio nombre.

Y los dos conviven. Sin conflicto. Sin ambigüedad. El equipo de Tesorería sigue usando SaldoMedio-DiasHabiles. El equipo de Regulatorio usa SaldoMedio-DiasNaturales. Cada uno coge sus ingredientes de la despensa y sus elaboraciones de la mise en place. Sin dependencias. Sin afectaciones. Si mañana Tesorería cambia un parámetro de su versión, Regulatorio ni se entera. Porque no comparten bol. Comparten despensa.

Eso es lo que la ingeniería de software llama Open/Closed: abierto a la extensión (puedes añadir componentes nuevos), cerrado a la modificación (no tocas los que ya funcionan). Y en una cocina se entiende al instante: añades boles a la mesa sin tocar los que ya están.

Eso es desacoplamiento real. No el que se escribe en un documento de arquitectura. El que se implementa en la estructura de los datos.

Y aquí es donde la despensa lo hace posible

¿Recordáis que en la Semana 3 insistimos en separar la identidad del estado? ¿En que cada foto de estado de cada entidad es independiente?

Esa separación no era solo para la trazabilidad. Era para esto.

Cuando la despensa separa las fotos de estado de cada entidad, cada preparación de la mise en place puede operar sobre una sola entidad sin acoplarse a las demás. El saldo medio opera sobre las fotos de estado de la cuenta. La prima neta opera sobre las fotos del contrato. La cartera opera sobre las fotos de la sucursal. Cada una en su bol. Independientes.

Si mañana Riesgos añade un indicador nuevo a su entidad, la mise en place de Marketing no se entera. Si Finanzas cambia la fórmula de la provisión técnica, el saldo medio de Tesorería sigue funcionando. Porque no comparten cadena. Comparten identidades (los enchufes estándar de la Semana 1), pero cada uno tiene su mise en place propia.

En el antipatrón de la cadena de dominós, un cambio en la extracción rompe todo río abajo. En una mise en place desacoplada, un cambio en una entidad afecta solo a las preparaciones de esa entidad. El radio de impacto pasa de “todo” a “solo lo que toca.”

Ahora pensad en lo que esto significa para los 15 equipos de la Semana 1. Cada equipo puede crear y evolucionar sus preparaciones sin pisarse, sin coordinarse, sin esperar a que el otro termine. Exactamente igual que 15 cocineros preparando sus boles en la misma cocina sin estorbarse.

Lo que casi nadie hace: la mise en place gobernada

En un restaurante, cada preparación de la mise en place tiene una ficha técnica. No es solo un bol de salsa. Es “Salsa boloñesa — receta #14 — Chef: Marco — Porciones: 12 — Caducidad: 24h.” Si Marco se va y Ana tiene que prepararla, la ficha lo tiene todo.

En la mayoría de data warehouses, las transformaciones no tienen ficha. Son scripts en Git (con suerte) o en la carpeta personal de alguien. No tienen contrato explícito: qué esperan recibir, qué garantizan producir. No tienen owner. No tienen versionado.

Una mise en place gobernada es otra cosa. Cada preparación tiene un contrato declarado:

  • Qué espera recibir: una serie temporal con estas columnas, en este formato.
  • Qué garantiza producir: una serie sin huecos, rellena con esta política.
  • Quién la definió: el equipo de Tesorería, porque ellos saben cómo se calcula un saldo medio en su contexto.
  • Qué parámetros acepta: granularidad, política de relleno, período.
  • Qué versión es: v1.0, aprobada el 12 de febrero.

Ese contrato no es un documento separado. Es el propio componente. La definición y la ejecución son la misma cosa, igual que la Receta de la Semana 2. No puedes ejecutar una preparación sin definir su contrato. La gobernanza viene incluida.

En la cocina amateur, el chef tiene la receta en la cabeza. En la cocina profesional, la receta está en la ficha. Y si el chef se va, la ficha se queda.

Volvamos a nuestro saldo medio

¿Recordáis el proyecto de banca del principio? 200.000 cuentas, 15 indicadores, 6 trimestres. Un script de 400 líneas que solo una persona entendía.

Con una mise en place desacoplada y gobernada, la historia habría sido muy distinta.

El relleno de huecos habría sido un componente estándar. Entrada: serie temporal con huecos. Salida: serie completa. Política: repetir último valor conocido. Eso es todo. No 400 líneas — una definición de 10 parámetros.

El saldo medio habría sido otro componente. Entrada: serie temporal completa. Salida: saldo medio por período. Parámetros: granularidad, fecha inicio, fecha fin. Otra definición de 10 parámetros.

Dos componentes. Compuestos. Cada uno con su contrato. Cada uno reutilizable para las 200.000 cuentas y los 15 indicadores. Sin reescribir nada.

Y cuando el regulador cambió la definición de “días hábiles” a “días naturales”, el cambio fue un parámetro. No 200 líneas de SQL. Un parámetro.

Pero la historia tiene un epílogo que cuenta más que los números. Aquel ingeniero senior que escribió las 400 líneas se fue del proyecto tres meses después. El equipo tardó dos semanas en entender su código. Dos semanas de un ingeniero a tiempo completo solo para descifrar lo que había hecho el anterior. Con un componente gobernado, el contrato lo habría explicado todo: qué hace, cómo lo hace, qué espera, qué produce. El cambio de “días hábiles” a “días naturales” lo habría hecho cualquiera en una tarde.

Ahora imaginad que alguien — o algo — pudiera tomar esa definición de parámetros y generar automáticamente todo el SQL necesario para cada warehouse, cada fuente, cada indicador. Que lo que antes era un script artesanal de 400 líneas se convirtiera en una definición declarativa que un motor ejecuta.

Como si alguien hubiera pre-cortado todas las verduras exactamente como las necesitas, antes de que llegaras a la cocina.

Los números

Para los que necesitan justificarlo ante un comité:

Sin mise en place estandarizada (scripts artesanales, acoplados): - Tiempo de implementación de un saldo medio nuevo: 2-4 semanas (escribir el script, debugear, validar con Negocio, documentar si hay suerte). - Impacto de un cambio en origen: impredecible (puede romper 0 o 15 transformaciones, no lo sabes hasta el lunes). - Tiempo de investigación cuando algo falla: horas a días (¿dónde está la lógica? ¿quién la escribió? ¿qué versión es?). - Reutilización entre fuentes: cero (cada equipo reimplementa el mismo cálculo a su manera).

Con mise en place desacoplada y gobernada (componentes con contrato): - Tiempo de implementación: horas (defines los parámetros, el componente hace el resto). - Impacto de un cambio en origen: localizado (afecta solo a las preparaciones de esa entidad, el resto ni se entera). - Tiempo de investigación: minutos (el contrato dice qué hace, quién lo definió, y qué versión es). - Reutilización: total (el mismo componente de saldo medio para 200.000 cuentas, solo cambian los parámetros).

Y hay un número que importa más que todos los demás: el número de implementaciones distintas del mismo cálculo. En una empresa con 15 dominios, sin componentes estándar, es habitual encontrar 8 o 10 versiones del “saldo medio”, cada una con variaciones sutiles que nadie sabe si son intencionadas o son bugs. Con componentes gobernados, hay una versión. Versionada. Auditable. Y si alguien necesita una variación, crea un nuevo componente — no modifica el existente.

Para el CDO o CTO que esté leyendo esto: pensad en lo que significa cuando el regulador pregunta “¿cómo calculáis el saldo medio?” y la respuesta honesta es “depende de a qué equipo le preguntes.” No es un problema técnico. Es un riesgo regulatorio. Es un hallazgo de auditoría. Y con componentes gobernados, la respuesta es: “Lo calcula el componente SaldoMedio v2.1, con estos parámetros, definido por el equipo de Tesorería, aprobado el 12 de febrero.” Una respuesta. No diez.

La mise en place no es un detalle técnico. Es la diferencia entre una cocina que escala y una que colapsa cada lunes.

Lo que viene: el emplatado

Hoy hemos preparado los ingredientes. Hemos visto que tener datos crudos organizados no basta: necesitas transformarlos en información de negocio. Y hemos visto que la forma en que lo haces importa tanto como el resultado: funciones independientes, no cadenas acopladas. Con contrato, no scripts sueltos. Gobernado, no improvisado.

Pero los ingredientes preparados siguen en la cocina. Negocio no entra en la cocina a servirse. Necesita un plato terminado: una tabla limpia, un dashboard, un reporte regulatorio. Algo que pueda consumir sin saber cómo se preparó.

La semana que viene vamos al emplatado: donde la información preparada se presenta para el consumo. Donde se oculta la complejidad de la despensa y la mise en place detrás de una interfaz simple. Y donde se certifica que lo que sale de la cocina cumple los estándares de calidad antes de llegar a la mesa.

Porque de nada sirve una mise en place impecable si el plato sale mal presentado. O peor: si sale sin que nadie haya comprobado que está en condiciones de servir.

Pero antes de pasar al emplatado: