Skip to content

MVP 1 API Contracts

TravelAgency Team Bot edited this page Oct 9, 2026 · 3 revisions

MVP-1 API Contracts

Внешний API (frontend → gateway)

  • Формат: REST/JSON, префикс /api/v1.
  • Маршруты:
    • /api/v1/auth/* — аутентификация и профиль
    • /api/v1/catalog/* — каталог туров и направлений
    • /api/v1/bookings/* — заявки
    • /api/v1/favorites/* — избранное
    • /api/v1/chat/* — чат (если включён)

Каталог туров (с 2026-10-08, PR #76)

Подробности модели и правил в ADR-001.

Публичное чтение без входа, отдаются только опубликованные туры:

  • GET /api/v1/catalog/tours: список с фильтрами, сортировкой и ценой «от».
  • GET /api/v1/catalog/tours/{id}: страница тура. На черновик и снятый тур ответ 404.
  • GET /api/v1/catalog/tours/cards?ids=: карточки для избранного, до 50 id. Снятый тур приходит с available: false.

Запись идёт только через manage API (роли Manager и Admin). Менеджер работает со своими турами, на чужой тур получает 403. Админ видит все туры.

  • GET /api/v1/catalog/manage/tours: список туров. GET /api/v1/catalog/manage/tours/{id}: один тур, версия приходит в заголовке ETag.
  • POST /api/v1/catalog/manage/tours: создать черновик (201).
  • Шаги мастера: PUT /api/v1/catalog/manage/tours/{id}/basics, /description, /program, /conditions, /prices, /images.
  • POST /api/v1/catalog/manage/tours/{id}/publish и /unpublish.
  • DELETE /api/v1/catalog/manage/tours/{id}: удалить можно только черновик.

Каждая запись в существующий тур требует заголовок If-Match с версией тура. Без заголовка ответ 428, на устаревшую версию 409. Если тур не проходит проверку публикации или фото принадлежит не владельцу тура, ответ 422 с кодами ошибок.

Старые POST, PUT, PATCH и DELETE на /api/v1/catalog/tours удалены: у тура один путь записи, и он проверяет владельца и версию.

Картинки (с 2026-10-09, PR #82, задача #75)

API не отдаёт адресов картинок, только id файлов. Адрес собирает клиент.

  • Каталог: в списке, на странице тура и в cards вместо imageUrl приходит coverMediaFileId (обложка, null, если фото нет). В images, previews и cover есть только mediaFileId, alt, isCover и sortOrder, поля url нет.
  • Media: POST /api/v1/media/upload возвращает id и метаданные файла без url, у thumbnails тоже нет url.
  • Публичный адрес картинки GET /api/v1/media/files/{id}/w200|w800|w1600. Он работает только для фото опубликованных туров. Превью черновика идут через /api/v1/media/manage/files/{id}/…. На фронте адреса строят только mediaImageUrl и manageMediaFileUrl.
  • POST /api/v1/media/presign наружу не опубликован, Gateway отвечает 404.
  • Колонка Tour.ImageUrl и сохранённые адреса в базе пока остаются, но в ответы не попадают. Удалим их отдельной миграцией в #81, после «да» Платона.

Пример. Карточка тура приходит с "coverMediaFileId": "3f2a…". Фронт показывает <img src="/api/v1/media/files/3f2a…/w800">. Если хранилище переедет, контракт не изменится, потому что в нём нет адреса хранилища.


Межсервисные контракты

  • Протокол: gRPC (синхронные вызовы между сервисами).
  • Обязательные вызовы:
    • Booking → Catalog: получение снимка тура (например, GetTourSnapshot).
    • Booking → Identity: получение краткой информации о пользователе (например, GetUserSummary).

Правила версионирования

  • Ломающие изменения: только в новом префиксе, например /api/v2.
  • Неломающие: добавление необязательных полей в ответах и запросах.

См. также: Соответствие экранов и API · Архитектура MVP-1 · Дорожная карта

Clone this wiki locally