Asistente nutricional inteligente impulsado por Gemini AI Tus datos de salud, tus metas, tus recomendaciones — todo en un solo lugar.
Tanayen AI es una aplicación Kotlin Multiplatform (KMP) para Android e iOS que usa inteligencia artificial para darte recomendaciones nutricionales personalizadas basadas en tus métricas de salud reales, alacena disponible y perfil clínico.
⚠️ Esta app no reemplaza a un médico o profesional de la salud.
- Chat inteligente con Gemini — conversación en lenguaje natural con contexto clínico inyectado en cada turno
- Imágenes en el chat — toma o adjunta varias fotos en un mismo envío (hasta 6, cámara acumulativa + galería multi-selección); ideal para cargar varios ingredientes de la alacena de una sola vez. Gemini determina el contexto automáticamente:
- 🛒 Comparación de productos en el supermercado
- 🍽️ Recomendaciones de platos en menús de restaurante
- 🏠 Detección de ingredientes domésticos para guardar en la alacena
- Alacena inteligente — Gemini sugiere ingredientes detectados en imágenes; el usuario confirma antes de guardar
- Memoria de sesión persistente — el asistente retoma dónde se quedó entre reinicios: conserva los últimos turnos y un resumen rodante comprimido de sesiones anteriores (texto plano en la BD local, sin inflar el contexto)
- Registro automático de comidas — detecta lo que comiste en el chat, estima macros con Gemini y lo guarda en tu diario nutricional
- Diario de comidas — pantalla con lo que comiste hoy y ayer (hora, tipo, comida, kcal) agrupado por día con subtotal; desliza para borrar un registro y las calorías del día se recalculan al instante
- Notificaciones proactivas — recordatorio matutino con consejo personalizado (WorkManager / BGTaskScheduler)
- Sincronización de salud — métricas reales desde Health Connect (Android) y HealthKit (iOS)
- Perfil clínico — restricciones dietéticas basadas en colesterol, glucosa, presión arterial y más
- Historial de recomendaciones — Gemini evita repetir sugerencias recientes
| Capa | Tecnología |
|---|---|
| Multiplataforma | Kotlin Multiplatform (KMP) |
| Android UI | Jetpack Compose |
| iOS UI | SwiftUI |
| AI | Google Gemini 3.1 Flash Lite (SDK KMP) |
| Salud Android | Health Connect |
| Salud iOS | HealthKit |
| Base de datos local | SQLDelight (offline-first, todo en el dispositivo) |
| Networking | Ktor Client |
| Inyección de dependencias | Koin |
| Coroutines iOS | KMP-NativeCoroutines |
| Build System | Gradle 9, AGP 9 |
| CI/CD | GitHub Actions + Firebase App Distribution |
El proyecto sigue una arquitectura Clean Architecture + MVVM con código compartido en KMP.
shared/
├── commonMain/
│ ├── data/ # Repositorios + datasources locales (SQLDelight) y Gemini
│ ├── domain/
│ │ ├── model/ # Entidades de dominio
│ │ ├── repository/# Interfaces de repositorio
│ │ └── usecase/ # Casos de uso (lógica de negocio)
│ ├── presentation/
│ │ └── viewmodel/ # ViewModels compartidos Android/iOS
│ └── di/ # Módulos Koin
├── androidMain/ # Implementaciones Android (HealthConnect, DB driver)
└── iosMain/ # Implementaciones iOS (HealthKit, DB driver, Koin init)
Usuario adjunta imagen (cámara/galería)
↓
Compresión y conversión a Base64 en capa nativa (Android/iOS)
↓
ChatViewModel envía imagen + texto + contexto clínico a Gemini
↓
Gemini responde en streaming — ChatTagParser oculta tags parciales en tiempo real
↓
Al cerrar el stream: se detectan tags [PANTRY:...] y [REC:...]
↓
Si hay [PANTRY:...] → chip de confirmación en el chat
↓
Usuario confirma → SavePantryIngredientsUseCase guarda sin duplicados
El sistema usa un protocolo de tags al final de cada respuesta, invisible para el usuario:
[PANTRY:ingrediente1|ingrediente2|...] ← ingredientes para guardar en alacena
[REC:TIPO:título:ingrediente1|ingrediente2|...] ← recomendación para guardar en historial
[CLINICAL:{"key":valor}] ← valores clínicos extraídos (PDF/foto/texto)
[FOODLOG:{"description":"..."}] ← comida consumida → registro nutricional
[CHECKIN:{"meal_type":"...","recommended_food":"..."}] ← seguimiento proactivo de una recomendación
[GOAL_SET:{"goal":"..."}] / [GOAL_CHANGE:{"goal":"..."}] ← define o cambia la meta nutricional
El separador | (pipe) evita ambigüedad con nombres compuestos como sal, pimienta.
shared/src/commonTest/
├── domain/usecase/
│ ├── BuildContextUseCaseTest # Construcción de contexto clínico para Gemini
│ ├── ChatTagParserTest # Parsing y limpieza de tags en streaming
│ ├── FetchContextParamsUseCaseTest # Obtención de datos para el contexto
│ └── SavePantryIngredientsUseCaseTest # Deduplicación de ingredientes
shared/src/androidHostTest/
└── data/repository/
├── PantryRepositoryIntegrationTest # CRUD con SQLDelight real
├── FoodLogRepositoryIntegrationTest # Registro nutricional con SQLite real
└── ChatMessageRepositoryIntegrationTest # Ventana reciente + resumen rodante
# Ejecutar todos los tests
./gradlew :shared:allTests- Android Studio Meerkat o superior
- Xcode 16+
- JDK 21+ (el CI usa Zulu 21)
- Clona el repo
- Copia tu credencial en
local.properties:GEMINI_API_KEY=tu_api_key - Para iOS, agrega la misma variable en
iosApp/Configuration/Secrets.xcconfig:GEMINI_API_KEY = tu_api_key
ℹ️ Supabase quedó dormido (offline-first, todo en la BD local); ya no se necesitan
SUPABASE_URL/SUPABASE_ANON_KEYpara ejecutar la app. El código se conserva enreference/supabase/para la Fase 6 (Auth + multi-usuario).
# Android
./gradlew :androidApp:assembleDebug
# Shared (compilar + tests)
./gradlew :shared:buildPara iOS: abre iosApp/iosApp.xcodeproj en Xcode y ejecuta en simulador o dispositivo.
GitHub Actions (.github/workflows/ci.yml) automatiza lint, tests, builds y distribución:
| Evento | Qué corre |
|---|---|
PR a main/develop |
ktlint + tests, build APK Android, build de simulador iOS (solo compila) |
Push a develop |
solo ktlint + tests (sin distribución) |
Push a main |
AAB release firmado → Firebase App Distribution (grupo release-testers) |
🚀 El despliegue a Firebase ocurre únicamente al hacer push a
main(tras mergear un PR verificado).developya no distribuye.
📦 La distribución es solo Android (vía Firebase App Distribution). El build de iOS en CI únicamente compila el simulador para detectar errores; no hay publicación en TestFlight/App Store.