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>
This commit is contained in:
137
backend/README.md
Normal file
137
backend/README.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# FoodAI Backend
|
||||
|
||||
Go REST API с авторизацией через Firebase, JWT и PostgreSQL.
|
||||
|
||||
## Стек
|
||||
|
||||
- **Go 1.23** — язык
|
||||
- **chi** — HTTP-роутер
|
||||
- **pgx / pgxpool** — PostgreSQL-драйвер
|
||||
- **goose** — миграции
|
||||
- **golang-jwt/v5** — JWT
|
||||
- **Firebase Admin SDK** — верификация токенов
|
||||
|
||||
## Требования
|
||||
|
||||
- Go 1.23+
|
||||
- Docker & Docker Compose
|
||||
- [goose](https://github.com/pressly/goose) (`go install github.com/pressly/goose/v3/cmd/goose@latest`)
|
||||
- Файл `firebase-credentials.json` (сервисный аккаунт Firebase)
|
||||
|
||||
## Быстрый старт
|
||||
|
||||
### 1. Переменные окружения
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Отредактируйте `.env`:
|
||||
|
||||
| Переменная | Описание | По умолчанию |
|
||||
|---|---|---|
|
||||
| `DATABASE_URL` | DSN подключения к PostgreSQL | `postgres://food_ai:food_ai_local@localhost:5432/food_ai?sslmode=disable` |
|
||||
| `FIREBASE_CREDENTIALS_FILE` | Путь к JSON-ключу сервисного аккаунта Firebase | `./firebase-credentials.json` |
|
||||
| `JWT_SECRET` | Секрет для подписи JWT | — |
|
||||
| `JWT_ACCESS_DURATION` | Время жизни access-токена | `15m` |
|
||||
| `JWT_REFRESH_DURATION` | Время жизни refresh-токена | `720h` |
|
||||
| `PORT` | Порт сервера | `8080` |
|
||||
| `ALLOWED_ORIGINS` | CORS-разрешённые источники | `http://localhost:3000` |
|
||||
|
||||
### 2. Запуск через Docker Compose
|
||||
|
||||
Поднимает PostgreSQL и собирает приложение:
|
||||
|
||||
```bash
|
||||
make docker-up
|
||||
```
|
||||
|
||||
### 3. Запуск локально (только БД в Docker)
|
||||
|
||||
```bash
|
||||
# Запустить только PostgreSQL
|
||||
docker compose up -d postgres
|
||||
|
||||
# Применить миграции
|
||||
make migrate-up
|
||||
|
||||
# Запустить сервер
|
||||
make run
|
||||
```
|
||||
|
||||
## Команды
|
||||
|
||||
| Команда | Описание |
|
||||
|---|---|
|
||||
| `make run` | Запустить сервер в режиме разработки |
|
||||
| `make test` | Запустить unit-тесты |
|
||||
| `make test-integration` | Запустить интеграционные тесты (требует Docker) |
|
||||
| `make lint` | Проверить код через golangci-lint |
|
||||
| `make docker-up` | Поднять PostgreSQL + приложение |
|
||||
| `make docker-down` | Остановить контейнеры |
|
||||
| `make docker-logs` | Логи приложения |
|
||||
| `make migrate-up` | Применить миграции |
|
||||
| `make migrate-down` | Откатить последнюю миграцию |
|
||||
| `make migrate-status` | Статус миграций |
|
||||
| `make migrate-create name=<name>` | Создать новую миграцию |
|
||||
|
||||
## API
|
||||
|
||||
### Публичные эндпоинты
|
||||
|
||||
| Метод | Путь | Описание |
|
||||
|---|---|---|
|
||||
| `GET` | `/health` | Проверка состояния сервера и БД |
|
||||
| `POST` | `/auth/login` | Вход через Firebase ID-токен |
|
||||
| `POST` | `/auth/refresh` | Обновление JWT по refresh-токену |
|
||||
| `POST` | `/auth/logout` | Выход (инвалидация refresh-токена) |
|
||||
|
||||
### Защищённые эндпоинты (Bearer JWT)
|
||||
|
||||
| Метод | Путь | Описание |
|
||||
|---|---|---|
|
||||
| `GET` | `/profile` | Получить профиль пользователя |
|
||||
| `PUT` | `/profile` | Обновить профиль пользователя |
|
||||
|
||||
### Примеры запросов
|
||||
|
||||
**Логин:**
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/auth/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"firebase_token": "<FIREBASE_ID_TOKEN>"}'
|
||||
```
|
||||
|
||||
**Получить профиль:**
|
||||
```bash
|
||||
curl http://localhost:8080/profile \
|
||||
-H "Authorization: Bearer <ACCESS_TOKEN>"
|
||||
```
|
||||
|
||||
**Обновить профиль:**
|
||||
```bash
|
||||
curl -X PUT http://localhost:8080/profile \
|
||||
-H "Authorization: Bearer <ACCESS_TOKEN>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"height_cm": 180, "weight_kg": 75.5, "age": 28, "gender": "male", "activity": "moderate", "goal": "maintain"}'
|
||||
```
|
||||
|
||||
## Структура проекта
|
||||
|
||||
```
|
||||
backend/
|
||||
├── cmd/server/ # Точка входа
|
||||
├── internal/
|
||||
│ ├── auth/ # Firebase-верификация, JWT, сервис и хэндлер авторизации
|
||||
│ ├── config/ # Конфигурация через переменные окружения
|
||||
│ ├── database/ # Подключение к PostgreSQL (pgxpool)
|
||||
│ ├── middleware/ # RequestID, Logging, Recovery, CORS, Auth
|
||||
│ ├── server/ # Роутер (chi)
|
||||
│ ├── testutil/ # Вспомогательные утилиты для тестов
|
||||
│ └── user/ # Модель, репозиторий, сервис, хэндлер, расчёт калорий
|
||||
├── migrations/ # SQL-миграции (goose)
|
||||
├── .env.example
|
||||
├── docker-compose.yml
|
||||
├── Dockerfile
|
||||
└── Makefile
|
||||
```
|
||||
Reference in New Issue
Block a user