Role
Fundador · Product engineer · Diseñador · Operador
Year
2024 – presente

Nexo Barber

SaaS multi-tenant para barberías independientes en Costa Rica. Reservas públicas, cola en vivo, dashboard del dueño y PWA, diseñado y shippeado de punta a punta.

  • Next.js 16
  • React 19
  • TypeScript
  • Supabase (Postgres, Auth, Storage, Realtime)
  • TailwindCSS v4
  • Framer Motion
  • Vercel
  • Sentry

Resumen

Nexo Barber es un SaaS mobile-first que ayuda a las barberías independientes a reemplazar el flujo de “cuaderno + WhatsApp” con una sola plataforma: los clientes reservan en línea, los walk-ins entran a una cola en vivo, los barberos ven su día y los dueños operan el negocio desde un único dashboard. Cada barbería tiene su propio subdominio, branding, horario y programa de lealtad, todo sobre un backend multi-tenant en Supabase.

Diseñé el producto, escribí el código, monté la infraestructura, defino el roadmap y atiendo el soporte. El trabajo cubre todo el stack: UI, design system, API, base de datos, políticas de RLS, push notifications, observabilidad, billing y DevOps.

El problema

Las barberías independientes operan con piezas sueltas: un cuaderno para las citas, un grupo de WhatsApp para el equipo, Google Calendar para el dueño y nada del lado del cliente. Las reservas se duplican. Los walk-ins se pierden. Los dueños no pueden ver los ingresos del día sin hacer cuentas a mano. Las herramientas off-the-shelf (Calendly, Square) son demasiado caras, demasiado genéricas o están construidas para otro mercado.

La apuesta de Nexo: un producto enfocado, diseñado para la realidad operativa de un país, que cuesta menos de lo que la barbería pierde con una sola cita no asistida por semana.

El enfoque

Tres audiencias, un solo producto:

  1. Clientes reservan un servicio desde un sitio público en <barberia>.nexocr.pro, siguen una cola en vivo con seis estados (countdown → “sos el siguiente” → “es tu turno” → completada) y tienen un perfil con su historial y progreso de lealtad.
  2. Barberos ven su día en una vista mobile-first “Mi día”: citas, walk-ins y huecos, todo en una sola columna.
  3. Dueños tienen un dashboard por día, semana y mes que cubre ingresos, tracking de no-shows, servicios, equipo, clientes, programas de lealtad, anuncios y manejo de suscripción.

Todo es mobile-first. La app web es una PWA: instalable en la pantalla de inicio, funciona offline para la data ya cacheada y envía notificaciones push cuando se abre un espacio o llega el turno.

Arquitectura

Un tour corto por las partes que más pensamiento llevaron:

  • Data multi-tenant con Row-Level Security. Un único schema de Postgres aísla la data de cada barbería a nivel de fila vía RLS de Supabase. Las políticas se escriben evitando patrones auto-referenciales (que disparan recursión infinita la primera vez que haces JOIN sobre tu propia tabla de verificación). Cada request corre bajo el JWT del usuario; no existe camino de superusuario desde el cliente.
  • Routing por subdominio. Un middleware de Next.js lee el host del request, lo resuelve a una barbería y reescribe la URL para que el mismo App Router sirva a todas. Las rutas reservadas (/api, /auth, /_next, /track) se saltan el rewrite del subdominio para no romper SSE, OAuth ni internals de Next.
  • Cola en tiempo real. Tanto el tracking del cliente como la vista “hoy” del dueño se suscriben a canales de Supabase Realtime filtrados por business_id. Las transiciones de estado (reservada → llegó → en servicio → completada) se propagan a cada cliente activo en menos de un segundo.
  • PWA con push. Un service worker maneja el prompt de instalación, los fallbacks offline para la página de reservas y las notificaciones Web Push para actualizaciones de cola y recordatorios.
  • Observabilidad sin ruido. Los errores se categorizan en el momento de captura: fallas de validación, fallas de RPC, resultados esperados de negocio (rate-limited, suscripción expirada) y errores realmente inesperados. Solo la última categoría dispara alerta; el resto se queda en logs estructurados. Esa fue la diferencia entre “200 pings de Sentry al día” y “una alerta que realmente importa”.
  • Disciplina de zona horaria. Vercel corre en UTC. Costa Rica no. Toda ruta de API que filtra por día o mes calcula su rango usando intervalos UTC semi-abiertos derivados de la zona local de la barbería, nunca la del servidor. El CI bloquea los patrones peligrosos. Esto eliminó toda una clase de bugs tipo “la cita de las 7 pm desapareció”.

Funciones destacadas

El producto está construido alrededor de dos audiencias con necesidades muy distintas: el cliente reservando desde el sitio público de la barbería y el dueño operando su negocio desde un dashboard. Las dos vistas comparten un design system mobile-first, el dark mode por default y el mismo backend en Supabase.

Flujo público de reservas

Cuatro pasos, sin necesidad de crear cuenta para llegar al final. Diseñado para sentirse tan fluido como pedir comida.

Paso uno de la reserva: lista de servicios con precios, con el nombre de la barbería y su estado abierto al inicio.
01. Elegir un servicio
Paso dos de la reserva: selector de barbero arriba, carrusel de fechas debajo, slots de horario divididos en Mañana / Tarde.
02. Elegir barbero, día y hora
Paso tres de la reserva: formulario de contacto con placeholders de teléfono seguros y opción de OAuth con Google.
03. Dejar nombre y teléfono

Espacio del dueño

Citas de día, semana y mes, ingresos, tracking de no-shows, manejo de equipo, servicios, clientes, lealtad, anuncios y suscripción: todo en un layout mobile-first que corre desde cualquier teléfono.

Dashboard del dueño con las citas e ingresos del día, más un link compartible al sitio de reservas.
Inicio del dueño
Calendario de citas del dueño en vista semana, con desglose día por día y filtros en pills.
Calendario semanal
Navegación lateral con secciones de Operación y Crecimiento: servicios, citas, equipo, clientes, bloqueos, gastos, analítica, lealtad, anuncios.
Amplitud total de funciones
Vista de manejo de servicios con categorías, buscador y lista mostrando precio, duración y cantidad de reservas.
Manejo de servicios

Decisiones que vale la pena compartir

Algunas elecciones que no se ven en los screenshots.

01

Baseline mobile Apple-HIG

Touch targets de 44 px, bottom sheets para cualquier contexto tipo overlay, filas swipeables para acciones destructivas, header sticky de dos filas en las vistas de calendario y KPIs en texto inline (no en cards). El producto se siente nativo porque eligió las convenciones de una sola plataforma y se comprometió con ellas.

02

Restaurar el estado de la reserva tras OAuth

Bug sutil pero de alto tráfico: cuando un usuario se loguea a mitad de una reserva, restaurar el flujo tiene que degradar el paso si el horario ya no es válido. La página hoy lleva un invariante en runtime que auto-corrige el estado en vez de renderizar una pantalla en blanco.

03

Reglas operativas enforced del lado del servidor

Los guards de UI no alcanzan. Reservar, cerrar, ofertas vencidas: cada transición de estado pasa por un check server-side, escrito asumiendo un cliente hostil.

04

Gates de CI para los patrones que muerden

lint:tz bloquea todo código nuevo que trate los bordes día/mes en tiempo de servidor. lint:adapter agarra lecturas de columnas JSONB sin el adapter canónico. Ambas reglas se sumaron el día después del bug que previenen.

Qué optimizo

El producto opera con presupuesto ajustado (tanto en plata como en entropía de diseño). Las constraints que defiendo, en orden:

  1. Velocidad mobile. Core Web Vitals primero. La pantalla de inicio y el flujo de reservas son las únicas rutas donde no acepto regresiones bajo ningún concepto.
  2. Seguridad multi-tenant. Cada feature nueva pasa revisión de impersonación y aislamiento por tenant. Prefiero shippear una feature con una semana de atraso que shippear una que filtre data.
  3. Claridad para el operador. Los dueños no son ingenieros. Cada pantalla tiene que cerrar en tres segundos, o está mal.
  4. Rigor de diseño. Apple-HIG es el piso, no el techo. El producto compite con apps que la gente ya quiere.

Stack

  • Next.js 16 (App Router)
  • React 19
  • TypeScript (strict)
  • Supabase Postgres
  • Supabase Auth
  • Supabase Storage
  • Supabase Realtime
  • Row-Level Security
  • TailwindCSS v4
  • Framer Motion
  • Resend (correo transaccional)
  • Web Push (VAPID)
  • Service Worker / PWA
  • Vercel
  • Sentry
  • pino (logging estructurado)
  • Vitest + Playwright
  • Cloudflare DNS

Dónde mirar

Producto en vivo: barberapp.nexocr.pro. ¿Querés una demo guiada o un write-up técnico más profundo? Escribime a bryn.acuna7@gmail.com.

← Todos los proyectos