main commit
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2025-10-16 16:30:25 +09:00
parent 91c7e04474
commit 537e7b363f
1146 changed files with 45926 additions and 77196 deletions

593
docs/NUTRITION_API.md Normal file
View File

@@ -0,0 +1,593 @@
# API Сервиса Питания (Nutrition Service)
Сервис питания предоставляет API для работы с данными о питании, включая поиск продуктов питания, добавление продуктов в дневник питания, отслеживание потребления воды и физической активности.
## Основные функции
- Поиск продуктов питания через FatSecret API
- Отслеживание потребления пищи и питательных веществ
- Учет потребления воды
- Отслеживание физической активности
- Установка и отслеживание целей по питанию и активности
## Базовый URL
```
http://localhost:8006/api/v1/nutrition/
```
## Swagger-документация
Интерактивная документация API доступна через Swagger UI по следующим URL:
```
http://localhost:8006/docs
```
или через ReDoc:
```
http://localhost:8006/redoc
```
> **Примечание**: Swagger-документация доступна только при запущенном сервисе питания. Если сервис не запущен, страница документации будет недоступна.
### Использование Swagger UI
1. Откройте URL `http://localhost:8006/docs` в браузере
2. Авторизуйтесь с помощью кнопки "Authorize" в верхней части страницы:
- Введите ваш JWT токен в формате: `Bearer <token>`
- Нажмите "Authorize"
3. Теперь вы можете тестировать все эндпоинты API непосредственно через Swagger UI:
- Выберите нужный эндпоинт
- Заполните параметры запроса
- Нажмите "Execute" для отправки запроса
![Swagger UI Example](https://swagger.io/swagger/media/images/swagger-ui-example.png)
## Эндпоинты
### Поиск продуктов
#### Поиск по названию
```http
POST /api/v1/nutrition/search
```
Параметры запроса:
```json
{
"query": "яблоко",
"page_number": 0,
"max_results": 10
}
```
Ответ:
```json
[
{
"id": 1,
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"fatsecret_id": "35718",
"name": "Apple",
"brand": null,
"description": "A common fruit",
"food_type": "Generic",
"serving_size": "100g",
"serving_weight_grams": 100.0,
"calories": 52.0,
"protein_grams": 0.26,
"fat_grams": 0.17,
"carbs_grams": 13.81,
"fiber_grams": 2.4,
"sugar_grams": 10.39,
"sodium_mg": 1.0,
"cholesterol_mg": 0.0,
"ingredients": null,
"is_verified": true,
"created_at": "2025-10-16T23:10:00"
}
]
```
#### Получение информации о продукте
```http
GET /api/v1/nutrition/food/{food_id}
```
Ответ:
```json
{
"id": 1,
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"fatsecret_id": "35718",
"name": "Apple",
"brand": null,
"description": "A common fruit",
"food_type": "Generic",
"serving_size": "100g",
"serving_weight_grams": 100.0,
"calories": 52.0,
"protein_grams": 0.26,
"fat_grams": 0.17,
"carbs_grams": 13.81,
"fiber_grams": 2.4,
"sugar_grams": 10.39,
"sodium_mg": 1.0,
"cholesterol_mg": 0.0,
"ingredients": null,
"is_verified": true,
"created_at": "2025-10-16T23:10:00"
}
```
### Дневник питания
#### Добавление записи в дневник питания
```http
POST /api/v1/nutrition/diary
```
Параметры запроса:
```json
{
"food_item_id": 1,
"entry_date": "2025-10-16",
"meal_type": "breakfast",
"quantity": 1.5,
"unit": "piece",
"notes": "Morning apple"
}
```
Ответ:
```json
{
"id": 1,
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"user_id": 42,
"entry_date": "2025-10-16",
"meal_type": "breakfast",
"food_item_id": 1,
"custom_food_name": null,
"quantity": 1.5,
"unit": "piece",
"calories": 78.0,
"protein_grams": 0.39,
"fat_grams": 0.255,
"carbs_grams": 20.715,
"notes": "Morning apple",
"created_at": "2025-10-16T23:15:00"
}
```
#### Получение записей дневника за день
```http
GET /api/v1/nutrition/diary?date=2025-10-16
```
Ответ:
```json
[
{
"id": 1,
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"user_id": 42,
"entry_date": "2025-10-16",
"meal_type": "breakfast",
"food_item_id": 1,
"custom_food_name": null,
"quantity": 1.5,
"unit": "piece",
"calories": 78.0,
"protein_grams": 0.39,
"fat_grams": 0.255,
"carbs_grams": 20.715,
"notes": "Morning apple",
"created_at": "2025-10-16T23:15:00"
}
]
```
#### Получение сводки за день
```http
GET /api/v1/nutrition/summary?date=2025-10-16
```
Ответ:
```json
{
"date": "2025-10-16",
"total_calories": 2150.5,
"total_protein": 85.2,
"total_fat": 65.4,
"total_carbs": 275.3,
"water_consumed_ml": 1500,
"activity_minutes": 45,
"calories_burned": 350,
"entries_by_meal": {
"breakfast": [
{
"id": 1,
"food_name": "Apple",
"quantity": 1.5,
"unit": "piece",
"calories": 78.0
}
],
"lunch": [...],
"dinner": [...],
"snack": [...]
}
}
```
### Потребление воды
#### Добавление записи о потреблении воды
```http
POST /api/v1/nutrition/water
```
Параметры запроса:
```json
{
"amount_ml": 250,
"entry_date": "2025-10-16",
"notes": "Morning glass"
}
```
Ответ:
```json
{
"id": 1,
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"user_id": 42,
"entry_date": "2025-10-16",
"amount_ml": 250,
"entry_time": "2025-10-16T08:30:00",
"notes": "Morning glass"
}
```
#### Получение записей о потреблении воды за день
```http
GET /api/v1/nutrition/water?date=2025-10-16
```
Ответ:
```json
[
{
"id": 1,
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"user_id": 42,
"entry_date": "2025-10-16",
"amount_ml": 250,
"entry_time": "2025-10-16T08:30:00",
"notes": "Morning glass"
},
{
"id": 2,
"uuid": "223e4567-e89b-12d3-a456-426614174001",
"user_id": 42,
"entry_date": "2025-10-16",
"amount_ml": 500,
"entry_time": "2025-10-16T12:15:00",
"notes": "Lunch"
}
]
```
### Физическая активность
#### Добавление записи о физической активности
```http
POST /api/v1/nutrition/activity
```
Параметры запроса:
```json
{
"entry_date": "2025-10-16",
"activity_type": "running",
"duration_minutes": 30,
"distance_km": 5.2,
"intensity": "medium",
"notes": "Morning run"
}
```
Ответ:
```json
{
"id": 1,
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"user_id": 42,
"entry_date": "2025-10-16",
"activity_type": "running",
"duration_minutes": 30,
"calories_burned": 300.5,
"distance_km": 5.2,
"steps": null,
"intensity": "medium",
"notes": "Morning run",
"created_at": "2025-10-16T09:00:00"
}
```
#### Получение записей об активности за день
```http
GET /api/v1/nutrition/activity?date=2025-10-16
```
Ответ:
```json
[
{
"id": 1,
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"user_id": 42,
"entry_date": "2025-10-16",
"activity_type": "running",
"duration_minutes": 30,
"calories_burned": 300.5,
"distance_km": 5.2,
"steps": null,
"intensity": "medium",
"notes": "Morning run",
"created_at": "2025-10-16T09:00:00"
}
]
```
### Цели по питанию и активности
#### Установка целей
```http
POST /api/v1/nutrition/goals
```
Параметры запроса:
```json
{
"daily_calorie_goal": 2000,
"protein_goal_grams": 100,
"fat_goal_grams": 65,
"carbs_goal_grams": 250,
"water_goal_ml": 2500,
"activity_goal_minutes": 45,
"weight_goal_kg": 75.5,
"goal_type": "lose_weight"
}
```
Ответ:
```json
{
"id": 1,
"user_id": 42,
"daily_calorie_goal": 2000,
"protein_goal_grams": 100,
"fat_goal_grams": 65,
"carbs_goal_grams": 250,
"water_goal_ml": 2500,
"activity_goal_minutes": 45,
"weight_goal_kg": 75.5,
"goal_type": "lose_weight",
"created_at": "2025-10-16T10:00:00",
"updated_at": "2025-10-16T10:00:00"
}
```
#### Получение текущих целей
```http
GET /api/v1/nutrition/goals
```
Ответ:
```json
{
"id": 1,
"user_id": 42,
"daily_calorie_goal": 2000,
"protein_goal_grams": 100,
"fat_goal_grams": 65,
"carbs_goal_grams": 250,
"water_goal_ml": 2500,
"activity_goal_minutes": 45,
"weight_goal_kg": 75.5,
"goal_type": "lose_weight",
"created_at": "2025-10-16T10:00:00",
"updated_at": "2025-10-16T10:00:00"
}
```
## Коды ошибок
| Код | Описание |
|-----|----------|
| 400 | Некорректный запрос |
| 401 | Не авторизован |
| 403 | Доступ запрещен |
| 404 | Ресурс не найден |
| 500 | Внутренняя ошибка сервера |
## Аутентификация
Все запросы к API требуют JWT-токен в заголовке Authorization:
```
Authorization: Bearer <token>
```
Токен можно получить через сервис авторизации (User Service) по эндпоинту `/api/v1/auth/login`.
## Интеграции
Сервис питания интегрирован с API FatSecret для получения данных о продуктах питания и их пищевой ценности. Работа с API FatSecret осуществляется через OAuth 1.0 аутентификацию с использованием ключей, указанных в конфигурации приложения.
## Тестирование API
### Тестирование через Swagger UI
Самый простой способ протестировать API - использовать встроенный интерфейс Swagger UI:
1. Убедитесь, что сервис питания запущен:
```bash
# Запуск всех сервисов
./start_services.sh
```
2. Откройте в браузере URL: `http://localhost:8006/docs`
3. Авторизуйтесь:
- Нажмите на кнопку "Authorize" в правом верхнем углу
- Введите ваш JWT токен в формате `Bearer <token>`
- Нажмите "Authorize"
4. Теперь вы можете интерактивно тестировать все эндпоинты:
- Выберите нужный эндпоинт
- Заполните параметры запроса
- Нажмите "Execute"
- Просмотрите результат запроса и код ответа
### Настройка и запуск через CLI
1. Убедитесь, что все необходимые сервисы запущены:
```bash
# Запуск всех сервисов
./start_services.sh
```
2. Получите токен аутентификации:
```bash
# Регистрация нового пользователя
curl -X POST http://localhost:8001/api/v1/auth/register -H "Content-Type: application/json" -d '{
"email": "test_user@example.com",
"username": "test_user",
"password": "Test123!",
"first_name": "Test",
"last_name": "User",
"phone": "+79991234567"
}' | jq
# Вход и получение токена
curl -X POST http://localhost:8001/api/v1/auth/login -H "Content-Type: application/json" -d '{
"username": "test_user",
"password": "Test123!"
}' | jq
```
3. Сохраните полученный токен в переменную для дальнейшего использования:
```bash
export TOKEN=аш_полученный_jwt_токен"
```
### Примеры запросов
#### Поиск продуктов
```bash
# Поиск продуктов по названию
curl -X POST http://localhost:8006/api/v1/nutrition/search \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"query": "apple",
"max_results": 5
}' | jq
```
#### Работа с дневником питания
```bash
# Добавление записи в дневник питания
curl -X POST http://localhost:8006/api/v1/nutrition/diary \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"food_item_id": 1,
"entry_date": "2025-10-16",
"meal_type": "breakfast",
"quantity": 1.5,
"unit": "piece",
"notes": "Morning apple"
}' | jq
# Получение дневника за день
curl -X GET http://localhost:8006/api/v1/nutrition/diary?date=2025-10-16 \
-H "Authorization: Bearer $TOKEN" | jq
```
#### Работа с водой
```bash
# Добавление записи о потреблении воды
curl -X POST http://localhost:8006/api/v1/nutrition/water \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"amount_ml": 250,
"entry_date": "2025-10-16",
"notes": "Morning glass"
}' | jq
# Получение записей о потреблении воды за день
curl -X GET http://localhost:8006/api/v1/nutrition/water?date=2025-10-16 \
-H "Authorization: Bearer $TOKEN" | jq
```
#### Работа с активностью
```bash
# Добавление записи о физической активности
curl -X POST http://localhost:8006/api/v1/nutrition/activity \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"entry_date": "2025-10-16",
"activity_type": "running",
"duration_minutes": 30,
"distance_km": 5.2,
"intensity": "medium",
"notes": "Morning run"
}' | jq
# Получение записей об активности за день
curl -X GET http://localhost:8006/api/v1/nutrition/activity?date=2025-10-16 \
-H "Authorization: Bearer $TOKEN" | jq
```
### Автоматизированное тестирование
В папке `tests` есть скрипты для автоматизированного тестирования API:
```bash
# Запуск всех тестов для nutrition service
cd tests
./test_nutrition_service.sh
# Запуск тестов через Python
python test_nutrition_api.py
```
Для непосредственного тестирования FatSecret API можно использовать скрипт в корне проекта:
```bash
# Тестирование FatSecret API
python test_fatsecret_api_oauth1.py
```