# 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
```