MVP 1 API Contracts - PlutoGr/TravelAgency GitHub Wiki
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).
- Booking → Catalog: получение снимка тура (например,
Правила версионирования
- Ломающие изменения: только в новом префиксе, например
/api/v2. - Неломающие: добавление необязательных полей в ответах и запросах.
См. также: Соответствие экранов и API · Архитектура MVP-1 · Дорожная карта