The Artificer by Loopit
Ensayo de Arquitectura

El almacén central de Objectville: un solo contrato común al que toda la cadena se suscribe

Por Santiago Coca · 13 min de lectura · Entrega 07 de 15
Almacén industrial oscuro con estanterías simétricas y luz azul tenue
Un almacén central versionado: cada dominio suscribe el contrato común y aporta su pieza.

El brazo robot del almacén

La semana pasada cerré con un brazo robot que servía pizza con salsa de noodles si las cajas del almacén estaban mal colocadas. La pizza salía con seguridad académica — y mal hecha. La pregunta que dejé abierta era esta: ¿cómo se organiza el almacén para que el brazo no pueda equivocarse?

Hoy entro a contestar. Y la mejor manera de verlo es desde dentro de una franquicia que ya lo hace bien.

La inspección de los lunes

Lunes por la mañana en una sede cualquiera de Objectville Pizza Store. Llega el inspector. Sin avisar, como en cualquier inspección decente. Pide tres cosas: trazabilidad de la materia prima del fin de semana, registro de temperatura de los hornos, y la lista de alérgenos servida con cada plato.

La gerente no se va al despacho a buscar carpetas. No llama a la central. No abre un Word. Abre un sistema, abre dos pestañas, y enseña.

En quince minutos la inspección está cerrada. Sin discutir. Sin reproches. Sin esa cara de pánico que se le pone a una pyme cuando entra alguien con una libreta.

Lo interesante no es que la inspección se haya pasado. Lo interesante es lo que la sede no ha tenido que decidir para pasarla. No ha decidido qué cuenta como un lote de mozzarella. No ha decidido bajo qué código identifica al cliente que pidió la pizza Chicago Style. No ha decidido si el lote MZ-7842-IT del lunes es el mismo que el que llegó el martes con el código MZ-7842-IT-2 ni si la cebolla cortada del miércoles cuenta como “fresca” o “preparada”.

Nada de eso lo decide la sede. La franquicia ya lo tiene decidido. Y lo tiene decidido igual para las cuarenta sedes — no caso por caso, no negociado por gerente, no según costumbre del barrio. Un manual. Un contrato común. Cuarenta gerentes con autonomía sobre lo que el contrato no fija.

Os pregunté la semana pasada cómo se implementa una despensa de datos. Hoy entro a contestarlo, y al brazo robot a la vez. Lo primero que veréis al entrar al almacén es que no distribuye una cosa, distribuye dos — y que ese matiz, que parece pequeño, es lo que diferencia una franquicia que escala de una cadena que se rompe en pedazos a la primera crisis.

Eje 1 — La central distribuye dos cosas, no una

En la mayoría de las cadenas, la central distribuye ingredientes. Harina, tomate, mozzarella, aceite. Audita la calidad de cada lote, negocia los precios con el proveedor, y manda al final un camión con cajas etiquetadas. Cada sede recibe sus cajas, las identifica como puede, y se busca la vida para encajarlas en su proceso.

Caja de mozzarella con etiqueta firmada por la central: lote, proveedor, alérgenos y regla de validación
La etiqueta la firma la central. La sede la aplica — sin renegociar identidad.

Eso ya es mucho mejor que pedir cada sede su propia harina. Pero no basta.

En Objectville la central hace algo más. Junto al ingrediente auditado distribuye también su etiqueta de identidad. La sede recibe la mozzarella y junto a ella una tarjeta colgada que dice: “Mozzarella di bufala — lote #2026-04-23-1742 — proveedor certificado — alérgenos: lácteos — válida hasta el viernes — identificador de franquicia: MOZ-7842”. Esa tarjeta la firma la central, no el proveedor. La sede no la negocia. La aplica.

¿Por qué dos cosas y no una? Porque cuando entra una pizza por la puerta de tres sedes distintas — Roma, Boston, Chicago — y el inspector pregunta “¿de qué lote era ese ingrediente?”, las tres responden con el mismo identificador. Las tres pueden trazar atrás hasta el mismo proveedor. Las tres pueden, si hay un retiro de lote por contaminación, identificar exactamente qué pizzas usaron qué ingrediente y avisar a sus clientes.

La identidad llega firmada de la central. La sede no la negocia. La aplica.

Trasladado al dato, la cosa funciona igual. La franquicia de datos no distribuye solo “ingredientes” — esquemas de tablas crudas, accesos al warehouse, copias de los CSV de origen. Eso es lo que distribuye una arquitectura inmadura — “aquí tienes BigQuery, apáñate” —, y es exactamente lo que provoca que cada dominio reinvente su propio cliente, su propio producto, su propia idea de qué cuenta como un “contrato”.

La franquicia de datos distribuye dos cosas:

  1. Ingredientes auditados — el qué: una despensa común con los ingredientes canónicos de toda la cadena. Cliente. Producto. Contrato. Punto de venta. Cada uno con un código común, una manera única de identificarlo.
  2. La etiqueta firmada — la traza completa del ingrediente: cada vez que un dominio sube datos a la despensa, la plataforma firma no solo quién es el ingrediente, sino también de qué pedido viene, cuándo llegó, qué características tiene y qué validaciones ha pasado. El cliente NIF/CIF que sube Pólizas y el cliente que sube Siniestros, si son el mismo cliente, llevan pegada la misma etiqueta firmada. No por coincidencia. Por contrato.

Esa traza firmada es lo que hace que cuando un auditor pregunta “¿qué clientes tienen pólizas y siniestros abiertos al mismo tiempo, y desde cuándo?”, la respuesta exista — y además sea demostrable. Sin reuniones de coordinación. Sin un equipo central revisando. Las dos sedes hablan el mismo idioma porque el almacén firmó la traducción en el momento en que el dato entró.

Eje 2 — Hub, Satellite y Link (y por fin un nombre completo)

Lo que acabamos de ver — el catálogo canónico por un lado, la etiqueta firmada con la traza completa por otro — lleva dos décadas con nombre propio. El catálogo es la identidad: qué cuenta como cliente en toda la cadena, dónde vive esa definición. La etiqueta firmada es el estado: qué sabemos de ese cliente, qué scoring tiene, en qué dirección vive, qué teléfono tenía el año pasado. Los dos separados.

Esa separación tiene nombre y apellido desde hace dos décadas. Hasta hoy lo había llamado por su función — porque quería que entendierais por qué la separación es correcta antes de que el nombre la condicionara. Hoy le pongo el nombre completo.

Es Data Vault 2.0.

La identidad de cada entidad común — el cliente, el producto, el contrato — vive en una pieza llamada Hub. El Hub es deliberadamente austero: lleva la clave de negocio, una clave técnica derivada por un hash determinista, una marca de cuándo se vio por primera vez y de qué fuente vino. Nada más. Esa austeridad es a propósito: el Hub define qué cuenta como cliente, no qué sabemos de él.

El estado vive en una pieza llamada Satellite. El Satellite cuelga del Hub y describe atributos versionados. Si el cliente cambia de dirección, no se sobrescribe la dirección antigua — se inserta una fila nueva en el Satellite con un sello temporal, y la antigua queda viva en su época. Si Pólizas guarda atributos del cliente — fecha de incorporación, scoring, segmento comercial — vive en su Satellite. Si Siniestros guarda otros — historial de partes, indicador de fraude, prima ajustada — vive en otro Satellite, colgando del mismo Hub.

Y aquí está la propiedad que ningún warehouse tradicional resuelve:

Pólizas y Siniestros pueden añadir, evolucionar y refinar sus Satellites en paralelo, sin coordinación humana entre equipos, sin pisarse, sin romper a la sede de al lado. Cada Satellite es un trozo de modelo independiente que se conecta al Hub común. La concurrencia es estructural — no es algo que se resuelva con un comité de coordinación; es algo que se resuelve porque el modelo está diseñado para que dos dominios no necesiten reunirse para añadir su parte.

Esa propiedad — paralelismo de trabajo y de carga: dos dominios trabajando a la vez, sin coordinación, sin pisarse — es la primera cosa que cualquier implementación seria de Data Vault 2.0 industrializa desde hace años. Es vocabulario común del modelo, no patente de nadie. Lo importante hoy no es la maquinaria que lo automatiza — lo importante es por qué la separación Hub/Satellite es lo que hace posible la cadena.

Y mientras esto pasa, hay otra propiedad operando en silencio: nada se borra. El Satellite de Pólizas guarda la dirección de hoy, pero también la del año pasado, y la del año anterior, cada una con su rango de validez. Eso se llama insert-only — solo se inserta, nunca se sobrescribe — y es lo que hace que la memoria de la cadena se sostenga sin esfuerzo. Cuando dentro de seis meses alguien descubre que un dato que entró el 14 de marzo era erróneo, no hay que reconstruir nada de papeles antiguos. La fila incorrecta sigue allí, con su sello temporal cerrado por una corrección posterior.

De ahí sale otra propiedad consecuencia, también demasiado densa para abrirla hoy: reproceso = replay. Reproducir el cálculo del 14 de marzo con la regla vigente ese día se hace porque las versiones no se han destruido. La semana que viene la abro en serio. Hoy basta con que sepáis que vive en el modelo, y es consecuencia del insert-only — no un módulo añadido encima.

Hub guarda identidad. Satellite guarda estado. Y falta una tercera pieza, la que conecta entidades entre sí: el Link.

Cuando llega al almacén un dato que dice “el cliente Pepe tiene la póliza P-1234”, eso no es un atributo de Pepe ni un atributo de la póliza. Es una relación. Y las relaciones, en este modelo, no se guardan dentro de las entidades — se guardan en una pieza propia. Un Link Cliente-Póliza es la pareja de identidades + un sello temporal de cuándo se vio esa relación + la fuente que la trajo. Nada más.

¿Por qué hace falta una pieza solo para esto? Porque los Links emergen automáticamente del paralelismo de carga. Pólizas sube su Cliente y su Póliza. Siniestros sube su Cliente y su Parte. Nadie está hablando con nadie. Pero el Link Cliente-Póliza que sube Pólizas y el Link Cliente-Parte que sube Siniestros se conectan al mismo Hub Cliente — sin necesidad de decírselo, sin reunión de coordinación.

Esa magia se sostiene sobre dos propiedades operativas que conviene nombrar antes de seguir, porque sin ellas no hay paralelismo posible:

Business keys. Son las claves de negocio que dan identidad a cada Hub canónico — el NIF del cliente, el código de póliza, el ISBN del libro, el SKU del producto. La franquicia decide qué business key da identidad a cada Hub, y esa decisión vive en el Shared Kernel — no la negocia cada dominio. “En esta cadena, un cliente se identifica por NIF/CIF — punto.” Cuando dos sedes hablan del mismo NIF, hablan del mismo cliente. No hace falta nada más.

Hashing determinista. El mismo NIF, normalizado, produce siempre la misma clave técnica — da igual qué sede lo cargue, cuándo, o desde qué sistema. Por eso cuando Pólizas y Siniestros suben el mismo NIF, la clave técnica que producen es idéntica — y por eso sus Links se enganchan al mismo Hub sin coordinación humana.

Las tres piezas estructurales del modelo cierran aquí, con sus dueños:

Pieza Para qué sirve Quién decide
Hub Identidad — quién es quién en la cadena La central (Shared Kernel)
Satellite Estado contextual — atributos versionados Cada dominio (autonomía)
Link Relaciones entre entidades Emerge mecánicamente del paralelismo

Las tres juntas son lo que hace que cuarenta dominios puedan cargar al mismo tiempo, contra los mismos Hubs, sin reuniones, sin pisarse, sin que la sede de al lado se rompa.

Pero todo esto — Hub, Satellite, Link, business keys, hashing, paralelismo, insert-only — se sostiene sobre algo más profundo. Se sostiene sobre un acuerdo común que la franquicia ya firmó antes de que la cebolla saliera del huerto. Y ese acuerdo común tiene un nombre técnico que no es nuestro — es prestado del diseño de software, igual que tantas otras piezas de esta serie.

Eje 3 — Shared Kernel: el contrato común que nadie negocia

Volvemos a la sede de Objectville. La gerente decide qué pizzas pone en su carta — la napolitana clásica, la Chicago Style, la california dreaming en LA, una pizza local con queso payoyo en Cádiz. Decide qué proveedores locales complementan el envío de la central. Decide qué horario abre. Decide qué clientela quiere fidelizar y cómo.

Lo que no decide:

  • Qué cuenta como un lote de mozzarella di bufala.
  • Bajo qué código identifica a un cliente regular.
  • Qué etiqueta de identidad lleva cada ingrediente que recibe.
  • Cómo se encadenan las trazabilidades cuando un mismo cliente compra en dos sedes distintas.

Eso lo decide la central. Y lo decide una sola vez, para toda la cadena. Esa pieza pequeña, deliberadamente mínima, es lo que en Domain-Driven Design (Eric Evans, 2003) tiene un nombre técnico: Shared Kernel. Un contrato mínimo común que dos o más dominios comparten sin negociarlo.

La franquicia de datos funciona porque la plataforma fija un Shared Kernel ejecutable: las entidades canónicas de la cadena (Cliente, Producto, Contrato), las tres reglas inquebrantables del almacén (separar identidad y atributos, no sobrescribir nunca, identificar de forma determinista), y las reglas mínimas de validación que un dato tiene que cumplir para entrar. Todo lo demás — qué Satellites añadir, qué reglas locales aplicar, qué productos componer — lo decide cada dominio sobre ese kernel.

Lo que separa esto de cualquier programa de gobernanza tradicional es una palabra: ejecutable. El Shared Kernel no es un PDF colgado en SharePoint que “todos deberíamos respetar”. Es código que la plataforma ejecuta cada vez que entra un dato. La regla que dice “el NIF de un cliente español tiene que pasar el algoritmo de validación oficial” no vive en una guía de buenas prácticas que algún día alguien revisa: vive pegada al Hub Cliente y se ejecuta en cada carga. Si llega un dato que no la cumple, no entra. Si entra una variante nueva — un identificador de un nuevo régimen jurídico —, el sistema lo detecta y obliga a refinar la regla. (Vuelvo a esto en el Eje 4.)

Eso — un Shared Kernel ejecutable — es exactamente lo que Zhamak Dehghani identificó como cuarto pilar de Data Mesh: la gobernanza federada y computacional, hecha código.

Recordemos los cuatro pilares que ella describió hace años: dominios dueños del dato, dato como producto, plataforma de autoservicio, y gobernanza federada y computacional. La pregunta más operativa que el modelo ha tenido que contestar desde el día uno cae justo sobre ese cuarto pilar: “¿cómo se federa una gobernanza sin que cada dominio reinvente las reglas? ¿Cómo se computa una gobernanza sin que la plataforma se convierta en un cuello de botella central?” La respuesta concreta — la que se puede implementar el lunes que viene — es la que estamos viendo: un Shared Kernel ejecutable que la plataforma garantiza por construcción y los dominios extienden con sus Satellites.

Aquí cae también una pregunta que varios habéis dejado en los comentarios, sobre identidad canónica y proyecciones contextuales: ¿hay un único cliente, o hay muchos? En el modelo lo resuelve la separación Hub / Satellite: hay un único cliente — el del Hub canónico, identificado por la cadena entera con la misma clave. Y hay muchas proyecciones de ese cliente — la que ve Pólizas, la que ve Siniestros, la que ve Marketing —, cada una en su Satellite. La identidad es una. La descripción es contextual. Esa simetría es la que hace que la cadena no se rompa en silos.

Y aquí cierra el círculo de hoy: Data Vault 2.0 es, por construcción, ese Shared Kernel ejecutable. La identidad común vive en los Hubs. Las descripciones contextuales viven en los Satellites. La carga paralela está integrada de fábrica. La trazabilidad es estructural, no una capa añadida. Cuando a un modelo le pides exactamente esas tres cosas — identidad compartida, paralelismo, memoria que no se borra —, has descrito Data Vault 2.0 sin saberlo. Y que ese kernel sea ejecutable — código vivo, no PDF — es lo que cierra el círculo.

“La gobernanza federada y computacional que describió Zhamak tiene un nombre técnico: Data Vault 2.0. La franquicia, en arquitectura.”

Eje 4 — Documentación viva: la regla que no puede envejecer en silencio

Llegamos a la pieza que más se malentiende. Una sola frase la define: la regla es código, el código se ejecuta cada día contra la realidad, y cuando la realidad cambia, el sistema lo detecta antes de que nadie lo busque.

Pantalla con alerta de filas fuera del catálogo y pizarra ampliando el catálogo a COOPERATIVA
La regla aprende cuando la analista valida el valor legítimo; el PDF envejece en silencio.

Volved al almacén de Objectville. El Hub Cliente lleva pegada una regla: “El catálogo conocido del campo tipo_cliente registra los valores PARTICULAR, EMPRESA y AUTONOMO. Cualquier valor fuera del catálogo se inserta con flag de revisión.” Esa regla no es una nota en una guía. Es código. Se ejecuta cada vez que entra un dato.

Un martes cualquiera llegan dos filas con tipo_cliente = 'COOPERATIVA' — valor fuera del catálogo. La regla las marca. Una operadora ve la alerta. Llama al dominio de origen. “Es legítimo — la asesoría acaba de incorporar el régimen cooperativo.” Se amplía la regla, se versiona, se despliega. El flag se levanta. La cadena nunca se rompió.

Eso es la semilla. La diferencia entre esta alerta y el PowerPoint que envejece en silencio durante dos años hasta que llega un auditor — y todo lo que la plataforma hace para que no puedas ignorarla — es lo que aterrizo la semana que viene.

Lo que viene

¿Qué pasa cuando llega un dato malo, malo de verdad? No el caso legítimo del Eje 4 — el régimen nuevo que la asesoría acaba de incorporar. Eso es evolución, se resuelve refinando la regla. Hablo del proveedor que cambia su esquema sin avisar y manda basura. Del campo obligatorio que llega vacío. De la business key que aparece duplicada porque alguien metió la pata. ¿Dónde van esos datos? ¿Cómo se rechazan sin perder la traza de que llegaron? ¿Quién decide qué cuenta como dato bueno cuando hay cuarenta sedes y un solo contrato común?

La respuesta no se monta encima del modelo — es una propiedad del modelo. Hoy la he sembrado al pasar al hablar de reglas que se ejecutan en cada carga. La semana que viene la abro en serio.

Os dejo el giro con una imagen concreta: un camión de proveedor llega un martes con cinco mil litros de tomate triturado que nadie pidió, mezclados con la mercancía buena del pedido. Lote MZ-7842-IT. Proveedor BLUE-LINE. ¿Lo devuelves? ¿Lo dejas en cuarentena con etiqueta visible? ¿Lo aceptas con marca de “rechazado” para que dentro de seis meses puedas reconstruir qué pasó? La respuesta no es una. Son tres severidades distintas, una doctrina firmada hace dos décadas, una pieza concreta del modelo que sostiene la huella, y un chef que prueba el plato cada día.

Hasta la semana que viene.