← Volver a proyectos

Arbolito

Full-stack · producto en dupla con un diseñador UI/UX
Ubicación difusa por privacidad: coordenadas ofuscadas de forma determinística (SHA-256, radio 300m); la posición exacta recién se revela al aceptar el intercambio
Cotización del blue con circuit breaker sobre Bluelytics (CLOSED/OPEN/HALF_OPEN), caché en memoria con fallback a Postgres y flag de staleness
Máquina de estados de solicitudes con creación transaccional (solicitud + conversación + mensaje), chat bloqueado hasta la aceptación y expiración por cron

P2P · USD/ARS · Argentina

El “Tinder” del dólar blue: ves ofertas cerca tuyo con la cotización del momento, mandás una solicitud por el monto que querés y, si te aceptan, se abre el chat para coordinar el cambio.

USD / ARS 1.482,00/1.515,00 cotización en vivo — el ancla de cada pantalla
Feed de ofertas cercanas con la CurrencyPill en vivo

¿Qué problema resuelve Arbolito?

En Argentina el dólar informal —el “blue”— se cambia todos los días en efectivo, cara a cara, a través de arbolitos y cuevas. Es un mercado enorme que vive en grupos de WhatsApp, recomendaciones y confianza a pulso: no sabés bien a quién le estás por comprar, ni a qué precio real, ni si el encuentro es seguro.

Arbolito nació de una pregunta simple: ¿y si ese intercambio tuviera la claridad de una app de fintech y la mecánica de descubrimiento de una app de citas? Ver ofertas cerca tuyo, con la cotización del momento, la reputación de la contraparte y un canal para coordinar — sin exponer tu identidad ni tu ubicación hasta que hay acuerdo.

¿Cómo se construyó Arbolito?

Arrancamos por la identidad. Con mi socio diseñador definimos un sistema de diseño completo antes de escribir producto: la estética de “cueva” —navy profundo, verde menta, elevación por color en vez de sombras, números en tabular-nums— y el elemento de firma, la CurrencyPill que mantiene la cotización viva en el header de cada pantalla.

Sobre esa base construí el producto de punta a punta: un monorepo Turborepo con una API en NestJS y una PWA en React, tiempo real con Socket.io, y una capa de módulos por dominio (ofertas, solicitudes, chat, geo, KYC, reviews, notificaciones).

Por qué quedó en prototipo. En paralelo hicimos el análisis legal del modelo. La conclusión fue que operar un marketplace de cambio informal nos metía en una zona regulatoria que, como side project de dos personas, no podíamos ni queríamos sostener. Decidimos frenar antes de publicar y dejarlo como prototipo funcional. Fue la decisión correcta, aunque duela: el producto está terminado a nivel diseño y arquitectura, y eso es lo que muestra este caso.

¿Qué decisiones técnicas tiene Arbolito bajo el capó?

Las decisiones que hacen a Arbolito no están en la lista de features, están en los detalles. Estas son las que más me importan.

Detalle de oferta con cotización y botón Solicitar
Confianza y seguridad

Ubicación difusa por privacidad

Cambiar efectivo implica encontrarse con un desconocido. Por eso la ubicación exacta de cada oferta nunca se expone: se ofusca del lado del servidor y la posición real recién se revela cuando la contraparte acepta el intercambio.

  • Coordenadas ofuscadas de forma determinística con SHA-256 sobre el id de la oferta
  • Desplazamiento uniforme dentro de un radio de 300 m (distribución con √ para no concentrar en el centro)
  • La posición precisa solo la ve el dueño o alguien con la solicitud ya aceptada
Wizard de creación de anuncio, paso precio de venta
La cotización, siempre presente

El blue en vivo, con red de contención

La cotización es el corazón del producto, así que no podía fallar. La traigo de una fuente pública (Bluelytics) detrás de un circuit breaker propio, con caché en memoria y fallback a Postgres. Los anuncios pueden fijar un precio o seguir al mercado con un “±%”, y se recalculan solos cuando el blue se mueve.

  • Circuit breaker propio (CLOSED / OPEN / HALF_OPEN) sobre la API externa
  • Caché en memoria (TTL) → fallback a Postgres → flag de staleness al cliente
  • Precios MARKET_PERCENT recalculados por cron cuando cambia la cotización
Pantalla de envío de solicitud
El match

De la solicitud al chat, como una máquina de estados

La mecánica central es un pedido explícito: mandás una solicitud por un monto y la contraparte acepta o rechaza. Cada solicitud es una máquina de estados (pendiente → aceptada / rechazada / expirada) y su creación es transaccional: solicitud, conversación y primer mensaje nacen juntos o no nacen.

  • Creación atómica de solicitud + conversación + mensaje en una transacción
  • El chat queda bloqueado hasta que se acepta — nada de mensajes en frío
  • Expiración automática por cron y notificaciones event-driven en cada cambio
Chat con tarjeta de solicitud y acciones
Tiempo real

Un chat que se siente instantáneo y no miente

El chat corre sobre Socket.io con autenticación por JWT y una room por usuario. La UI es optimista para que se sienta inmediata, pero cada mensaje espera confirmación del servidor: si falla, se revierte. Y hay un rate-limiter propio para que nadie inunde una conversación.

  • Gateway autenticado con JWT + rooms por usuario
  • Entrega por ACK con rollback del update optimista si el envío falla
  • Rate-limiter propio (5 msg/s) y validación estricta del lado del server
Pantalla de privacidad y visibilidad
Control del usuario

Verificación, visibilidad y bloqueos

En un mercado de confianza, el control es parte del producto. Hay verificación de identidad (KYC) como módulo aislado, controles finos de visibilidad —quién ve tu nombre, tu foto, tus anuncios— y bloqueo de usuarios aplicado a nivel de query, no como filtro cosmético.

  • KYC como módulo desacoplado, listo para enchufar un proveedor automático
  • Visibilidad configurable por campo: todos / solo verificados / nadie
  • Usuarios bloqueados filtrados en la base en todas las consultas relevantes

Recorrido por el producto

Pantalla de ingreso con la marca arbo
Ingreso — la marca “arbo” y el modo demo
Lista de conversaciones con usuarios verificados
Mensajes — solicitudes de cambio y verificados
Mis anuncios con precio atado al mercado
Mis anuncios — precio “Mercado −3%”, activo/pausado
Selector de ubicación sobre un mapa
Ubicación aproximada — arrastrás para ajustar
Pantalla de por qué verificar la cuenta
Verificación — por qué conviene validar la cuenta
Pantalla de configuración de la cuenta
Ajustes — perfil, seguridad y documentos legales

Cierre

Arbolito no llegó a producción, pero llegó a ser un producto real: un sistema de diseño coherente, una arquitectura por dominios y un puñado de decisiones —privacidad de ubicación, resiliencia de la cotización, tiempo real confiable— que resolvían problemas concretos del contexto argentino.

Para mí fue el ejercicio de llevar una idea de punta a punta con un socio de diseño, y también de saber cuándo parar. Lo dejo acá como caso: el código y las pantallas hablan por sí solos.