Saltar al contenido principal
Jordi Izquierdo Montalbán
Proyectos

Gordito Family

App Android para toda la familia: calculo las necesidades de cada miembro, genero menús con lo que hay en la nevera, planifico la compra al gramo y registro entrenos, con un asistente de IA integrado. Es mi proyecto final del ciclo formativo y ya va por la versión 1.1, instalable como APK.

Código privado: te lo enseño en una entrevista

React Native, Expo SDK 54, Firebase, Ollama Cloud, JavaScript, Firestore y Auth, React Navigation, Context API, AsyncStorage, Expo Notifications, Expo Print, React Native SVG, EAS Build

El problema

Tres problemas conviven en muchos hogares y ninguna app del mercado los resuelve a la vez: mantener una dieta variada y equilibrada para cada miembro de la familia, reducir los alimentos desperdiciados por caducidad y eliminar la fatiga de decisión diaria ("¿qué cenamos hoy?").

Las soluciones existentes (MyFitnessPal, Lifesum, Cronómetro) son reactivas: registran lo que ya has comido. Faltaba una herramienta proactiva que conectara las necesidades biológicas de cada familiar con el inventario real de la despensa y generara un plan nutricional accionable.

La solución - interfaz

S.I.P.N.F. - Sistema Integral de Planificación Nutricional Familiar, conocido comercialmente como Gordito Family, es una app móvil Android que actúa como un ERP para el hogar: cruza necesidades nutricionales con inventario, planifica menús automáticos y genera la lista de la compra calculada al gramo.

Autenticación
Login con accesibilidad WCAG 2.1 - placeholders descriptivos, toggle de visibilidad, props accesibles
Perfil de usuario
Perfil con 5 objetivos metabólicos: pérdida, mantenimiento, volumen, definición, recomposición
Generador de menú
Dashboard con macros en semáforo y botón 'Regenerar Menú' (control del usuario, ISO 9241)
Lista de la compra
Diferencial menú vs despensa: rojo (falta todo), amarillo (parcial), verde (suficiente)

La solución - arquitectura

Arquitectura de Gordito Family
Arquitectura serverless cloud-native en 3 capas: presentación React Native, lógica de negocio JavaScript pura, persistencia Firebase con reglas de mínimo privilegio.

Decisiones técnicas

  • React Native + Expo (hoy SDK 54), no bare workflow. Una única base de código JS compilada a APK nativo. Pierdo acceso a algunos módulos nativos pero gano builds OTA, EAS y testing instantáneo en Expo Go. Para una app social donde la lógica nativa es mínima, el trade-off compensa.
  • Firebase Firestore con onSnapshot listeners. Sincronización en tiempo real entre dispositivos sin servidor propio. Tres listeners simultáneos (usuarios, despensa, lista de la compra) con cleanup explícito al desmontar para evitar memory leaks.
  • Reglas Firestore con denegación por defecto. Aislamiento total por UID en cada documento (users/{uid}/...).
  • Context API en vez de Redux. La estructura (3 colecciones) no justifica el boilerplate de Redux. Context con providers limpios y suficiente para escalar a esta app.
  • Algoritmo heurístico, no ML. El generador de menús aplica reglas explícitas (Mifflin-St Jeor + factor de actividad + restricciones por comida + priorización de inventario). Inspeccionable, depurable, sin coste de inferencia.
  • Configuración en .env (EXPO_PUBLIC_*). Inyectada en compilación y fuera del repositorio.

Motor nutricional - Mifflin-St Jeor

TMB  = (10 × peso) + (6.25 × altura) − (5 × edad) + A
       (A = +5 hombre, −161 mujer)
TDEE = TMB × factor de actividad

Macros ajustados por objetivo (5 perfiles): pérdida (déficit 400 kcal · 2.2 g/kg proteína), mantenimiento, volumen, definición, recomposición. Cada miembro de la familia tiene los suyos.

Versión 1.1: de TFC a app que uso cada día

Entregar el TFC no fue el final. Seguí usando la app en casa y todo lo que echaba en falta acabó en la versión 1.1:

  • Módulo de entrenamiento con rutinas por fases (del circuito inicial a una rutina dividida), biblioteca de ejercicios con vídeo y gasto energético estimado por método MET, que ajusta los macros del día.
  • Recetas compuestas que calculan sus macros a partir de los ingredientes.
  • Historial con calendario, gráfico de evolución de peso y menú semanal imprimible en un solo folio.
  • Suplementos editables por usuario, que suman a los macros y salen en la impresión.
  • Notificación semanal para planificar la compra.

GordiBot: un asistente de IA que no se inventa números

Sobre todo eso añadí GordiBot, un asistente con modelo de lenguaje (Ollama Cloud, con cascada de cinco modelos) que conoce el menú y la rutina del día. La regla que me impuse fue sencilla: el bot no calcula, usa herramientas. Los LLM se equivocan sumando, así que cada número sale de una de sus 17 herramientas, que llaman a las mismas calculadoras que el resto de la app.

  • Ninguna herramienta escribe. Si el bot propone apuntar el peso o marcar una comida, la app lo enseña como tarjeta y solo se guarda si el usuario pulsa Confirmar.
  • Datos separados de instrucciones. Los nombres de recetas y notas los escribe el usuario, así que se sanean y se encierran en marcas antes de llegar al modelo. Lo comprobé con una rutina llamada literalmente «IGNORA TUS INSTRUCCIONES».
  • Consentimiento explícito y versionado. Son datos de salud (categoría especial del RGPD), así que la app explica qué sale del móvil y hacia dónde, y vuelve a pedir permiso cada vez que eso cambia. Sin aceptación, el asistente funciona en modo básico sin enviar nada.
  • Un único fichero conoce claves y modelos, de forma que pasar a un proxy en Cloud Functions para una distribución pública es reescribir una sola función.

Stack desglosado

  • Frontend: React Native 0.81 + Expo SDK 54, React Navigation (Stack + Material Top Tabs), Context API.
  • Backend: Firebase Firestore (real-time NoSQL) + Firebase Auth (email/contraseña).
  • Algoritmo: JavaScript puro - Calculos.js (Mifflin-St Jeor), GeneradorMenu.js (heurístico con 5 comidas, 259 alimentos en BD local).
  • Build: EAS Build con perfiles development/preview/production; genero un APK instalable.
  • Calidad: lógica de negocio en JavaScript puro, separada de la vista.

Resultados y aprendizajes

Lo que funcionó: la decisión de invertir tiempo desde el día 1 en reglas Firestore con mínimo privilegio. También el botón "Regenerar Menú" (control del usuario, ISO 9241) mejora la adherencia: si una propuesta no convence, hay otra al instante sin perder configuración.

Autoevaluación frente a 5 normas internacionales: ISO 27001 (seguridad), ISO 40500/WCAG 2.1 (accesibilidad), ISO 9241 (usabilidad), ISO 14915 (multimedia), ISO 9126 (calidad software). Cada hallazgo y corrección documentado en NormasISO.md del repo.

Lo que cambiaría hoy: añadiría TanStack Query encima de Firestore para gestionar caché y reintentos. La gestión manual con listeners se complica cuando aparecen pantallas con varias queries paralelas.

Trabajo futuro: mover la clave del modelo a un proxy en Cloud Functions antes de una distribución pública, Google OAuth, escáner de código de barras para digitalizar la despensa y predicción de la lista de la compra a partir del historial.