Files
food-ai/docs/plans/Summary.md
dbastrikin d53e019d90 docs: add Iteration 5 — home screen dashboard
Describe GET /home/summary endpoint (plan, logged calories, expiring
products, cached recommendations) and HomeScreen layout with calorie
ring, today's meals, expiring banner, and quick actions.
Update Summary.md to include iteration 5 and fix provider references
from Gemini/Groq to OpenAI/GPT.

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

283 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 |
Дальнейшие итерации определяются приоритетами после MVP. Функциональность из TODO.md (дневник статистики, режим готовки, полировка) — следующий горизонт.
## Карта зависимостей
```
┌──────────────┐
│ 0. Фундамент │
└──────┬───────┘
┌────────────┴────────────┐
│ │
▼ ▼
┌────────────────────┐ ┌──────────────────┐
│ 1. AI-рекомендации │ │ 2. Продукты │
│ (Gemini+Pexels) │ │ + ingredient_ │
│ saved_recipes │ │ mappings │
└──────────┬─────────┘ └────────┬─────────┘
│ │
└────────────┬────────────┘
┌──────────┴──────────┐
│ │
▼ ▼
┌────────────────────┐ ┌─────────────────────┐
│ 3. Распознавание │ │ 4. Планирование │
│ продуктов │ │ меню │
│ (GPT-4o Vision) │ │ (GPT+Pexels) │
└────────────────────┘ └──────────┬──────────┘
┌─────────────────────┐
│ 5. Главный экран │
│ (дашборд) │
└─────────────────────┘
```
**Параллельная разработка:** итерации 1 и 2 могут выполняться параллельно. Итерации 3 и 4 — тоже параллельно после завершения 1 и 2. Итерация 5 — после 4.
---
## Итерация 0: Фундамент
> **Детальный план:** [Iteration_0.md](./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](./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](./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](./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](./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](./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-вызова (из ранее сохранённых)
---
## Итоги
| Итерация | Цель | Ключевые 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. Главный экран | Дашборд: калории, план, истекающие, рекомендации | — |
**MVP:** итерации 02 (авторизация + рекомендации + продукты) — пользователь получает персонализированные рецепты.
**Полный продукт:** итерации 04 — полный цикл: сфотографировал чек → получил меню → список покупок → дневник питания.