En vez de darte la típica guía de “cómo construir un MVP en 4 semanas”, te voy a contar lo que pasó de verdad cuando construí un MVP para un cliente real hace 3 meses. Con timestamps, con problemas que surgieron, con decisiones que tomé sobre la marcha, y con lo que el cliente cambió a mitad de proyecto (porque siempre pasa algo).
Es una bitácora. La escribo en pasado para que sepas qué pasó, no qué deberías hacer. Si te sirve como guía, perfecto. Si no, al menos te habrás reído un rato con mis errores.
El proyecto: una app para que un coach de fitness gestione las sesiones con sus clientes, con chat, calendario, y pago integrado. El cliente se llama Marcos, lleva 4 años dando sesiones 1 a 1 en Madrid, y quiere lanzar la app para abrirse a clientes online en LATAM. El MVP tiene que validar si la gente está dispuesta a pagar por sesiones online (no solo en persona).
Stack acordado: React Native + Expo + Supabase + Stripe. Por qué este: lo explico en el post de comparativa de stacks, pero resumido, porque Marcos no tiene experiencia técnica y necesita algo que yo pueda entregar rápido y mantener sin él tener que aprender nada raro.
Presupuesto: 1.800 €, en 2 sprints de 2 semanas. Sin permanencia, pago al final de cada sprint.
Semana 1: setup, auth, primera pantalla (10-14 marzo 2026)
Lunes 10 de marzo, 09:30. Empiezo el proyecto. Reviso el correo con Marcos: me ha enviado 3 PDFs con los flujos de trabajo que quiere en la app, 4 fotos de sus sesiones para usar de mockup, y un link a una app de la competencia que le gusta. Buen cliente: documentación clara desde el día 1.
Lunes 10 de marzo, 10:00-13:00. Setup del proyecto. Expo CLI, TypeScript, ESLint, Prettier, Supabase como backend. Configuro el repositorio en GitHub con la cuenta de Marcos como propietario. Hago el primer commit: “Initial commit”. 3 horas.
Lunes 10 de marzo, 16:00-18:00. Llamada de kickoff con Marcos (vía Google Meet, 1 hora, la mitad en español, la mitad en inglés porque Marcos vivió 3 años en Londres). Le enseño el proyecto base, le explico la arquitectura, le digo qué espero de él esta semana. Me confirma que el calendario de pagos está OK, y que prefiere Stripe Checkout (en vez de la API nativa de Stripe) porque es más simple.
Martes 11 de marzo, 09:00-12:00. Pantalla de login con Supabase Auth. Email + contraseña + magic link. Funciona a la primera (raro, normalmente hay que pelearse con la config de deep links en Expo). 3 horas.
Martes 11 de marzo, 15:00-17:00. Mockups en Figma de las 6 pantallas principales: login, dashboard, calendario de sesiones, detalle de sesión, chat, perfil. Marcos había pedido solo 4, pero al explicarle el flujo me di cuenta de que necesitaba 2 más (sesiones pasadas vs futuras, y ajustes de perfil). 2 horas.
Miércoles 12 de marzo, 10:00-14:00. Base de datos en Supabase. 4 tablas: users, sessions, messages, payments. Las defino con SQL, no con la UI de Supabase, porque es más rápido y más limpio. 4 horas.
Jueves 13 de marzo, problema. Cuando intento conectar la app a Supabase desde el móvil de Marcos (que es Android), falla con un error de CORS. Me llevo 2 horas hasta que me doy cuenta de que el problema es que la URL de Supabase que estoy usando es la interna de Expo, no la pública. Lo cambio, y funciona. 2 horas perdidas que me lascomo.
Viernes 14 de marzo, 11:00-13:00. Pantalla de dashboard con placeholder. La app arranca, se ve, se puede navegar. Le paso captura a Marcos por WhatsApp. Me dice: “perfecto, ¿cuándo puedo probarla en mi móvil?”. Le digo: “el viernes de la semana que viene”. Cierre de la semana 1.
Tiempo total semana 1: 18 horas. Entregable: app base con login, dashboard vacío, 6 mockups, base de datos lista.
Semana 2: calendario de sesiones + detalle (16-20 marzo 2026)
Lunes 16 de marzo, 09:30. Empiezo la semana 2. El sprint es más complejo: pantalla de calendario, detalle de sesión, lógica de reserva y cancelación. Marcos me envió feedback el fin de semana: le gusta el dashboard pero quiere que la pantalla principal sea el calendario, no el dashboard. Es un cambio pequeño, pero importante: le da más protagonismo a las sesiones.
Lunes 16 de marzo, 10:00-13:00. Cambio dashboard por calendario en la navegación. 1 hora. Empiezo con la pantalla de calendario visual con React Native Calendars. 3 horas.
Martes 17 de marzo, todo el día (8 horas). El calendario me está dando problemas: las sesiones pasadas y futuras se mezclan, no se distinguen bien los días con sesión, y el rendimiento baja cuando hay más de 20 sesiones. Me peleo 6 horas con la librería antes de decidir cambiar de librería. Pruebo react-native-calendar-events (la nativa de iOS/Android) + mi propia UI. Mejor rendimiento y más control. 8 horas.
Miércoles 18 de marzo, 09:00-13:00. Pantalla de detalle de sesión: muestra fecha, hora, tipo de sesión (online/presencial), cliente, notas del coach, botón de cancelar. 4 horas.
Miércoles 18 de marzo, 16:00-17:00. Llamada con Marcos (1 hora). Le enseño el calendario y el detalle de sesión. Le gusta, pero me pide un cambio: en vez de “cancelar sesión”, quiere “reprogramar sesión” (que el cliente pueda elegir otra fecha/hora sin cancelar la actual). Es buena idea, le digo que lo añado el viernes. 1 hora.
Jueves 19 de marzo, 09:00-14:00. Pantalla de reprogramar sesión. Modal con selección de nueva fecha/hora, validación de que no choque con otra sesión, confirmación. 5 horas.
Viernes 20 de marzo, 10:00-13:00. Integración de la pantalla de reprogramar con el calendario. Testing manual de los 4 flujos: ver sesión, cancelar sesión, reprogramar sesión, ver sesiones pasadas. 3 horas.
Viernes 20 de marzo, 16:00. Cierre de sprint 1. Le paso la app a Marcos para que la pruebe en TestFlight (iOS) y en Expo Go (Android). Le doy feedback del sprint y de los cambios que pidió.
Tiempo total semana 2: 22 horas. Entregable: app con calendario, detalle de sesión, cancelación, reprogramación, base de datos conectada.
Semana 3: chat + Stripe Checkout (23-27 marzo 2026)
Lunes 23 de marzo. Empiezo sprint 2. Lo más crítico: chat entre coach y cliente, y pago con Stripe Checkout. Si algo falla aquí, el MVP no valida nada.
Lunes 23 de marzo, 09:00-14:00. Pantalla de chat con Supabase Realtime. Lista de conversaciones a la izquierda, mensajes a la derecha, input abajo. La realtime funciona a la primera (Supabase lo hace muy fácil). Lo más costoso: la UI, porque Marcos quiere que el chat se parezca a WhatsApp (burbujas, hora, indicador de “escribiendo…”). 5 horas.
Martes 24 de marzo, todo el día (7 horas). El indicador de “escribiendo…” me está dando guerra. Resulta que Supabase Realtime tiene un canal específico para “presence” que se puede usar, pero la documentación es confusa. Me peleo 4 horas hasta que encuentro un ejemplo funcional en GitHub. Lo adapto, y funciona. 7 horas.
Miércoles 25 de marzo, 10:00-13:00. Integración con Stripe Checkout. Sigo el flujo recomendado: el cliente toca “Pagar sesión” en la app, se abre Stripe Checkout en el navegador (no en la app, por las políticas de Apple/Google), paga, vuelve a la app con la sesión marcada como pagada. Es 1 hora de implementación real + 2 horas de testing con la tarjeta de prueba de Stripe. 3 horas.
Miércoles 25 de marzo, 15:00-16:00. Marcos prueba la app y me da feedback. Todo bien, salvo un detalle: en la pantalla de chat, cuando un cliente nuevo abre la app por primera vez, no ve sus conversaciones porque hay un race condition con la carga inicial. Lo arreglo el jueves.
Jueves 26 de marzo, 09:00-12:00. Race condition arreglado (era un orden de operaciones en el useEffect). Empiezo a hacer onboarding: cuando un cliente nuevo entra por primera vez, ve 3 pantallas de explicación de la app. 3 horas.
Viernes 27 de marzo, 10:00-14:00. Pulido UX: empty states (qué pasa cuando no hay sesiones, qué pasa cuando no hay mensajes), loading states, error states. 4 horas.
Viernes 27 de marzo, 16:00. Cierre de sprint 2. La app está completa: login, calendario, detalle de sesión, reprogramar, cancelar, chat con realtime, pago con Stripe Checkout, onboarding. Le paso la app a Marcos.
Tiempo total semana 3: 21 horas. Entregable: app completa con todas las funcionalidades pedidas.
Semana 4: beta cerrada, bugs, deploy final (30 marzo - 3 abril 2026)
Lunes 30 de marzo, todo el día (7 horas). Beta cerrada con 12 usuarios reales (5 amigos de Marcos, 4 clientes suyos, 3 míos). Les paso la app por TestFlight y Expo Go. Les pido que la usen 3 días y me digan qué falla. 7 horas (de setup + monitoreo).
Martes 31 de marzo, monitorizando. Recibo 8 reportes de bugs en 24 horas:
- 3 personas no podían registrarse (el magic link no llegaba a sus emails corporativos).
- 2 personas veían el calendario en blanco aunque tenían sesiones (bug en el filtro de fechas).
- 2 personas no podían pagar con tarjetas de débito (solo crédito, problema de configuración de Stripe).
- 1 persona tuvo un crash al abrir el chat (error en el componente de Realtime).
Me pongo a arreglarlos todos. 6 horas.
Miércoles 1 de abril, todo el día (8 horas). Continúo arreglando bugs. Además:
- Reescribo el onboarding para que sea más claro.
- Añado un FAQ dentro de la app con las 6 preguntas más frecuentes.
- Mejoro el rendimiento del calendario cuando hay más de 30 sesiones. 8 horas.
Jueves 2 de abril, 09:00-12:00. Testing final. Pruebo la app en 4 dispositivos distintos (iPhone 13, iPhone 15, Pixel 7, Samsung Galaxy S22). Todo funciona. 3 horas.
Jueves 2 de abril, 15:00-17:00. Llamada final con Marcos. Le enseño todo, le explico cómo va a gestionar usuarios, sesiones, pagos desde su panel de Supabase. Le entrego:
- Código fuente en GitHub (con su cuenta).
- App publicada en TestFlight y Google Play Internal Testing.
- 2 horas de formación con él y su assistant.
- Documentación escrita (manual de uso, troubleshooting, FAQ).
- Acceso a mi tablero de Trello con todas las tareas y su estado. 2 horas.
Viernes 3 de abril, 10:00-12:00. Cierre del proyecto. Facturo 1.800 € (los 2 sprints completos). Marcos me dice que está contento y que cuando tenga 50 usuarios activos me llama para el sprint 3 (analytics avanzados, integración con Zoom para las sesiones online, etc.).
Tiempo total semana 4: 26 horas. Entregable: app en producción con 12 usuarios beta, 0 bugs críticos, formación completa.
El desglose de las 4 semanas
| Semana | Horas | Lo entregado | Problemas |
|---|---|---|---|
| 1 | 18 h | App base, login, dashboard, mockups, BD | Cambio de dashboard a calendario |
| 2 | 22 h | Calendario, detalle, reprogramar | Cambio de librería de calendario (6h) |
| 3 | 21 h | Chat realtime, Stripe Checkout, onboarding | “Escribiendo…” (4h) |
| 4 | 26 h | Beta con 12 usuarios, bugs, formación | 8 bugs, 14h arreglándolos |
| Total | 87 h | App en producción | 22h de problemas (25% del total) |
El proyecto terminó 7 horas por encima de las 80h que yo había estimado inicialmente. No se lo cobré a Marcos porque era mi culpa por cambiar de librería a mitad de sprint 2. La próxima vez que me pase, lo cobro. Es una lección que aprendí: las horas de debugging entran en el presupuesto, no son “extra gratis”.
A pesar de los problemas, el MVP se entregó en 4 semanas exactas, como acordamos. Marcos validó la hipótesis: 3 de los 12 usuarios beta pagaron por una sesión online en la primera semana. Es un 25% de conversión, brutal para un MVP. La app sigue en producción y Marcos está gestionando 8 clientes online con ella a día de hoy.
Lo que aprendí de este proyecto (y que aplico a todos)
- Reserva siempre un 20% extra de horas para bugs y problemas. Si las usas, las cobras. Si no las usas, son tuyas. Pero que estén en el presupuesto desde el día 1.
- Documenta cada cambio del cliente que afecte al alcance. Yo lo hago por email después de cada llamada. Esto evita discusiones a final del proyecto.
- No cambies de librería a mitad de sprint si puedes evitarlo. Me costó 6 horas que no deberían haber sido necesarias.
- El sprint 4 siempre es el más caro porque es cuando aparecen los bugs reales de uso. Presupón esto desde el día 1.
- El onboarding con beta testers reales es lo que de verdad valida el MVP, no el código en sí. 12 beta testers te dan más información que 1.000 horas de testing interno.
Si quieres aplicar este mismo enfoque a tu MVP, escríbeme a landinowebs@gmail.com o por WhatsApp. Te paso presupuesto cerrado sprint a sprint. Sin permanencia, sin compromiso.
Y si quieres ver el caso completo de la app de la Clínica Pepa Ramón (que es un proyecto más grande y más serio), lo tienes aquí: Clínica Estética Pepa Ramón — caso de estudio.