App completa · Side Project · En producción
Yunke
Empezó como una calculadora de pesos para el gym. Hoy es una plataforma completa de CrossFit: temporizadores, logros, programación semanal, seguimiento de progreso y, en el centro de todo, inteligencia artificial que convierte el texto del coach en datos estructurados en segundos. Usada a diario por atletas reales en un box real.
El origen del problema
En el entrenamiento de fuerza y CrossFit, los ejercicios se planifican en base a porcentajes de tu repetición máxima (RM). Si tu RM en sentadilla es 87 kg y el entrenamiento pide trabajar al 45%, 65% y 80%, necesitás tres cálculos distintos antes de siquiera arrancar a mover una barra.
El método habitual era una planilla pegada en la pared del box, pero tenía una limitación importante: solo mostraba valores de 5 en 5%. Si tu RM no era un número redondo, la tabla no te servía. Terminabas haciendo cuentas a mano o de a una en la calculadora del celu — en el medio de un entrenamiento, con las manos sucias de tiza.
La primera solución fue simple: ingresás tu RM y obtenés todos los porcentajes de una sola vez, instantáneamente. Para validarla con usuarios reales, imprimí códigos QR y los pegué en distintos puntos del gimnasio. Eso me permitió incorporar feedback directo de personas que la usaban en contexto — y ese feedback terminó siendo el motor de todo lo que vino después.
La app
De calculadora a plataforma completa
El feedback de los usuarios reveló una necesidad más amplia: no solo calcular, sino entrenar asistidos. Cada iteración respondió a un problema concreto que alguien del gym planteó en persona.
Temporizador CrossFit. Cinco modalidades nativas: AMRAP, FOR TIME, EMOM (con intervalo configurable), TABATA y MIX. Cuenta regresiva animada, beeps con Web Audio API y Wake Lock para que la pantalla del celu no se apague a mitad del entrenamiento. Sin dependencias de audio externas — el sonido se genera directamente en el browser.
Programación semanal. El box publica la programación de cada semana y los atletas la ven desde su perfil, agrupada por día, con un drawer de detalle que muestra bloques de calentamiento, fuerza, acondicionamiento y técnica. Los links de video en los ejercicios se detectan automáticamente y se renderizan como botones.
Logros y registro de PRs. Catálogo estático de ~500 ejercicios tipados por categoría. Cada atleta registra sus récords personales con fecha, peso, unidad (kg, reps o tiempo en mm:ss) y modalidad. Los logros se guardan en Supabase, se agrupan por categoría con filtro en tiempo real y se pueden editar o eliminar con confirmación.
Seguimiento de progreso. Gráficos de evolución del peso corporal y métricas personales a lo largo del tiempo, construidos con Chart.js sobre datos del perfil del usuario.
Plan de alimentación. Sección personalizada con porciones, badges por grupo alimentario y tabla de equivalencias — pensada para atletas que quieren llevar control nutricional junto con el entrenamiento.
Inteligencia artificial en el flujo del coach
La funcionalidad más compleja de la plataforma nació de un problema real de operación: los coaches escriben la programación semanal en texto libre — sin formato fijo, con variaciones de estilo, bullets, notas, URLs de video intercaladas. Pasarla a mano a un sistema estructurado era inviable.
La solución: el superadmin pega el texto semanal del box en un campo de texto, selecciona la fecha de inicio y ejecuta el parseo. Una Netlify Function serverless divide el texto por día (regex sobre encabezados de día) y lanza llamadas paralelas a Claude Haiku — una por día, simultáneamente. Cada llamada recibe un prompt estructurado y retorna el JSON del día: bloques tipados (warmup, strength, conditioning, skill, leaderboard), ítems, notas y si el bloque es parte del "leaderboard workout" del día.
El resultado se ensambla server-side y se presenta con un preview completo: la misma vista que ve el atleta, con drawer por día. Si algún bloque quedó mal parseado, hay un editor JSON integrado para correcciones manuales. Con un botón, la programación se publica en Supabase y queda disponible para todos los atletas del box en segundos.
El diseño con llamadas paralelas fue una decisión técnica clave: el timeout de Netlify Functions en producción es de 10 segundos. Un único request con el texto completo de la semana lo superaba consistentemente. Con 7 llamadas en paralelo — una por día — cada request responde en ~4 segundos, dentro del límite. El procesamiento total se redujo de timeout a menos de 10 segundos para toda la semana.
Interfaz en uso real
Arquitectura y decisiones técnicas
Frontend. Angular 19 con standalone components y el nuevo control flow nativo (@if, @for, @switch). PrimeNG 19 como librería de componentes, TailwindCSS 4 con un sistema de tokens semánticos para modo oscuro sin clases dark: hardcodeadas — el tema cambia automáticamente según la preferencia del sistema y se puede overridear manualmente, persistiendo en localStorage.
Backend y datos. Supabase como plataforma central: autenticación con Supabase Auth, base de datos PostgreSQL con Row Level Security (RLS) en todas las tablas para que cada usuario solo acceda a sus propios datos, y Storage para avatares de perfil con políticas de acceso por carpeta de usuario. El catálogo de ejercicios (~500 movimientos tipados) es estático en el servicio — sin tabla en DB — con slugs como clave de relación en los logros.
Serverless. Dos Netlify Functions críticas: la de parseo con IA (Claude Haiku, llamadas paralelas por día) y la de reset de contraseña de admin (que usa la Service Role Key de Supabase para bypassear RLS y llamar a la Admin API — nunca expuesta en el frontend). Las credenciales sensibles viajan solo por variables de entorno en Netlify.
Sistema de roles. Dos dimensiones independientes: rol de gym (atleta, coach, headcoach) y rol de app (admin, superadmin). Tabla pivot en Supabase, con una función SQL SECURITY DEFINER que asegura que los roles de gym sean mutuamente excluyentes. Guards de ruta en Angular verifican el rol directamente en la DB en cada navegación — sin depender del estado en memoria.
PWA y APIs nativas. Instalable en iOS y Android con manifest, íconos por plataforma y flujo de instalación diferenciado: prompt nativo en Android/Chrome, instrucciones paso a paso en iOS/Safari. Wake Lock API para mantener la pantalla activa durante el timer. Web Audio API para generar los beeps del temporizador sin ningún archivo de audio externo. Scroll lock + intercepción del swipe-back en drawers para comportamiento nativo correcto en iOS.
Email transaccional. Los emails de confirmación, recuperación de contraseña e invitación se envían desde noreply@yunke.fit vía Resend, configurado como SMTP personalizado en Supabase. Dominio verificado con DKIM, SPF y DMARC — sin el límite de 2 emails/hora del plan gratuito de Supabase.
Multi-box. La plataforma soporta múltiples gimnasios: cada box tiene su programación semanal activa independiente, los atletas ven la programación del box al que pertenecen, y el superadmin gestiona boxes y usuarios desde paneles dedicados. El panel de administración de usuarios incluye listado con último acceso real, filtro por rol, CRUD completo vía dialog y soft delete — los usuarios nunca se eliminan físicamente.
Resultados
- 45+ Usuarios activos
- ~750 Cálculos semanales
- <10s Parseo semanal con IA
- ~500 Ejercicios en catálogo
¿Querés ver otros proyectos?