# ArquitecturaPlataforma de decisión orientada a eventos, multi-tenant, aumentada con ML — cómo está estructurada.

## Vista general del pipeline

```
Stream-Ingest → Validadores de features → Persistencia
                                             ↓
                                        Bus de eventos (PG LISTEN/NOTIFY)
                                             ↓
                              ┌──────────────────────┐
                              │ Daemon de decisión   │ (config por tenant)
                              └──────────┬───────────┘
                                         ↓
                                    Acción validada
                                         ↓
                                  Feedback de resultado
                                         ↓
                              Entrenamiento / Tuning del modelo
```

La plataforma convierte flujos de datos brutos en decisiones
convergentes a través de un pipeline deliberadamente escalonado.
Cada etapa tiene una única responsabilidad y emite eventos
durables para la siguiente.

## Núcleo orientado a eventos

- **Bus de eventos.** PostgreSQL `LISTEN/NOTIFY` transporta
  eventos entre daemons. Los eventos se persisten en una tabla
  durable, no solo se difunden — los consumidores pueden hacer
  replay desde un cursor tras una reconexión.
- **Entrega at-least-once.** Los consumidores reconocen los
  eventos procesados. Los eventos no reconocidos se reenvían tras
  timeout. La idempotencia es responsabilidad del consumidor.
- **Replay rastreado por cursor.** Cada consumidor mantiene su
  propio cursor. Tras una desconexión, retoma donde paró — sin
  eventos perdidos, sin doble procesamiento más allá de las
  semánticas de reintento configuradas.

## Pipeline ML

- **Modelos.** XGBoost entrenado contra features históricas, con
  ONNX Runtime para inferencia (2–5× más rápido que el framework
  de entrenamiento).
- **Salidas.** Los modelos clasifican regímenes en tres
  dimensiones — dirección, volatilidad, calidad. Sin pronósticos
  puntuales especulativos.
- **Tuning de hiperparámetros.** Optuna con holdout walk-forward,
  oleadas champion/challenger, quality gates.
- **Bucle de feedback.** El resultado de cada decisión se
  registra y se realimenta en la siguiente ronda de tuning.

## Modelo multi-tenant

El aislamiento de tenants se aplica en dos niveles:

- **Stored procedures.** Todas las operaciones del lado del
  tenant pasan por stored procedures que aplican la propiedad.
  Las escrituras directas a tabla por código de tenant no están
  permitidas.
- **Row-level security.** RLS de Postgres como red de seguridad
  dura. Incluso si la lógica de la aplicación tiene un bug, RLS
  impide el acceso a datos cross-tenant.

La configuración por tenant cubre:

- **Claves y rate-limits.**
- **Kill-switch.** Override del operador para desactivar un
  tenant inmediatamente sin redeploy.
- **Perfil de riesgo.** Parámetros de umbral por clase de
  decisión.

## Validadores

Tres lugares donde ocurre la validación:

1. **Antes de la persistencia.** Los eventos de stream que
   fallan la validación se marcan, no se descartan en silencio.
   Los operadores los ven en el dashboard.
2. **Antes del entrenamiento de modelos.** Las features usadas
   para entrenamiento se revalidan contra el esquema. El drift
   dispara una alerta antes de reentrenar.
3. **En tiempo de ejecución.** Los validadores de features
   corren continuamente con auto-recuperación `DATAMISSING` —
   cuando falta una feature esperada, el daemon cae a un default
   documentado y dispara un evento estructurado.

## Observabilidad

- **21 dashboards en vivo.** Heartbeat, latencia, detección de
  drift, distribución de decisiones, volumen por tenant.
- **Logging estructurado.** Consola, fichero y base de datos —
  mismos eventos de log legibles desde los tres con la misma
  query.
- **Monitorización de salud.** Cada daemon emite eventos de
  salud a cadencia fija. Eventos faltantes disparan pages.

## Mecanismos listos para producción

- **Circuit breakers** por fuente de datos — los fallos degradan
  con gracia en vez de cascada.
- **Alerting por email y XMPP** para eventos visibles al
  operador.
- **Defaults universales dirigidos por config.** Mapeos de
  fuentes, cadenas de fallback, conversiones de unidades,
  umbrales — todo en JSON. Sin magic numbers en el código.
- **Aislamiento de procesos** vía tmux + Devuan — los daemons
  se pueden reiniciar individualmente sin coordinación.

## Lo que esto no es

- No es una plataforma de autoscaling estilo Kubernetes. Esto
  corre en un pequeño número de máquinas bien entendidas con
  ubicación deliberada de daemons.
- No es "instalar y olvidarse". Conjuntos de tokens, versiones
  de modelo, configs de tenant y dashboards requieren atención
  del operador.
- No es genérico. La plataforma refleja una clase específica de
  problemas de decisión de alta frecuencia — adaptarla a una
  carga muy distinta es el servicio
  [Desarrollo](/es/services/development/).
