SnoekByte LogoSnoekByte
Caso de estudio · En producción
Plataforma de leads para estudios deportivos locales

De la pantalla en blanco al primer cliente en vivo — en ocho días.

Fit in de Buurt es una plataforma de leads para estudios deportivos locales: landing pages que convierten, un portal para dar seguimiento a los leads llamados, una guía por código postal y la facturación alrededor. Diseño, desarrollo, base de datos, hosting y operación — hecho en solitario.

Ver la plataforma en vivo
Rol
Diseño, desarrollo, base de datos, hosting y operación (solo)
Periodo
Agosto 2026 · 8 días hasta el primer cliente
Stack
Next.js 16 · React 19 · TypeScript · Tailwind 4 · Supabase · Resend · Vercel
En vivo
fitindebuurt.nl

En vivo en fitindebuurt.nl · Row-level security en todo lo privado · Next.js 16, React 19, Supabase

8
días hasta el primer cliente
±33k
líneas de TypeScript (265 archivos)
464
pruebas automatizadas
Live
primer cliente real en producción

El problema

Un pequeño estudio deportivo se anuncia localmente, envía a la gente a su Instagram o a una web genérica, y la pierde ahí. Quien sí responde llega por un DM, un correo o un mensaje; la dueña recuerda en su cabeza a quién debe volver a llamar. Dos días después la mitad está olvidada y el interés se ha esfumado.

Las tres cosas que existen para esto resuelven cada una solo una parte. Un creador de webs entrega una página sin seguimiento. Un CRM es demasiado pesado para alguien con un puñado de leads al mes. Un linktree no da ningún dato. Y todo lo que sí funciona pone los datos personales de sus clientes en un lugar sobre el que ella no tiene control.

En qué se convirtió

Una plataforma que sirve a tres tipos de visitantes a la vez — el deportista, el estudio y el operador.

Para el deportista

La página de inicio es una guía: introduce tu código postal y ve qué estudios, gimnasios, salones y consultas están más cerca, con distancia, reseñas y un botón al sistema de reservas o a la página de leads. Sin cookies, sin cuenta, y sin que guardemos lo que alguien busca.

Para el estudio

Su propia página de leads en nombre.fitindebuurt.nl y fitindebuurt.nl/nombre, construida por bloques y ajustada a su identidad. Quien deja su número aterriza al instante en su portal, con un correo. Ese portal tiene una lista: a quién llamo. Por lead el sistema registra intentos de llamada, permite posponer con una nota, y marcar ganado o descartado.

Para el operador

Un editor donde construyo y publico una página de cliente, estadísticas por versión de esa página, y facturación con suscripciones, numeración, PDF y una tarea cron nocturna.

No hay en ningún sitio un botón de llamada ni un enlace tel:. Esa es toda la idea: un visitante deja sus datos y el estudio llama de vuelta. Así la dueña sabe quién estaba interesado, aunque la llamada no cuaje enseguida.

Cuatro decisiones que definen el proyecto

Decisiones que repercuten en todo el código — y marcan la diferencia entre terminado y hecho a medias.

1

La separación entre clientes está en la base de datos, no en la interfaz

Cada página tiene un dueño. El row-level security en Postgres decide quién ve qué fila; la app no puede saltárselo, yo tampoco. Una suite de pruebas usa las credenciales reales de dos dueños para intentar leer, modificar y borrar los leads del otro. Sin esa prueba en verde, nada sale a producción.

2

El contenido de una página vive en dos sitios, a propósito

La plantilla es un archivo tipado que termina en satisfies LandingPagina — si falta un texto, el build falla. Lo que cambio en el editor se guarda como overlay en la base y se superpone a la plantilla al renderizar. Así conservo las garantías del compilador y puedo cambiar textos sin desplegar.

3

Se publica bajo un nombre, las cifras pertenecen a una versión

Cada publicación es una fila inmutable en pagina_versies. Los contadores diarios recuerdan lo contado por versión, así veo qué dio "Hero más corto" frente a "Promo de verano", y restauro una versión antigua como borrador con un clic.

4

Todo en neerlandés, hasta la base de datos

Las columnas se llaman belpogingen, snooze_tot, weggedrukt_op. Se lee igual para el cliente y para mí, y mantiene corta la distancia entre lo que decimos en una conversación y lo que hay en el código.

Tres partes para destacar

Los lugares donde fue la mayor parte del tiempo de pensar y construir.

El editor de páginas

A la izquierda una vista previa en vivo, a la derecha la página de arriba abajo: un panel por bloque con todo lo suyo. Los textos se editan en la propia vista previa — señalar, clicar, escribir — y un visitante recibe exactamente el mismo HTML. El color de acento vive en una variable CSS; color-mix deriva cinco tonos, así cada bloque encaja con cualquier identidad.

La guía por código postal

Los códigos postales van al servidor de localización del Kadaster (PDOK): abierto, gratis, sin clave. Lo que vuelve se guarda en nuestra propia tabla, un segundo visitante con el mismo código postal no cuesta ninguna petición. Postgres calcula la distancia y solo devuelve estudios que cumplen todas las condiciones. Del visitante no guardamos nada: ni cookie, ni IP.

Facturación

Suscripciones por cliente, borradores automáticos de una ejecución nocturna, una serie de números de factura que no puede saltar, importes en céntimos, IVA por línea y un PDF en almacenamiento. Una factura enviada queda congelada: los triggers de base rechazan cualquier cambio, porque una factura enviada debe mantenerse igual siete años.

¿Necesitas algo así para tu empresa?

Cómo está montado

Un proyecto Next.js sirve a cuatro tipos de visitantes, separados con grupos de rutas: la guía, las páginas de marketing, las landing pages de clientes y la parte con sesión. Los subdominios pasan por proxy.ts, que refresca la sesión de Supabase y bloquea todo tras el login.

CapaElección
AppNext.js 16 (App Router), React 19, TypeScript strict
EstilosTailwind CSS 4, componentes propios, interfaz totalmente en neerlandés
Datos + authSupabase (Postgres, auth, storage), región Fráncfort
ValidaciónZod, en ambos lados y en las variables de entorno
MailResend, cinco correos transaccionales con un diseño
PDF@react-pdf/renderer, facturas en Supabase Storage
HostingVercel, wildcard *.fitindebuurt.nl, tareas cron, preview por push
SecretosDoppler; ninguna clave en el repo
MonitoringSentry, solo en producción
  • Dos tareas nocturnas en Vercel tras un secreto compartido: 06:00 facturación, 04:00 limpieza de solicitudes caducadas.
  • Sin nombres, teléfonos ni correos en logs o mensajes de error, sin direcciones IP en las estadísticas.
  • Los leads se escriben solo en el servidor — el navegador no tiene permiso de escritura en la base.
  • Un lead pospuesto vuelve solo: snooze no es un estado sino una fecha, ninguna tarea en segundo plano que pueda pararse.

Calidad y método

Un comando es la puerta: npm run check ejecuta typecheck, ESLint sin advertencias, Prettier, todas las pruebas unitarias y un build completo. Lo que no pasa no se da por terminado. Husky y lint-staged hacen lo mismo en cada commit, GitHub Actions lo repite en cada push.

QuéAlcance
Código265 archivos, ± 33.000 líneas de TypeScript
Base de datos27 migraciones, 20 tablas, RLS en todo lo privado
Pruebas unitarias412, en 37 archivos
Pruebas de navegador (Playwright)52, en 9 archivos
Plantillas y bloques8 plantillas, 12 bloques reutilizables
Commits94, en ocho días

Las pruebas de navegador hacen lo que hace una persona

Iniciar sesión, captar un lead, posponerlo, apagar un bloque en el editor, publicar y comprobar que la página pública también cambia. Ahí están justo los fallos que typecheck y las pruebas unitarias no ven.

La visibilidad está fijada en cuatro sitios

robots.ts (nombrando veintitrés crawlers de IA), un sitemap que saca las páginas de cliente de la base, un /llms.txt generado con toda la web en markdown, y datos estructurados por tipo de página — nunca más de lo que está en la propia página.

Construido con asistencia de IA, pero no a ciegas

Cada parte se escribió primero como un plan en el repo — por qué, qué fases, qué compromisos — y luego se construyó. Los acuerdos fijos viven en un archivo de reglas que cada sesión lee. Las pruebas, los tipos y el row-level security son el freno.

Dónde está ahora

El sitio funciona, el primer cliente real está en vivo y en la guía, y la facturación está lista para su primera suscripción.

En la hoja de ruta
  • Vista de mapa y páginas de resumen por tipo y lugar
  • Reseñas de Google verificadas
  • Exportación de leads
  • Autenticación de dos factores
  • Pruebas A/B sobre dos versiones publicadas a la vez

De la idea a la plataforma en vivo

Software a medida que perdura.

Una plataforma de leads, un portal, una tienda o una herramienta interna — construido con pruebas, tipos y privacidad como base. Hablemos de lo que necesitas.

Contacto