Loading repository data…
Loading repository data…
papercri / repository
Proyecto piloto creado para testear agentes de IA y skills con OpenCode. El objetivo es evaluar cómo un agente puede comprender, mantener y mejorar un proyecto real de front-end moderno.
A transparent discovery signal based on current public GitHub metadata.
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
Live deploy: avocato-ia.vercel.app
Plataforma web para gestionar hábitos alimenticios saludables. Permite calcular el IMC, el peso ideal y el gasto calórico diario, analizar comidas con IA y recibir recomendaciones nutricionales personalizadas a través de una experiencia visual inspirada en la alimentación mediterránea.
Proyecto piloto creado para testear agentes de IA y skills con OpenCode. El objetivo es evaluar cómo un agente puede comprender, mantener y mejorar un proyecto real de front-end moderno.
La app incluye 6 vistas principales:
| Capa | Tecnología |
|---|---|
| Lenguaje | TypeScript estricto |
| Framework | Vue 3 (Composition API, <script setup>) |
| Runtime / Build | Vite 8 |
| Estado | Pinia (persistencia en localStorage + Supabase) |
| Estilos | Tailwind CSS v4 (configuración vía CSS) |
| Enrutado | Vue Router (lazy-loaded) |
| Datos | Fetch Nativo → Open Food Facts API |
| Backend | Supabase (Auth + PostgreSQL + RLS) |
| IA Backend | Vercel Serverless Functions (Node.js) |
| IA Providers | Groq (gpt-oss-120b) + Cerebras (gpt-oss-120b) con fallback automático |
| Tests | Vitest + @vue/test-utils |
| Linting | ESLint 9 (flat config) + Prettier |
| Iconos | Font Awesome (SVG tree-shaking, ~55 iconos) |
Avocato es un proyecto piloto para experimentar con:
frontend-design, vue, tailwind-css-patterns, vitest, entre otros, en un contexto práctico.El repositorio incluye un archivo AGENTS.md con instrucciones específicas para agentes de IA que trabajen en el proyecto.
La app integra dos agentes de IA con fallback automático para analizar comidas y generar recetas personalizadas. El sistema intenta el proveedor primario y, si falla, recurre al secundario sin intervención del usuario.
Frontend (Vue) → /api/analyze-meal → Groq (primario) → Respuesta JSON
↓ (si falla)
Cerebras (fallback) → Respuesta JSON
Frontend (Vue) → /api/generate-recipe → Groq (primario) → Respuesta JSON
↓ (si falla)
Cerebras (fallback) → Respuesta JSON
| Proveedor | Modelo | Rol |
|---|---|---|
| Groq | gpt-oss-120b | Proveedor primario — respuesta rápida y de alta calidad |
| Cerebras | gpt-oss-120b | Proveedor de respaldo — fallback automático si Groq falla |
/api/analyze-meal)/api/analyze-meal (Vercel serverless function).| Componente | Archivo | Función |
|---|---|---|
MealAnalyzerForm | src/components/nutrition/MealAnalyzerForm.vue | Textarea + botón de análisis con estados loading/error |
NutritionResultCard | src/components/nutrition/NutritionResultCard.vue | Card principal con nombre, calorías, score y confianza |
MacroDistribution | src/components/nutrition/MacroDistribution.vue | Barras de distribución de macronutrientes |
IngredientBreakdown | src/components/nutrition/IngredientBreakdown.vue | Lista de ingredientes con cantidades y calorías |
NutritionTips | src/components/nutrition/NutritionTips.vue | Consejos de bienestar devueltos por la IA |
/api/generate-recipe)/api/generate-recipe junto con el objetivo nutricional del perfil del usuario.Se calcula con la fórmula estándar de la OMS:
BMI = peso (kg) / altura (m)²
| Clasificación | Rango BMI | Badge |
|---|---|---|
| Bajo peso | < 18.5 | warning |
| Peso normal | 18.5 – 24.9 | success |
| Sobrepeso | 25 – 29.9 | warning |
| Obesidad | ≥ 30 | danger |
Peso ideal se calcula con la fórmula: 22 × altura (m)²
El BMI Gauge en el perfil muestra un indicador lineal con gradiente de color (verde a rojo) que posiciona el BMI actual en el rango 15–40, con un pill flotante que muestra el valor numérico. Junto al gauge se muestran: peso actual, peso ideal, peso deseado, kg de sobrepeso y tiempo estimado para alcanzar el objetivo (~3 kg/mes).
La app calcula el gasto calórico diario en 3 pasos:
TMB (Tasa Metabólica Basal) — Fórmula de Mifflin-St Jeor:
10 × peso + 6.25 × altura - 5 × edad + 510 × peso + 6.25 × altura - 5 × edad - 161TDEE (Gasto Calórico Total) — TMB × factor de actividad:
Meta diaria — TDEE × ajuste de objetivo:
Se distribuyen automáticamente en macronutrientes: 30% proteínas, 45% carbohidratos, 25% grasas.
src/
├── design-system/ # Design System
│ ├── tokens/index.css # Design tokens (colors, spacing, typography, etc.)
│ └── index.ts # Barrel export de todos los componentes Ds*
├── components/
│ ├── ui/ # Primitivos UI del Design System
│ │ ├── Button.vue # Variantes: primary/secondary/ghost/danger/accent
│ │ ├── Input.vue # Label, helper, error, tamaños sm/md/lg
│ │ ├── Card.vue # Variantes: default/elevated/warm/surface
│ │ ├── Badge.vue # Variantes: primary/accent/success/warning/danger/info
│ │ ├── Modal.vue # Teleport, tamaños sm/md/lg/xl, backdrop blur
│ │ └── Typography.vue # Variantes: display/h1-h4/body/label/caption
│ ├── layout/ # Componentes de layout
│ │ ├── Container.vue # Max-width responsive + padding
│ │ ├── Stack.vue # Flex direction + gap + align + justify
│ │ └── Grid.vue # CSS Grid responsive con minItemWidth
│ ├── forms/ # Componentes de formulario
│ │ └── Field.vue # Wrapper con label/error/helper
│ ├── state/ # Componentes de estado
│ │ ├── EmptyState.vue # Estado vacío con icono + action slot
│ │ ├── Loading.vue # Spinner animado con tamaños
│ │ └── ErrorState.vue # Error con retry
│ ├── nutrition/ # Analizador de comidas con IA
│ │ ├── MealAnalyzerForm.vue # Textarea + análisis con loading/error
│ │ ├── NutritionResultCard.vue # Card con calorías, score, confianza
│ │ ├── MacroDistribution.vue # Barras de distribución de macros
│ │ ├── IngredientBreakdown.vue # Lista de ingredientes
│ │ └── NutritionTips.vue # Consejos de bienestar
│ ├── AppHeader.vue # Navbar sticky con hamburger menu
│ ├── CalorieRing.vue # Anillo SVG de progreso calórico
│ ├── FoodCard.vue # Tarjeta de alimento con Nutri-Score badge
│ ├── FoodDetailModal.vue # Modal completo con nutrition facts y Nutri-Score
│ └── NutrientCard.vue # Barra de progreso por macro nutriente
├── hooks/ # Hooks reutilizables
│ ├── useModal.ts # Estado open/close/toggle
│ ├── useDebounce.ts # Debounce genérico con cleanup
│ └── index.ts # Barrel export
├── composables/ # Composables para lógica reactiva
│ ├── useFoodSearch.ts # Search state, debounce, performSearch
│ ├── useAddFood.ts # Modal state, openAddModal, confirmAdd
│ └── useAuth.ts # Auth state, signIn/signUp/signOut, migración
├── lib/ # Configuración de servicios
│ └── supabase.ts # Cliente Supabase singleton
├── views/ # Vistas principales (todas lazy-loaded)
│ ├── DashboardView.vue # Pestañas: Mi día, Mis platos, Mis recetas, Perfil
│ ├── ProfileView.vue # Pestañas: Mi día, Mis platos, Mis recetas, Datos
│ ├── SearchView.vue
│ ├── NutritionAnalyzerView.vue # Botón guardar plato en favoritos
│ ├── RecipeGeneratorView.vue # Botón guardar receta en favoritos
│ └── AuthView.vue # Login/registro con Supabase Auth
├── stores/ # Almacenes Pinia con persistencia dual
│ ├── userStore.ts # Perfil de usuario + metas calóricas (localStorage/Supabase)
│ ├── foodStore.ts # Registro de comidas del día (localStorage/Supabase)
│ ├── savedPlatesStore.ts # Platos guardados en favoritos (localStorage/Supabase)
│ └── savedRecipesStore.ts # Recetas guardadas en favoritos (localStorage/Supabase)
├── services/ # Clientes HTTP
│ ├── openFoodFacts.ts # API pública de Open Food Facts
│ ├── nutritionAI.ts # Cliente del analizador IA → /api/analyze-meal
│ └── recipeAI.ts # Cliente del generador IA → /api/generate-recipe
├── types/ # Definiciones TypeScript
│ ├── user.ts # UserProfile, CalorieGoals, ActivityLevel, GoalType
│ ├── food.ts # FoodItem, MealEntry, NutritionSummary
│ ├── nutrition.ts # NutritionAnalysis, MacroValue, Ingredient
│ ├── recipe.ts # Allergen, DietaryPreference, RecipeConfig, GeneratedRecipe
│ ├── supabase.ts # Database types (5 tablas)
│ └── calculator.ts # BmiResult, IdealWeightResult
├── utils/ # Func