Arbolito
- React
- Vite
- NestJS
- Prisma
- PostgreSQL
- Socket.io
- Turborepo
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
¿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).
¿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.

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

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_PERCENTrecalculados por cron cuando cambia la cotización

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

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

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






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.