Proyecto corporativo · Presentado sin referencias a la empresa: solo arquitectura y decisiones.
Plataforma de Apuestas Deportivas
Pipeline orientado a eventos: recepción, validación y registro de apuestas
Estado
En producción
Rol
Ingeniero backend senior: diseño de servicios y pipeline, handlers de Kafka, motor de límites en vivo, validación y entrega de apuestas en vivo, resiliencia, CI/CD y empaquetado para Kubernetes.
Arquitectura
Recepción y validación desacopladas con Kafka
Motor de límites compartido
Bloqueos por jugador, entrega idempotente a la API en vivo
La apuesta se acepta y se encola. Se revisan los límites y el historial del jugador y luego la apuesta aceptada se entrega a la API de apuestas del motor en vivo, que la inserta en la BD en vivo.
Arquitectura · 7 nodos · 2 flujos
1Front-end de apuestas → API de recepción de apuestasEnviar apuesta (HTTPS)
Servicio / cómputo
Almacén de datos
Cola / mensajería
Cliente
Síncrono
Asíncrono / bucle
Desplázate hacia los lados para ver todo el diagrama
Cómo fluye, paso a paso
Haz clic en un paso para saltar a él. Haz clic en un componente para ver detalles.
Qué hace
Suite de microservicios backend para un operador de apuestas deportivas en línea. Recibe apuestas pregame y en vivo, las valida contra límites del jugador y cuotas vigentes, las persiste en el libro de apuestas y devuelve cada cambio de estado al front-end en tiempo real. Las apuestas en vivo añaden límites con historial revisados bajo bloqueo por jugador y luego una entrega idempotente a la API de apuestas del motor en vivo.
El problema
Una ruta monolítica y síncrona de inserción de apuestas no soportaba los picos de tráfico de eventos, no daba retroalimentación al jugador durante la validación y ataba las reglas de límites a un modelo heredado de procedimientos almacenados, difícil de probar y evolucionar. El operador necesitaba desacoplar recepción, validación y persistencia, mantener orden estricto por jugador e introducir reglas de límites en vivo más ricas sin romper el libro de apuestas heredado.
Qué construí
Diseñé un pipeline desacoplado con Kafka (recepción, validación, inserción) con un flujo de notificación dedicado, de modo que cada apuesta avanza por estados explícitos y el jugador siempre ve el progreso.
Extraje un motor de límites determinista y sin infraestructura como paquete NuGet versionado (límites estáticos más topes por juego con historial y reglas de superación), compartido por la API, el servicio de validación y un nuevo cliente Blazor.
Hice la validación de apuestas en vivo segura ante concurrencia con bloqueos de aplicación por jugador y semáforos acotados para consultas de catálogo, rechazando limpiamente cuando faltan datos de límites o son inconsistentes.
Añadí idempotencia y umbrales de antigüedad (las apuestas obsoletas se rechazan en validación y persistencia), con identificadores de transacción estables propagados en logs estructurados y notificaciones.
Encapsulé la biblioteca heredada de inserción de apuestas detrás de una API HTTP de compatibilidad, de modo que el nuevo pipeline pudo liberarse de forma incremental mientras el libro heredado seguía siendo la fuente de verdad.
Entregué CI/CD multi-entorno: etapas de pruebas unitarias y end-to-end, construcción de contenedores, despliegues con Helm y despliegue paralelo en IIS para componentes alojados en infraestructura heredada.
Decisiones clave y por qué
01
Kafka como columna vertebral entre recepción, validación y persistencia
El desacople permite que la API responda al instante, absorbe picos en días de eventos y deja que cada etapa escale y falle de forma independiente. Los mensajes se particionan por jugador para preservar el orden por cuenta, con commits manuales de offsets y reintentos acotados.
02
Motor de límites como biblioteca pura, no como servicio
Mantener las reglas libres de dependencias HTTP, de base de datos y de Kafka las hace totalmente probables y reutilizables en servidor y navegador. Quien llama aporta una instantánea del historial; el motor solo decide. Las versiones se fijan explícitamente para revalidar juntos los cambios de contrato.
03
Segunda validación autoritativa bajo bloqueo por jugador
Una apuesta en vivo se revalida contra la instantánea de límites más reciente y otra vez bajo un bloqueo por jugador, de modo que apuestas concurrentes no superen en conjunto los topes por juego. El endpoint público de pre-verificación es explícitamente preliminar.
04
Flujo de notificación dedicado que alimenta SignalR
Cada servicio emite los cambios de estado de la apuesta a un solo tópico; un único hub los distribuye a los clientes. Los servicios nunca hablan directo con el front-end, lo que los mantiene sin estado y escalables horizontalmente.
05
Envoltorio estilo strangler sobre la ruta heredada de inserción
Reimplementar años de reglas del libro era más riesgoso que encapsularlas. La biblioteca heredada se aloja tras una API HTTP, dando al nuevo pipeline un contrato estable mientras las reglas se migran funcionalidad por funcionalidad.
06
Clientes HTTP resilientes con timeouts explícitos
Todas las llamadas externas (cuotas, perfil de jugador, API heredada) usan clientes tipados con políticas de reintento, timeout y circuit breaker. Los fallos se traducen en claves de error de negocio explícitas en lugar de pérdidas silenciosas.