Skip to content

Doc Booking

PlutoGr edited this page Oct 17, 2026 · 1 revision

Booking

src/Services/Booking/. Заявки на туры, предложения менеджера и избранное. База travel_booking.

Простой пример

Клиент на странице тура нажимает «Оставить заявку»:

POST /api/v1/bookings
{ "tourId": "3f2a…", "comment": "Двое взрослых, июль" }
→ 201 { "id": "b7c1…", "status": 0, … }

Booking сначала спрашивает у Catalog по gRPC, опубликован ли тур. Если нет, ответ 422 tour-unavailable, заявка не создаётся. Дальше заявку ведёт менеджер: берёт в работу, отправляет предложение, клиент его подтверждает. Весь сценарий: Заявки и чат.

Модель

Сущность Поля
Booking Id, ClientId, TourId, Comment, Status, CreatedAt, UpdatedAt
BookingStatusHistory BookingId, Status, ChangedByUserId, ChangedAt
Proposal BookingId, ManagerId, TourSnapshot, Notes, IsConfirmed, CreatedAt
TourSnapshot TourId, Title, Description, Price, Currency, DurationDays, SnapshotTakenAt: копия тура на момент предложения
Favorite UserId, TourId, AddedAt; пара уникальна
OutboxMessage EventType, Payload, Status (Pending, Processed, Failed), CreatedAt, ProcessedAt

Статус заявки в JSON передаётся числом:

Число Статус Смысл
0 New создана клиентом
1 InProgress менеджер взял в работу
2 ProposalSent клиенту отправлено предложение
3 Confirmed клиент подтвердил предложение
4 Closed заявка завершена
5 Cancelled отменена

Перевод чисел в названия на фронтенде: src/api/bookings.ts.

Переходы статусов

Из Можно в
New InProgress, Cancelled
InProgress ProposalSent (только если есть хотя бы одно предложение), Cancelled
ProposalSent Confirmed, InProgress, Cancelled
Confirmed Closed, Cancelled
Closed, Cancelled никуда

Недопустимый переход: BookingDomainException, ответ 422.

Кто что может

Действие Клиент Manager, Admin
создать заявку да да
свои заявки GET /bookings/my да да
все заявки GET /bookings нет (403 на Gateway) да
заявка по id только своя, иначе 403 любая; плюс имя и email клиента из Identity
смена статуса PATCH …/status только своя и только в Cancelled любой допустимый переход
предложение POST …/proposal нет да, кроме Closed и Cancelled
подтверждение POST …/confirm своя заявка да

PATCH с Confirmed отвечает 400: подтверждение идёт только через confirm с proposalId. Неверный proposalId: 422. Поле clientPhone в ответе всегда null: телефон хранится в Identity, но gRPC GetUserSummary его не передаёт.

Связи с другими сервисами (gRPC)

Вызов Когда
Catalog GetTourSnapshot создание заявки и добавление в избранное; тур должен быть опубликован
Catalog GetTourSnapshotForExistingBooking создание предложения; подходит и снятый с публикации тур
Identity GetUserSummary GET /bookings/{id} для менеджера и админа (имя и email клиента); роль пользователя в ValidateBookingAccess
сервер ValidateBookingAccess Chat проверяет, есть ли у пользователя доступ к заявке

Цена в снимке: самое дешёвое предложение тура, действующее сегодня; если такого нет, самое дешёвое из всех; если предложений нет, 0 USD. Подробно: Межсервисные контракты.

Избранное

GET /favorites, POST /favorites/{tourId} (409, если уже есть), DELETE /favorites/{tourId}. Карточки избранного фронтенд берёт из Catalog: GET /catalog/tours/cards?ids=.

Outbox

При создании заявки, смене статуса и отправке предложения в той же транзакции пишутся сообщения BookingCreated, BookingStatusChanged, ProposalSent. Обработчика, который бы их отправлял, в коде нет: сообщения остаются в статусе Pending. Задача на этапе 1: MVP-1.

Настройки

ConnectionStrings__BookingDb, JwtSettings__*, GrpcSettings__InternalServiceToken, GrpcClients__CatalogServiceUrl, GrpcClients__IdentityServiceUrl.

Clone this wiki locally