Proyecto personal en desarrollo activo Ingeniería de Software & Arquitectura Backend

Bid2Drive — Diseño y desarrollo de una plataforma de subastas de vehículos

Proyecto de ingeniería centrado en los desafíos de concurrencia en tiempo real, fiabilidad y orquestación asíncrona de eventos requeridos para subastas automovilísticas seguras y auditables.

Tipo de proyecto Proyecto de Ingeniería Personal
Áreas clave Concurrencia, Transacciones, Asincronía, Pagos
Stack tecnológico Django REST, Nuxt/Vue 3, PostgreSQL, Redis, Celery, Stripe, Webhooks, WebSockets, GitHub Actions, Docker
Estado Prototipo funcional en fase de desarrollo activo
bid2drive_architecture_spec.json
01

Frontend Reactivo

Nuxt 3 / Vue con actualización reactiva de contadores de subasta y WebSocket streams para pujas en directo.

→
02

API Gateway & Atomic Locks

Django REST Framework procesando pujas dentro de bloques select_for_update() para serializar colisiones.

→
03

Async & Escrow

Celery Beat gestionando la cuenta atrás con prórroga anti-snipping y Stripe reteniendo fondos de garantía.

Diagrama de flujo transaccional y prevención de condiciones de carrera

Las subastas de vehículos de ocasión presentan una complejidad técnica singular: a diferencia del comercio electrónico convencional donde el inventario es estático, en una subasta el precio, el adjudicatario provisional y el tiempo restante fluctúan segundo a segundo.

El problema crítico en estos entornos es la integridad concurrente: cuando múltiples usuarios pujan en el último segundo por un vehículo de alto valor, un sistema sin sincronización estricta corre el riesgo de registrar dos pujas con el mismo importe o validar una puja posterior al cierre formal.

Bid2Drive nace como proyecto personal con el objetivo específico de profundizar en este problema de ingeniería: diseñar una arquitectura capaz de manejar pujas de alta frecuencia, resolver condiciones de carrera en base de datos y coordinar eventos temporales asíncronos con fiabilidad absoluta.

Al tratarse de un proyecto personal en desarrollo, asumo el diseño de arquitectura y la implementación técnica de extremo a extremo:

  • Modelado de base de datos relacional: Definición de modelos en PostgreSQL para usuarios, subastas, vehículos, historiales de puja y registros de auditoría inmutables.
  • Lógica transaccional de puja: Implementación del motor de pujas en Django con serialización estricta de transacciones y cálculo dinámico de incrementos mínimos.
  • Infraestructura asíncrona: Configuración de Redis como broker y caché de estado en memoria, junto con workers de Celery para planificar cierres de subasta y extensiones dinámicas de tiempo.
  • Integración con pasarela Stripe: Diseño de un flujo de pre-autorización de fondos (hold de tarjeta) que garantiza que un usuario cuenta con saldo suficiente antes de pujar, liberando la retención si es superado.
  • Cliente web prototipo: Creación de una interfaz reactiva en Nuxt / Vue para la monitorización en vivo del catálogo de vehículos y el tablero de pujas.

Cada decisión de arquitectura en Bid2Drive estuvo guiada por priorizar la consistencia frente a la velocidad superficial:

Base de datos: PostgreSQL con bloqueos sobre bases de datos NoSQL

Aunque bases NoSQL como MongoDB ofrecen inserciones rápidas, carecen de las garantías ACID estrictas que exige un flujo monetario. En PostgreSQL, el uso de select_for_update() permite bloquear a nivel de fila la subasta mientras se valida y persiste la nueva puja más alta, garantizando coherencia absoluta.

Temporizadores: Celery + Redis sobre bucles de consulta activos (polling)

Consultar la base de datos cada segundo para comprobar si una subasta ha expirado colapsa las conexiones con miles de usuarios. Mediante tareas programadas de Celery con cuentas atrás (countdown) o tareas diferidas (ETA), el cierre se ejecuta de forma desacoplada y eficiente.

Seguridad financiera: Pre-autorización diferida (Separate Auth & Capture)

En lugar de cobrar inmediatamente o confiar en cobros posteriores al cierre, se utiliza la API de PaymentIntents de Stripe en modo manual (capture_method='manual'). Esto retiene una fianza temporal que disuade de ofertas falsas y evita costes de devolución.

Reto 1

El problema del "Snipping" en el último segundo

Problema: En las subastas online, los usuarios suelen esperar a los últimos 3 segundos para lanzar su puja, impidiendo que otros compradores puedan reaccionar y desvirtuando el valor real del vehículo.

Solución: Implementación de una regla de "prórroga automática" (Soft Close): si se registra una puja válida dentro de los últimos 2 minutos de la subasta, la tarea de Celery amplía automáticamente el tiempo de cierre en 2 minutos adicionales y notifica a los participantes.

Reto 2

Concurrencia extrema y prevención de condiciones de carrera

Problema: Dos compradores pulsan el botón de puja a 15.000 € en el mismo milisegundo. Ambas peticiones leen el estado actual (14.500 €) como válido y ambas intentan registrar 15.000 €.

Solución: Encapsulación del procesamiento dentro de una transacción atómica (@transaction.atomic) y bloqueo exclusivo de la fila de la subasta. La primera puja se procesa y actualiza el precio a 15.000 €; la segunda lee inmediatamente el nuevo precio y se rechaza limpiamente con un error explicativo.

Como proyecto de ingeniería en desarrollo activo, los resultados se evalúan en base a robustez arquitectónica y pruebas de carga internas:

100% ACID Cero inconsistencias en pruebas de concurrencia
Soft Close Mecanismo anti-snipping probado con Celery
Auth & Capture Flujo de depósitos con Stripe operativo

El prototipo funcional valida que la arquitectura elegida soporta la operativa completa de subastas vehiculares: creación de lotes, inspección de características técnicas de los coches, gestión de depósitos de garantía y liquidación automática tras el martillazo final.

El desarrollo de un sistema de subastas exige pensar en fallos desde el primer día. Las principales conclusiones de este ejercicio técnico son:

  • Adopción temprana de WebSockets dedicados: En las primeras pruebas el refresco se basó en peticiones periódicas cortas (short-polling). Migrar a un canal WebSocket bidireccional (vía Django Channels o un broker ligero) reduce drásticamente el consumo de red en el cliente y la carga en el servidor.
  • Auditoría inmutable de eventos (Event Sourcing): En entornos transaccionales donde se mueven sumas elevadas, guardar solo el estado actual es insuficiente. Diseñar un registro inmutable append-only donde cada puja y cada cambio de estado quede sellado con timestamp es fundamental para resolver disputas entre pujadores.
  • Simulación de latencias de red variables: Probar la concurrencia en local no reproduce los 150ms de latencia que puede experimentar un usuario en red móvil 4G. Es crucial introducir retardos artificiales en los tests para certificar que la experiencia de usuario se mantenga justa y predecible.
Proyecto Anterior

AI PLAN — Del concepto a la calle

Experiencia como cofundador construyendo y comercializando una plataforma de ocio integral.

Ver proyecto AI PLAN