Files
food-ai/docs/plans/Summary.md
dbastrikin e57ff8e06c feat: implement Iteration 1 — AI recipe recommendations
Backend:
- Add Groq LLM client (llama-3.3-70b) for recipe generation with JSON
  retry strategy (retries only on parse errors, not API errors)
- Add Pexels client for parallel photo search per recipe
- Add saved_recipes table (migration 004) with JSONB fields
- Add GET /recommendations endpoint (profile-aware prompt building)
- Add POST/GET/GET{id}/DELETE /saved-recipes CRUD endpoints
- Wire gemini, pexels, recommendation, savedrecipe packages in main.go

Flutter:
- Add Recipe, SavedRecipe models with json_serializable
- Add RecipeService (getRecommendations, getSavedRecipes, save, delete)
- Add RecommendationsNotifier and SavedRecipesNotifier (Riverpod)
- Add RecommendationsScreen with skeleton loading and refresh FAB
- Add RecipeDetailScreen (SliverAppBar, nutrition tooltip, steps with timer)
- Add SavedRecipesScreen with Dismissible swipe-to-delete and empty state
- Update RecipesScreen to TabBar (Recommendations / Saved)
- Add /recipe-detail route outside ShellRoute (no bottom nav)
- Extend ApiClient with getList() and deleteVoid()

Project:
- Add CLAUDE.md with English-only rule for comments and commit messages

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-21 22:43:29 +02:00

17 KiB
Raw Blame History

FoodAI — План реализации

Обзор итераций

# Итерация Цель Зависит от
0 Фундамент Go-проект, БД, авторизация, Flutter-каркас
1 AI-рекомендации рецептов Gemini генерирует рецепты, Pexels фото, сохранение рецептов 0
2 Управление продуктами CRUD продуктов, сроки хранения, ingredient_mappings 0
3 Распознавание продуктов OCR чека, фото продуктов, фото блюд (Gemini Vision) 1, 2
4 Планирование меню Меню на неделю, AI-генерация, список покупок, дневник 1, 2

Дальнейшие итерации определяются приоритетами после MVP. Функциональность из TODO.md (дневник статистики, режим готовки, полировка) — следующий горизонт.

Карта зависимостей

                        ┌──────────────┐
                        │  0. Фундамент │
                        └──────┬───────┘
                               │
                  ┌────────────┴────────────┐
                  │                         │
                  ▼                         ▼
     ┌────────────────────┐      ┌──────────────────┐
     │ 1. AI-рекомендации │      │  2. Продукты     │
     │    (Gemini+Pexels) │      │  + ingredient_   │
     │    saved_recipes   │      │    mappings      │
     └──────────┬─────────┘      └────────┬─────────┘
                │                         │
                └────────────┬────────────┘
                             │
                  ┌──────────┴──────────┐
                  │                     │
                  ▼                     ▼
     ┌────────────────────┐  ┌─────────────────────┐
     │ 3. Распознавание   │  │ 4. Планирование     │
     │    продуктов       │  │    меню             │
     │    (Gemini Vision) │  │    (Gemini+Pexels)  │
     └────────────────────┘  └─────────────────────┘

Параллельная разработка: итерации 1 и 2 могут выполняться параллельно. Итерации 3 и 4 — тоже параллельно после завершения 1 и 2.


Итерация 0: Фундамент

Детальный план: Iteration_0.md

Цель: развернуть скелет проекта, базу данных, авторизацию и каркас мобильного приложения. После итерации можно зарегистрироваться, войти и увидеть пустые экраны.

Зависимости: нет.

User Stories

Backend

ID Story Описание
0.1 Инициализация Go-проекта Структура проекта (cmd/, internal/, pkg/), go.mod, конфигурация (envconfig), логгер (slog), graceful shutdown
0.2 PostgreSQL + миграции Подключение к PostgreSQL (pgx), система миграций (goose или golang-migrate). Начальная миграция: таблица users
0.3 HTTP-сервер + роутер HTTP-сервер (net/http или chi), middleware (CORS, request ID, logging, recovery), healthcheck endpoint
0.4 Firebase Auth интеграция Firebase Admin SDK. Middleware для верификации Firebase idToken. Выдача собственного JWT. Эндпоинты: POST /auth/login, POST /auth/refresh, POST /auth/logout
0.5 Таблица users Миграция: users (id, firebase_uid, email, name, avatar_url, параметры тела, цель, preferences JSONB, plan, created_at). CRUD-сервис
0.6 Docker Compose docker-compose.yml: PostgreSQL, приложение. Makefile с основными командами (migrate, run, test)

Flutter

ID Story Описание
0.7 Инициализация Flutter-проекта Создание проекта, структура (features/, core/, shared/), подключение основных пакетов (dio, riverpod/bloc, go_router)
0.8 Firebase Auth во Flutter Пакеты firebase_auth, google_sign_in, sign_in_with_apple. Экраны: вход (email + Google + Apple), регистрация. Хранение JWT в secure storage
0.9 Навигация и каркас экранов Bottom Tab Bar (5 вкладок), пустые заглушки для каждого экрана, роутинг
0.10 API-клиент Dio-клиент с interceptors: JWT-токен, refresh, error handling. Базовые модели (User)

Результат итерации

  • Можно зарегистрироваться через email / Google / Apple
  • Войти в приложение и увидеть 5 вкладок с заглушками
  • Backend отвечает на healthcheck и auth-запросы
  • БД содержит таблицу users с данными зарегистрированных пользователей

Итерация 1: AI-рекомендации рецептов

Детальный план: Iteration_1.md

Цель: реализовать ключевую функцию — персонализированные рецепты, сгенерированные Gemini, с фотографиями из Pexels и возможностью сохранять понравившиеся.

Зависимости: итерация 0.

User Stories

Backend

ID Story Описание
1.1 Gemini-клиент Пакет internal/gemini. Интерфейс RecipeGenerator. GenerateRecipes(prompt) → []Recipe. Retry на невалидный JSON
1.2 Pexels-клиент Пакет internal/pexels. SearchPhoto(query) → image_url. Параллельные запросы
1.3 Таблица saved_recipes Миграция: id, user_id, title, description, cuisine, difficulty, prep/cook_time_min, servings, image_url, ingredients (JSONB), steps (JSONB), tags (JSONB), nutrition (JSONB), source, saved_at
1.4 GET /recommendations Формирует промпт из профиля пользователя → Gemini → Pexels → ответ с image_url
1.5 CRUD saved_recipes POST /saved-recipes, GET /saved-recipes, GET /saved-recipes/{id}, DELETE /saved-recipes/{id}

Flutter

ID Story Описание
1.6 RecommendationsScreen Список карточек, skeleton-загрузка, кнопка 🔄 для перегенерации
1.7 RecipeDetailScreen Фото, КБЖУ≈, ингредиенты, шаги, кнопка сохранить
1.8 SavedRecipesScreen Список с удалением, пустое состояние

Результат итерации

  • Пользователь открывает вкладку «Рецепты» и видит 5 персонализированных рецептов с фото
  • Может сохранить рецепт, просмотреть детали, удалить из сохранённых
  • КБЖУ помечены «≈» как приблизительные

Итерация 2: Управление продуктами

Детальный план: Iteration_2.md

Цель: пользователь может вести список своих продуктов вручную — добавлять через автодополнение (ingredient_mappings), редактировать, удалять, отслеживать сроки. Рекомендации становятся персонализированными: Gemini учитывает имеющиеся продукты.

Зависимости: итерация 0.

User Stories

Backend

ID Story Описание
2.1 Таблица products Миграция: id, user_id, mapping_id (FK nullable), name, quantity, unit (ENUM), category, storage_days, added_at, expires_at (computed). Индексы по user_id, expires_at
2.2 Products CRUD API GET /products (фильтры: category, expiring), POST /products, PUT /products/{id}, DELETE /products/{id}, DELETE /products (очистить все)
2.3 Частичное использование PATCH /products/{id}/consume — уменьшить количество. Если количество = 0, предложить удаление
2.4 Массовое добавление POST /products/batch — добавление нескольких продуктов за раз (после распознавания). Обработка дубликатов: проверка по mapping_id, предложение объединить
2.5 Дефолтные сроки хранения GET /products/storage-defaults, PUT /products/storage-defaults. Хранение в user preferences (JSONB в таблице users)
2.6 Fuzzy matching при добавлении При добавлении продукта — поиск по ingredient_mappings.aliases. Если найдено — автозаполнение: mapping_id, category, unit, storage_days, нутриенты

Flutter

ID Story Описание
2.7 Экран «Мои продукты» Список продуктов по категориям, поиск, chip-фильтры, badge «осталось X дней»
2.8 Добавление/редактирование продукта Форма: название, количество, единица, категория, период хранения. Выпадающее меню добавления (+)
2.9 Частичное использование Модалка «Сколько осталось?» при свайпе или тапе
2.10 Очистить и перезаполнить Контекстное меню (···) → подтверждение → очистка
2.11 Настройки сроков хранения Экран из Профиля: список категорий с редактируемыми днями
2.12 Пустое состояние Иллюстрация + CTA «Сфотографируйте продукты или сканируйте чек»

Результат итерации

  • Пользователь может вручную добавить продукты, указать количество и сроки
  • Видит «осталось X дней» для каждого продукта
  • Может частично использовать продукт, удалить, очистить всё
  • При добавлении — автоматический подбор категории, единицы, срока через fuzzy match

Итерация 3: Распознавание продуктов

Детальный план: Iteration_3.md

Цель: пользователь фотографирует чек, холодильник или блюдо — Gemini Vision распознаёт продукты и помогает заполнить список запасов.

Зависимости: итерации 1, 2.

User Stories

Backend

ID Story Описание
3.1 OCR чека POST /ai/recognize-receipt: фото → Gemini Flash (vision) → JSON (name, qty, unit, confidence). Fuzzy match по ingredient_mappings
3.2 Фото продуктов POST /ai/recognize-products: 13 фото → параллельные Gemini-запросы → дедупликация → JSON
3.3 Распознавание блюда POST /ai/recognize-dish: фото → Gemini → {dish_name, weight_g, КБЖУ≈, confidence}
3.4 Авто-маппинг Нераспознанный продукт → Gemini классифицирует → сохраняет в ingredient_mappings
3.5 S3 / multipart Загрузка фото: multipart или presigned URL

Flutter

ID Story Описание
3.6 ScanScreen Выбор режима: чек / продукты / блюдо. Камера + галерея
3.7 Экран подтверждения Список с инлайн-редактированием, удалением, «Добавить ещё фото», CTA «В запасы»
3.8 Экран результата блюда Фото, КБЖУ≈, кнопки «В дневник» / «Открыть рецепт»

Результат итерации

  • Сфотографировал чек → список продуктов → подтвердил → добавил в запасы
  • Сфотографировал холодильник → то же
  • Сфотографировал блюдо → КБЖУ≈ → можно добавить в дневник

Итерация 4: Планирование меню

Детальный план: Iteration_4.md

Цель: пользователь получает полное меню на неделю от Gemini с учётом продуктов, целей и предпочтений. Автоматически формируется список покупок.

Зависимости: итерации 1, 2.

User Stories

Backend

ID Story Описание
4.1 Таблицы menu_plans, menu_items Миграции. menu_items → saved_recipes
4.2 Таблица meal_diary Миграция. Записи приёмов пищи
4.3 POST /ai/generate-menu Gemini генерирует 21 рецепт, Pexels параллельно, сохранение в БД
4.4 Menu CRUD GET /menu?week=, PUT /menu/items/{id}, DELETE /menu/items/{id}
4.5 Shopping list POST /shopping-list/generate (SQL-агрегация без Gemini), GET, PATCH check

Flutter

ID Story Описание
4.6 MenuScreen 7-дневный вид, skeleton на генерацию, кнопка «Сгенерировать»
4.7 Замена рецепта Тап «Изменить» → выбор из saved_recipes или перегенерация
4.8 ShoppingListScreen Список по категориям, чекбоксы, «Поделиться»
4.9 DiaryScreen Записи за день, «+ Добавить»

Результат итерации

  • Пользователь получает меню на неделю одним запросом к Gemini
  • Все рецепты меню сохраняются в saved_recipes
  • Из меню автоматически формируется список покупок (то, чего нет в запасах)
  • Ведётся дневник питания

Итоги

Итерация Цель Ключевые API
0. Фундамент Auth, профиль, каркас Firebase
1. AI-рекомендации Рецепты + сохранение Gemini, Pexels
2. Продукты CRUD запасов, ingredient_mappings
3. Распознавание OCR чека, фото продуктов/блюда Gemini Vision
4. Меню Недельное меню, список покупок Gemini, Pexels

MVP: итерации 02 (авторизация + рекомендации + продукты) — пользователь получает персонализированные рецепты.

Полный продукт: итерации 04 — полный цикл: сфотографировал чек → получил меню → список покупок → дневник питания.