Proyecto real (no mockup): backend en Node/Express + frontend en React (Vite). Implementa las historias US-01 a US-13, US-27 y US-28 del backlog.
cd backend
npm install
cp .env.example .env
npm run generate-data # ya generado, solo si quieres regenerar el contenido
npm run dev # http://localhost:4000
Verás en la consola: “Modo desarrollo: los correos de acceso se guardan en backend/data-store/emails/ en vez de enviarse de verdad.” — eso es intencional (ver sección de correos abajo).
En otra terminal:
cd frontend
npm install
npm run dev # http://localhost:5173
Abre http://localhost:5173 en el navegador.
http://localhost:5173/?utm_source=tiktok — te manda directo al test
(US-28), no a una landing genérica.backend/data-store/emails/ — ahí queda guardado
el “correo” como si lo hubieras recibido de verdad.| Parte | Estado |
|---|---|
| Login, dashboard, rutina diaria, desbloqueo por día | Real — corre contra el backend, persiste en backend/data-store/db.json |
| Programas de 21 días: 3 niveles (Base / Intermedio / Avanzado) × 3 objetivos (fuerza / resistencia / pérdida de peso) = 9 programas | Real — la experiencia declarada decide el nivel y el objetivo decide el énfasis (ver “Cómo se asigna el programa”). Catálogo de 46 ejercicios con progresiones y alternativa sin barra. Se acortó de 30 a 21 días para respetar el descanso; la Fase 2 (28 días, más intensa) queda pendiente. |
| Recomendación de nivel según experiencia/objetivo | Real, reglas simples (ver backend/src/utils/recommendation.js) — define qué programa recibe cada usuario |
| Test antes de comprar (US-28) para tráfico de anuncios | Real — detecta ?utm_source= y guarda el lead aunque no compre |
| Envío de correo con accesos (US-27) | Simulado — se guarda como archivo de texto en vez de enviarse. Ver abajo cómo activar el envío real. |
| Cobro con Culqi | Simulado — el botón “Pagar” llama directo al endpoint que crea la cuenta, sin pasar por una pasarela real todavía |
| Videos de ejercicios | Temporal — 26 de los 46 ejercicios tienen un GIF de JahelCuadrado/ExerciseGymGifsDB (no siempre muestra la técnica correcta, ver advertencia legal abajo); los 20 nuevos aún no tienen clip y la app muestra un recuadro “VIDEO: NOMBRE”. Se reemplazan por clips propios .mp4. |
⚠️ Lee primero esta advertencia sobre los GIFs — es la más urgente de las cuatro, no la más técnica.
JahelCuadrado/ExerciseGymGifsDB,
servidos vía jsDelivr. Lo revisé y ese repositorio no tiene un archivo
LICENSE — ni ahí ni, que yo haya encontrado, en su README. Sin una
licencia explícita, el default legal es “todos los derechos reservados”:
está bien usarlo así mientras estás probando y desarrollando (que es
exactamente lo que hicimos), pero no es seguro venderlo así sin
confirmar permiso del autor. Antes de aceptar el primer pago real, elige
una de estas:
lista_ejercicios.md) — con contenido que
ya conoces bien, es más manejable de lo que sueles pensar, y te da
control total sobre la calidad y el estilo.<id>.mp4 (o .webm/.mov) en
frontend/public/videos/ — el id es el de lista_ejercicios.md, ej.
flexiones.mp4 — y corre npm run generate-data en backend/. El clip
reemplaza al GIF temporal de ese ejercicio. Si prefieres alojarlos fuera
(un CDN), crea backend/src/data/video-map.json con
{ "flexiones": "https://tu-cdn.com/flexiones.mp4" }. No hace falta tocar
exercises.json a mano (se regenera).Otras tres cosas hay que resolver antes de vender esto de verdad, en este orden:
Correo real: crea una cuenta en un proveedor SMTP (SendGrid, Mailgun,
Resend, o el de tu propio hosting) y rellena SMTP_HOST, SMTP_USER,
SMTP_PASS en backend/.env. El código de utils/email.js no cambia —
deja de escribir el archivo de texto y empieza a mandar correos reales
apenas detecta SMTP_HOST.
POST /api/purchase hoy actúa como si el
pago ya estuviera confirmado apenas alguien pone su correo — eso está
bien para que tú lo prueben, pero nunca debe quedar así en producción
porque cualquiera podría “comprar” sin pagar. Hay que:
email + tarjeta/Yape).backend/data-store/db.json es un archivo plano,
perfecto para probar pero no para producción (no soporta escrituras
concurrentes de verdad). Migrar a Postgres/MySQL es directo porque el
“shape” de los datos ya está definido en backend/src/db.js.Cada persona recibe uno de 9 programas de 21 días, que siempre arranca en el día 1:
Todo sale de backend/src/data/generate-data.js (3 programas escritos a mano + las
reglas del objetivo) y queda en programs.json. Para ajustar contenido: edita ese
archivo y corre npm run generate-data; el generador valida que no haya ejercicios
repetidos dentro de un mismo día ni ejercicios con barra sin alternativa.
En el test verás una pregunta de “silueta con la que te identificas”, con
opciones neutrales (delgado/promedio/atlético/contextura mayor). Se guarda,
pero no se usa para decidir si la rutina es más fácil o más difícil —
eso lo decide únicamente la experiencia previa (backend/src/utils/recommendation.js).
Está documentado en el código por si más adelante quieres cambiarlo, pero
usar el cuerpo de alguien para “colocarlo” en un nivel es justo el tipo de
suposición que puede sentirse ofensiva.