Saltar a contenido

ADR 025: Composición por caso de uso (patrón producto ensamblado)

Estado

Aceptado — 2026-07 (reclasificado: decisión de producto, no SPI de plataforma)

Relacionado con ADR 023, ADR 024 y ADR 021.

Contexto

Cortex HIVE es una plataforma genérica para ensamblar productos (unosportclub, coworking, etc.) mediante plugins instalables. El SPI (requires, optional_requires, provides) vive en cortex-core; el framework valida descriptores en boot (validate_plugin_dependencies) sin conocer grafos de producto.

core/cortex_core/plugin_graph.py expone solo tipos genéricos (PluginGraphNode, BundleProfile) y utilidades (transitive_requires, validate_bundle_closure, detect_requires_cycles). No contiene PLUGIN_GRAPH ni perfiles de UnoSportClub.

Esta ADR fija el patrón de ensamblado (paquete products/* como extensibilidad esperada, grafo, bundles, CI). El loader no lee composition.py en runtime. Los verticales concretos se documentan en casos de uso:

  • Reservassandbox PMV en cortex-product-unosportclub (UnoSportClub); valida el framework hacia el PMV, no producto comercial terminado.
  • Proptech — diseño desde PropTech Platform.

Documentación: casos-de-uso/ (Reservas, Proptech).

Árbol por capas

Capa Plugins
Fundación clients, resources, payments, discounts
Catálogo pricing
Operaciones booking, sales
Extensión events, store, subscriptions
Finanzas accounting, billing
Plataforma ai-agents

Grafo de dominio (caso Reservas — UnoSportClub)

Fuente machine-readable: products/unosportclub/cortex_product_unosportclub/composition.py (REFERENCE_GRAPH).

plugin_id requires (hard) optional_requires provides
clients clients
resources resources
pricing resources pricing
booking resources clients, pricing, payments, discounts booking
payments payments
sales clients, payments pricing, discounts sales
events booking, clients sales events
discounts discounts
accounting payments, sales accounting
store sales store
subscriptions clients payments subscriptions
billing clients payments, accounting billing
ai-agents booking, clients, payments ai-agents

Leyenda:

  • requires: boot falla en CORTEX_PLUGIN_DEPS=strict si el proveedor no está enabled.
  • optional_requires: el plugin carga; UI y flujos consultan capabilities y degradan (patrón reservation-flow).
  • provides: capability indexada en GET /api/v1/control/capabilities.

Namespaces UI vs plugins de dominio

Los namespaces operations y admin son generativos (mecanismo de plataforma): el framework los materializa con ensure_panel() cuando plugins habilitados registran módulos con ese panel_id.

La convención de qué módulos van en cada namespace para el caso Reservas (UnoSportClub) es decisión del caso de uso — ver bundles.

panel_id Origen Rol (sandbox Reservas — ilustrativo)
operations Generativo Operación diaria
admin Generativo Parametrización y finanzas
accounting Plugin + cortex.panels Contabilidad — módulo home (resumen) + ledger (operación vía register_resources)
control Framework embebido Plataforma (siempre activo)
trainer Plugin dedicado Portal entrenador

Un producto ensambla pip extras del paquete cortex-product-unosportclub + plugins activos en state store.

Integración permitida

Mecanismo Uso
HTTP /api/v1/{namespace} Lectura/escritura entre dominios
Capabilities API UI condicional y degradación graceful
Events / listeners (ADR 021) Reacción desacoplada (ej. booking.confirmed → accounting)
MCP tools Agentes y automatización

Prohibido: import Python entre paquetes cortex_plugin_* de distintos plugins.

Recetas de producto (bundle profiles)

Definidas en BUNDLE_PROFILES del paquete cortex-product-unosportclub:

Perfil Propósito
operations-core Operación diaria: clientes, recursos, reservas, pagos, tarifas
operations-full operations-core + descuentos + eventos
admin-finance Finanzas admin: clientes, recursos, pagos, tarifas, ventas, facturación
sports-club-full Producto deportivo completo (perfil de referencia)
coworking-minimal Segundo producto demo: solo recursos + reservas (genericidad)

Extras pip: pip install "cortex-product-unosportclub[sports-club-full]". El meta-paquete cortex re-exporta alias deprecados (cortex[operations-core]).

Activación en caliente y paneles host

Los paneles dedicados (accounting, trainer, …) registran en boot:

  1. configure_panel() → módulo home (y metadata del shell).
  2. register_resources() → módulos operativos (ej. ledger en Contabilidad).

Si el superadmin activa el plugin sin reiniciar el API, activate_pending_plugins() debe repetir el paso 2 (y register_forms si aplica). De lo contrario el panel muestra solo Inicio en el sidebar. Implementación: framework/cortex_framework/control/runtime_activation.py.

Validación

Capa Qué valida
CI products/unosportclub/tests Descriptores == REFERENCE_GRAPH; bundles cerrados; sin ciclos; sin imports cruzados
Boot validate_plugin_dependencies requires hard según CORTEX_PLUGIN_DEPS (framework, agnóstico de producto)
Boot (warn) optional_requires ausentes — log, no fail
Hot enable panel host register_resources + register_forms vía activate_pending_plugins

Consecuencias

  • Nuevo plugin en caso Reservas: actualizar REFERENCE_GRAPH, descriptor, tests de composición y dependency-contracts.
  • Segundo producto (coworking-minimal) demuestra que UnoSportClub no es blueprint de arquitectura de plataforma.
  • accounting y billing pueden evolucionar hacia integración por events sin requires circular.