# 06. API-контракты

## Назначение
Документ определяет стабильные контракты API для данных маркетплейса. Backend предоставляет только данные, frontend отвечает за представление.

## Поведение системы
- API base URL определяется tenant-конфигурацией.
- Frontend отправляет запросы через единый API слой и интерсепторы.
- Ответы маппятся в доменные модели frontend.

## Обязательные свойства JSON (ответы API)
- status или корректный HTTP status code
- data (основная полезная нагрузка)
- id для доменных сущностей

## Опциональные свойства JSON
- meta (pagination, total, filters)
- errors (детализация ошибок)
- warnings

## Строгие правила
- Backend не должен отдавать HTML для витрины.
- Контракты должны быть обратно совместимы в пределах одной major-версии.
- В ответах на списки должна поддерживаться пагинация.
- Ошибки API должны быть машиночитаемыми и локализуемыми на frontend.

## Product Engagement API (ожидаемый контракт)
- GET /products/{id}/rating
  - возвращает агрегированную оценку и распределение по звездам.
- GET /products/{id}/reviews
  - поддерживает пагинацию (page/pageSize).
- GET /products/{id}/questions
  - поддерживает пагинацию (page/pageSize).
- POST /products/{id}/reviews
  - принимает rating/title/text/anonymous.
- POST /products/{id}/questions
  - принимает text/anonymous.

Правило:
- Feature UI не вызывает API напрямую; запросы идут через ProductFacade -> domain service -> provider/repository.

## Advanced Catalog/Search Expectations
- Suggestions endpoint (future-ready):
  - GET /search/suggestions?q={term}
  - response: suggestion strings with optional popularity/count metadata.
- Dynamic filter metadata endpoint (future-ready):
  - GET /catalog/filters?category={id}&q={term}
  - response: filter definitions/options that frontend can render without hardcoded filter schema.
- Sort extension contract:
  - Backend may introduce new sort IDs via bootstrap `catalog.availableSorts`.
  - Frontend must render unknown sort keys safely if label mapping is provided.

  ## User Experience API Expectations (architecture-ready)
  - Wishlist (authenticated mode, future-ready):
    - GET /me/wishlist
    - POST /me/wishlist
    - DELETE /me/wishlist/{itemId}
  - Compare list (optional sync for authenticated mode):
    - GET /me/compare
    - POST /me/compare
    - DELETE /me/compare/{itemId}
  - Saved searches:
    - GET /me/saved-searches
    - POST /me/saved-searches
    - DELETE /me/saved-searches/{id}
  - Recently viewed sync (optional):
    - GET /me/recently-viewed
    - POST /me/recently-viewed

  Правила:
  - Guest mode может хранить UX данные локально (local storage) без backend-запросов.
  - UI не вызывает HttpClient напрямую: Feature -> Facade -> Repository/Provider.

## Пример API ответа: категории
```json
{
  "data": [
    {
      "id": 101,
      "title": "Смартфоны",
      "parentId": null,
      "priority": 1,
      "visible": true
    }
  ],
  "meta": {
    "total": 1
  }
}
```

## Пример API ответа: товары
```json
{
  "data": {
    "items": [
      {
        "itemID": 5001,
        "name": "Phone X",
        "price": 49990,
        "currency": "RUB",
        "categoryID": 101,
        "visible": true
      }
    ],
    "total": 1,
    "skip": 0,
    "count": 20
  }
}
```

## Ответственность Frontend
- Маппинг API DTO в доменные модели.
- Центральная обработка ошибок и retry-стратегий.
- Кеширование и переиспользование данных без нарушения актуальности.

## Ответственность Backend
- Гарантировать SLA и стабильность контрактов.
- Возвращать tenant-correct данные.
- Поддерживать фильтрацию, пагинацию и сортировку для каталога.
