Files
food-ai/docs/plans/Summary.md
dbastrikin 79c32f226c docs: add Iteration 6 — profile screen
Describe ProfileService, profileProvider, ProfileScreen sections
(avatar, body params, goal/activity, daily calories, logout),
EditProfileSheet, and HomeScreen name integration.
No new backend endpoints needed — GET/PUT /profile already exist.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 15:59:09 +02:00

21 KiB
Raw Permalink Blame History

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

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

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

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

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

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

┌─────────────────────┐
│ 6. Профиль          │  (зависит только от 0)
│    (просмотр +      │
│     редактирование) │
└─────────────────────┘

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


Итерация 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 GPT генерирует 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-агрегация без AI), GET, PATCH check

Flutter

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

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

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

Итерация 5: Главный экран

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

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

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

User Stories

Backend

ID Story Описание
5.1 GET /home/summary Агрегирует: план на сегодня, калории дневника, истекающие продукты, последние рекомендации

Flutter

ID Story Описание
5.2 HomeScreen Приветствие, кольцо калорий, план на сегодня, быстрые действия, баннер истекающих, блок рекомендаций
5.3 homeProvider StateNotifier, обновление после scan/menu-генерации

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

  • Открываешь приложение — сразу видишь баланс калорий и план на день
  • Предупреждение если продукты скоро истекут
  • Рекомендации без нового AI-вызова (из ранее сохранённых)

Итерация 6: Профиль

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

Цель: заменить заглушку вкладки «Профиль» полноценным экраном — просмотр данных, редактирование параметров тела и целей, отображение расчётной нормы калорий, выход из аккаунта.

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

User Stories

Backend

Новых эндпоинтов не требуется — GET /profile и PUT /profile реализованы в итерации 0.

Flutter

ID Story Описание
6.1 ProfileService getProfile()GET /profile, updateProfile()PUT /profile
6.2 profileProvider StateNotifier<AsyncValue<User>>, методы load() и update()
6.3 ProfileScreen Секции: аватар+имя, параметры тела, цель+активность, норма калорий, кнопка выхода
6.4 EditProfileSheet Modal bottom sheet с формой редактирования всех параметров
6.5 HomeScreen — имя Приветствие берёт имя из profileProvider вместо захардкоженного

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

  • Пользователь видит своё имя, email, параметры тела и цели
  • Может обновить параметры — норма калорий пересчитывается автоматически сервером
  • Может выйти из аккаунта с подтверждением
  • Приветствие на главном экране показывает реальное имя пользователя

Итоги

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

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

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