Files
food-ai/client/README.md
dbastrikin 24219b611e feat: implement Iteration 0 foundation (backend + Flutter client)
Backend (Go):
- Project structure with chi router, pgxpool, goose migrations
- JWT auth (access/refresh tokens) with Firebase token verification
- NoopTokenVerifier for local dev without Firebase credentials
- PostgreSQL user repository with atomic profile updates (transactions)
- Mifflin-St Jeor calorie calculation based on profile data
- REST API: POST /auth/login, /auth/refresh, /auth/logout, GET/PUT /profile, GET /health
- Middleware: auth, CORS (localhost wildcard), logging, recovery, request_id
- Unit tests (51 passing) and integration tests (testcontainers)
- Docker Compose setup with postgres healthcheck and graceful shutdown

Flutter client:
- Riverpod state management with GoRouter navigation
- Firebase Auth (email/password + Google sign-in with web popup support)
- Platform-aware API URLs (web/Android/iOS)
- Dio HTTP client with JWT auth interceptor and concurrent refresh handling
- Secure token storage
- Screens: Login, Register, Home (tabs: Menu, Recipes, Products, Profile)
- Unit tests (17 passing)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 13:14:58 +02:00

152 lines
6.0 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 Client
Flutter-приложение для управления питанием с поддержкой iOS, Android и Web.
## Стек
- **Flutter 3 / Dart 3** — фреймворк
- **Riverpod** — управление состоянием
- **go_router** — навигация с auth guard
- **Dio** — HTTP-клиент с автоматическим обновлением токенов
- **Firebase Auth** — аутентификация (email + Google)
- **flutter_secure_storage** — безопасное хранение токенов
- **json_serializable** — генерация сериализации моделей
## Требования
- Flutter SDK 3.x (`flutter --version`)
- Dart SDK 3.9+
- Android Studio или Xcode (для запуска на симуляторе/устройстве)
- Chrome (для запуска в браузере)
- Проект Firebase с включёнными Email и Google Sign-In
## Быстрый старт
### 1. Установить зависимости
```bash
flutter pub get
```
### 2. Настроить Firebase
1. Создайте проект в [Firebase Console](https://console.firebase.google.com)
2. Включите **Authentication → Sign-in method**: Email/Password и Google
#### Android
1. Project Settings (⚙️) → **Your apps** → иконка Android (`🤖`)
2. Package name: `com.foodai.food_ai`
3. Скачать `google-services.json` → положить в `android/app/`:
```bash
cp ~/Downloads/google-services.json android/app/google-services.json
```
#### iOS
1. Project Settings (⚙️) → **Your apps** → иконка iOS (``)
2. Bundle ID: `com.foodai.foodAi`
3. Скачать `GoogleService-Info.plist` → добавить через Xcode в группу `Runner`:
```bash
open ios/Runner.xcworkspace
# Перетащить GoogleService-Info.plist в группу Runner в навигаторе Xcode
```
#### Web
1. Project Settings (⚙️) → **Your apps** → иконка Web (`</>`)
2. Nickname: `FoodAI Web`
3. Скопировать полученный `firebaseConfig` в `web/index.html`, заменив `YOUR_*` placeholder'ы
4. Убедиться, что `localhost` есть в списке авторизованных доменов:
Authentication → **Settings****Authorized domains**
> **Важно:** не коммитить конфиг-файлы в git:
> ```bash
> echo "android/app/google-services.json" >> .gitignore
> echo "ios/Runner/GoogleService-Info.plist" >> .gitignore
> ```
### 3. Настроить URL бэкенда
Откройте `lib/core/config/app_config.dart` и укажите адрес API:
```dart
static const development = AppConfig(
apiBaseUrl: 'http://10.0.2.2:9090', // Android-эмулятор → localhost:9090
// apiBaseUrl: 'http://localhost:9090', // iOS-симулятор / Web
);
static const production = AppConfig(
apiBaseUrl: 'https://api.food-ai.app',
);
```
> Бэкенд по умолчанию поднимается на порту `9090` через Docker Compose (`9090:8080`).
### 4. Сгенерировать код
```bash
flutter pub run build_runner build --delete-conflicting-outputs
```
### 5. Запустить приложение
```bash
flutter run
```
## Команды
| Команда | Описание |
|---|---|
| `flutter pub get` | Установить зависимости |
| `flutter run` | Запустить на подключённом устройстве/симуляторе |
| `flutter run -d chrome` | Запустить в браузере (web) |
| `flutter test` | Запустить все тесты |
| `flutter analyze` | Статический анализ кода |
| `flutter build apk` | Собрать APK для Android |
| `flutter build ios` | Собрать для iOS |
| `flutter pub run build_runner build` | Сгенерировать код (json_serializable) |
| `flutter pub run build_runner watch` | Следить за изменениями и генерировать |
## Структура проекта
```
client/
├── lib/
│ ├── core/
│ │ ├── api/ # ApiClient (Dio), AuthInterceptor, исключения
│ │ ├── auth/ # AuthService, AuthNotifier (Riverpod), SecureStorage
│ │ ├── config/ # AppConfig (URL бэкенда по окружению)
│ │ ├── router/ # GoRouter с auth guard и MainShell
│ │ └── theme/ # Цвета и тема Material 3
│ ├── features/
│ │ ├── auth/ # LoginScreen, RegisterScreen
│ │ ├── home/ # HomeScreen (placeholder)
│ │ ├── menu/ # MenuScreen (placeholder)
│ │ ├── products/ # ProductsScreen (placeholder)
│ │ ├── profile/ # ProfileScreen (placeholder)
│ │ └── recipes/ # RecipesScreen (placeholder)
│ ├── shared/
│ │ └── models/ # User (json_serializable + user.g.dart)
│ ├── app.dart # Корневой виджет
│ └── main.dart # Точка входа, инициализация Firebase
└── test/
├── features/auth/ # Тесты LoginScreen, RegisterScreen
└── shared/models/ # Тесты модели User
```
## Навигация
Приложение использует `go_router` с guard-ом авторизации:
- `/login` — экран входа (только для неавторизованных)
- `/register` — экран регистрации
- `/``/home` — главная (требует авторизации)
- `/products` — продукты
- `/menu` — меню дня
- `/recipes` — рецепты
- `/profile` — профиль пользователя
Неавторизованный пользователь автоматически перенаправляется на `/login`. После входа — на `/home`.