El contrato CustomerCard
Cuadrante 04_EXPLANATION. La forma exacta y actual está en 03_REFERENCE/openapi.json — este documento explica por qué existe, no qué campos tiene.
El problema
Gastro tiene tenants con plan_type. Travel tiene properties con subscription_tier. Gastro
identifica al dueño con founder_email; Travel con una relación a owner. Gastro pagina
distinto que Travel. Ninguna de las dos está mal: cada una habla el idioma de su negocio.
Si el panel hablara los dos idiomas, cada componente tendría un if vertical === 'gastro'. La
tabla, el dashboard, la ficha, los filtros. Y la tercera vertical añadiría un tercer if en
cada uno de esos sitios.
La decisión
Existe un idioma —CustomerCard— y las diferencias se absorben en un sitio: el conector
de cada vertical.
El conector es el único archivo del BFF que sabe que Gastro dice plan_type y Travel dice
tier. Fuera de ahí, un cliente es un cliente.
La prueba está en el frontend: la tabla, el dashboard y la ficha no tienen una sola rama por vertical. Cambiar de Gastro a Travel en la barra lateral no cambia qué componentes se montan — solo de dónde salen los datos.
Queda una rama en todo el panel, en el texto del diálogo de suspender: a un restaurante hay que avisarle que su carta pública dejará de verse. Es una consecuencia real y distinta, y esconderla para que el código quedara simétrico sería peor producto. La regla no es "cero condicionales": es que ningún condicional exista por culpa de cómo la vertical nombra sus columnas.
Qué NO normaliza
extra y detail son la válvula de escape: campos que solo tienen sentido en su vertical
(cuántos productos tiene un restaurante; en qué municipio está un hotel). Van en un diccionario
libre, sin fingir que son universales.
Es una decisión deliberada: forzar products_count dentro del contrato común obligaría a
Travel a devolver null en un campo que para un hotel no significa nada. Un contrato que miente
para verse simétrico es peor que uno con una bolsa marcada como "esto depende de la vertical".
Dónde se rompería
Si un día una vertical no tiene "planes" —cobra por uso, digamos—, plan: str deja de tener
sentido y CustomerCard deja de ser el contrato correcto. Ese sería el momento de partirlo, no
de meter plan: "usage-based" y seguir.
La señal de que hay que revisarlo es esta: cuando un extra empiece a leerse desde la UI con un
if por vertical, el campo ya no es "extra" — es parte del contrato y hay que subirlo, o el
contrato ya no da.