Skip to main content
Estado: Propuesto · Fecha: 2026-08-17 · Supera: DEC-H2 · Refs: OQ-LOY-07, ADR-011, ADR-016
Traducción. Autoritativo: ../../adr/adr-021-multi-program-from-day-one.md.

Contexto

DEC-H2 decidió que multi-programa sería solo-esquema en F1: program_id en todas las tablas de loyalty desde la primera migración, un programa por defecto auto-creado e invisible para la UI y la API v1, y la capacidad de crear más habilitada después como puro trabajo de UI. El razonamiento era la complejidad de consola: cada pantalla, regla y reporte gana un selector de programa, y ningún design partner lo había pedido. Dos cosas cambiaron esa evaluación, y ambas vienen del owner:
  1. La demanda es probable el día uno, no después. Un holding con dos marcas, una empresa con un programa B2C junto a uno B2B para distribuidores, o una campaña estacional que no debe contaminar el principal son situaciones corrientes. Descubrirlo en la primera reunión comercial y responder “después” es un negocio perdido.
  2. Es una palanca de pricing, no solo una feature. La cantidad de programas es una dimensión de plan natural y honesta: el plan base incluye uno, y necesitar un segundo es una razón concreta para subir de tier. Una capacidad invisible no se puede vender; una visible y limitada genera la conversación de upgrade sola.
El argumento decisivo es la asimetría del arrepentimiento. El costo de esquema ya está pagado — program_id está de todas formas. Lo que DEC-H2 difería era superficie de consola y de API, y esa superficie solo se encarece a medida que se acumulan pantallas. Meter el selector en seis pantallas ahora es más barato que retrofitearlo en treinta después.

Decisión

Multi-programa se entrega como capacidad de primera clase en F1.
  • Un programa es una entidad visible y nombrada por el tenant desde el primer release.
  • Un tenant puede crear, renombrar, activar y desactivar programas por la consola y la Management API, sujeto a un entitlement.
  • program_id se expone en la API pública v1. Cuando un request lo omite, se resuelve el programa por defecto del tenant — así una integración de un solo programa nunca tiene que saber que el concepto existe.
  • Todo tenant sigue recibiendo un programa por defecto creado automáticamente al aprovisionarse, y exactamente un programa por tenant lleva is_default = true.
  • La cantidad de programas es un entitlement, no una métrica medida: el plan declara cuántos incluye, y excederlo se bloquea en vez de facturarse como overage. Un tope duro es la forma correcta para una capacidad que el tenant elige adoptar, no para consumo que genera el comportamiento de sus clientes.
  • La agregación entre programas en reportería queda explícitamente fuera de alcance en F1. Cada programa reporta sobre sí mismo. Agregar abre preguntas reales —de quién son los puntos, en qué moneda, con qué escalera de niveles— que merecen su propia decisión.
  • Un contacto puede tener saldos, niveles y membresías en más de un programa a la vez. Los puntos, niveles y recompensas nunca cruzan la frontera de un programa (ADR-011 sin cambios).

Consecuencias

+ El modelo comercial gana una dimensión de upgrade honesta, que no cuesta nada medir y es fácil de entender para un cliente. + El modelo de dominio calza con lo que muestra la consola, así que no hay un período en que la API esconde un concepto que el esquema ya tiene — la clase de bug donde un identificador “oculto” se filtra por un mensaje de error o una exportación simplemente no puede ocurrir. + Nunca se requiere una migración para habilitarlo, porque el esquema ya era correcto. La superficie de consola crece de inmediato: un selector de programa en las pantallas de loyalty, y alcance por programa en cada reporte. Estimado en el orden de un feature spec adicional, absorbido dentro de la entrega de la propia consola. Todo endpoint de loyalty debe resolver un programa, y todo test de loyalty gana un caso multi-programa. La regla de resolución por defecto mantiene el camino común sin cambios. Las conversaciones de soporte ganan una dimensión más (“¿qué programa?”). Mitigado porque el programa por defecto es invisible en la práctica para tenants de un solo programa.

Trabajo de seguimiento

  • FS-LOY-0001 reescrito: CRUD de programas, nombre visible para el tenant, verificación de entitlement, program_id expuesto en la API.
  • PRD-LOY: multi-programa sale de los no-objetivos; la cantidad de programas entra al modelo comercial.
  • ADR-016: la cantidad de programas se declara como dimensión de entitlement junto a las métricas medidas.
  • Consola: selector de programa, como parte de su propio feature spec.

Alternativas consideradas

Mantener DEC-H2 como estaba — lo más barato ahora, y el costo de esquema ya estaba hundido. Perdió porque el costo diferido es superficie de consola, que crece monótonamente; diferirlo lo hace estrictamente más caro, nunca más barato. Visible y nombrado, pero un solo programa por tenant en v1 — la opción intermedia. Arregla la incomodidad del “concepto oculto” a casi ningún costo, pero deja la palanca comercial sin construir y sigue exigiendo el trabajo del selector después. Optimiza por un ahorro que ADR-021 muestra que es temporal.