@escapenavigator/types 2.1.6 → 2.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/aggregator-order/aggregator-order.ro.d.ts +16 -0
- package/dist/admin/aggregator-order/aggregator-order.ro.js +16 -0
- package/dist/admin/aggregator-order/create-aggregator-order.dto.d.ts +6 -0
- package/dist/admin/aggregator-order/create-aggregator-order.dto.js +6 -0
- package/dist/agregator/agregator-find-questroom-by-title.ro.js +4 -1
- package/dist/agregator/agregator-questroom-card.ro.d.ts +17 -0
- package/dist/agregator/agregator-questroom-card.ro.js +36 -2
- package/dist/agregator/agregator-questroom.ro.d.ts +2 -0
- package/dist/agregator/agregator-questroom.ro.js +14 -1
- package/dist/client/update-client-billing-defaults.dto.d.ts +5 -0
- package/dist/client/update-client-billing-defaults.dto.js +35 -0
- package/dist/constants/navigator-certificate-nominal-bounds.d.ts +8 -0
- package/dist/constants/navigator-certificate-nominal-bounds.js +45 -0
- package/dist/integrations/admin-integration.ro.d.ts +122 -0
- package/dist/integrations/admin-integration.ro.js +2 -0
- package/dist/integrations/booking-mode.enum.d.ts +24 -0
- package/dist/integrations/booking-mode.enum.js +28 -0
- package/dist/integrations/connect-integration.dto.d.ts +44 -0
- package/dist/integrations/connect-integration.dto.js +101 -0
- package/dist/integrations/connection-status.enum.d.ts +30 -0
- package/dist/integrations/connection-status.enum.js +34 -0
- package/dist/integrations/connector-capabilities.d.ts +85 -0
- package/dist/integrations/connector-capabilities.js +2 -0
- package/dist/integrations/credential-field.d.ts +80 -0
- package/dist/integrations/credential-field.js +2 -0
- package/dist/integrations/crm-integration-status.ro.d.ts +70 -0
- package/dist/integrations/crm-integration-status.ro.js +43 -0
- package/dist/integrations/incident-status.enum.d.ts +31 -0
- package/dist/integrations/incident-status.enum.js +36 -0
- package/dist/integrations/incident-type.enum.d.ts +30 -0
- package/dist/integrations/incident-type.enum.js +34 -0
- package/dist/integrations/integration-request-status.enum.d.ts +22 -0
- package/dist/integrations/integration-request-status.enum.js +26 -0
- package/dist/integrations/normalized-slot.d.ts +79 -0
- package/dist/integrations/normalized-slot.js +2 -0
- package/dist/integrations/partner-wire.d.ts +124 -0
- package/dist/integrations/partner-wire.js +26 -0
- package/dist/integrations/partners-booking-v1-schedule.dto.d.ts +11 -0
- package/dist/integrations/partners-booking-v1-schedule.dto.js +43 -0
- package/dist/integrations/partners-booking-v1.d.ts +124 -0
- package/dist/integrations/partners-booking-v1.js +2 -0
- package/dist/integrations/pending-booking-request.ro.d.ts +32 -0
- package/dist/integrations/pending-booking-request.ro.js +2 -0
- package/dist/integrations/provider-code.enum.d.ts +37 -0
- package/dist/integrations/provider-code.enum.js +41 -0
- package/dist/integrations/resource-match-status.enum.d.ts +25 -0
- package/dist/integrations/resource-match-status.enum.js +29 -0
- package/dist/integrations/run-operation.enum.d.ts +22 -0
- package/dist/integrations/run-operation.enum.js +26 -0
- package/dist/integrations/run-outcome.enum.d.ts +23 -0
- package/dist/integrations/run-outcome.enum.js +27 -0
- package/dist/navigator-certificate/create-navigator-certificate-sale.dto.d.ts +2 -2
- package/dist/navigator-certificate/create-navigator-certificate-sale.dto.js +4 -2
- package/dist/navigator-certificate/create-navigator-certificate-template.dto.d.ts +3 -2
- package/dist/navigator-certificate/create-navigator-certificate-template.dto.js +10 -2
- package/dist/navigator-certificate/enum/navigator-certificate-tag-nav-mode.enum.d.ts +5 -0
- package/dist/navigator-certificate/enum/navigator-certificate-tag-nav-mode.enum.js +9 -0
- package/dist/navigator-certificate/enum/navigator-certificate-tag-slug.enum.d.ts +23 -0
- package/dist/navigator-certificate/enum/navigator-certificate-tag-slug.enum.js +27 -0
- package/dist/navigator-certificate/index.d.ts +6 -0
- package/dist/navigator-certificate/index.js +6 -0
- package/dist/navigator-certificate/navigator-certificate-tag-catalog.d.ts +8 -0
- package/dist/navigator-certificate/navigator-certificate-tag-catalog.js +107 -0
- package/dist/navigator-certificate/navigator-certificate-tag-season.d.ts +8 -0
- package/dist/navigator-certificate/navigator-certificate-tag-season.js +86 -0
- package/dist/navigator-certificate/navigator-certificate-tag.ro.d.ts +8 -0
- package/dist/navigator-certificate/navigator-certificate-tag.ro.js +31 -0
- package/dist/navigator-certificate/navigator-certificate-template.ro.d.ts +3 -2
- package/dist/navigator-certificate/navigator-certificate-template.ro.js +5 -1
- package/dist/navigator-certificate/navigator-certificate-templates.ro.d.ts +16 -0
- package/dist/navigator-certificate/navigator-certificate-templates.ro.js +54 -1
- package/dist/navigator-certificate/update-navigator-certificate-tag.dto.d.ts +5 -0
- package/dist/navigator-certificate/update-navigator-certificate-tag.dto.js +30 -0
- package/dist/navigator-certificate/update-navigator-certificate-template.dto.d.ts +3 -2
- package/dist/navigator-certificate/update-navigator-certificate-template.dto.js +9 -2
- package/dist/openapi/external-booking/openapi-external-quote.dto.d.ts +22 -0
- package/dist/openapi/external-booking/openapi-external-quote.dto.js +43 -0
- package/dist/openapi/external-booking/openapi-external-quote.ro.d.ts +65 -0
- package/dist/openapi/external-booking/openapi-external-quote.ro.js +83 -0
- package/dist/openapi/morty/morty-timeslot.ro.js +13 -0
- package/dist/openapi/shared/openapi-questroom.ro.d.ts +1 -0
- package/dist/openapi/shared/openapi-questroom.ro.js +4 -0
- package/dist/openapi/slots/openapi-slot-add-hold.dto.d.ts +9 -0
- package/dist/openapi/slots/openapi-slot-add-hold.dto.js +6 -0
- package/dist/openapi/slots/openapi-slot-hold.ro.d.ts +50 -0
- package/dist/openapi/slots/openapi-slot-hold.ro.js +37 -0
- package/dist/openapi/slots/openapi-widget-slot.ro.d.ts +16 -1
- package/dist/openapi/slots/openapi-widget-slot.ro.js +11 -0
- package/dist/openapi/widget/bookeo/openapi-widget-bookeo-get-prices.dto.d.ts +9 -0
- package/dist/openapi/widget/bookeo/openapi-widget-bookeo-get-prices.dto.js +6 -0
- package/dist/openapi/widget/bookeo/openapi-widget-create-bookeo-order.dto.d.ts +19 -0
- package/dist/openapi/widget/bookeo/openapi-widget-create-bookeo-order.dto.js +18 -0
- package/dist/order/update-order.dto.d.ts +4 -0
- package/dist/order/update-order.dto.js +24 -0
- package/dist/parse-results/booking-provider-signatures.d.ts +35 -0
- package/dist/parse-results/booking-provider-signatures.js +93 -0
- package/dist/player/player-leaderboard.ro.d.ts +20 -0
- package/dist/player/player-leaderboard.ro.js +81 -0
- package/dist/player/player.ro.d.ts +30 -1
- package/dist/player/player.ro.js +85 -1
- package/dist/profile/admin-profile.ro.d.ts +3 -0
- package/dist/profile/admin-profile.ro.js +9 -0
- package/dist/profile/create-profile.dto.d.ts +1 -0
- package/dist/profile/create-profile.dto.js +6 -0
- package/dist/profile/enum/navigator-certificate-program.enum.d.ts +5 -0
- package/dist/profile/enum/navigator-certificate-program.enum.js +9 -0
- package/dist/profile/profile.ro.d.ts +2 -0
- package/dist/profile/profile.ro.js +5 -0
- package/dist/profile/query-admin-profile.dto.d.ts +2 -0
- package/dist/profile/query-admin-profile.dto.js +4 -0
- package/dist/questroom/agregator-questroom.ro.d.ts +1 -0
- package/dist/questroom/create-questroom-admin.dto.d.ts +1 -0
- package/dist/questroom/create-questroom-admin.dto.js +6 -0
- package/dist/questroom/create-questroom.dto.d.ts +4 -0
- package/dist/questroom/create-questroom.dto.js +6 -0
- package/dist/questroom/questroom.ro.d.ts +1 -0
- package/dist/questroom/questroom.ro.js +4 -0
- package/dist/questroom/questrooms-list-admin.ro.d.ts +2 -0
- package/dist/questroom/questrooms-list-admin.ro.js +8 -0
- package/dist/rating-badge/create-rating-badge.dto.d.ts +9 -0
- package/dist/{questroom/bind-bookeo.dto.js → rating-badge/create-rating-badge.dto.js} +8 -7
- package/dist/rating-badge/enum/rating-badge-status.enum.d.ts +6 -0
- package/dist/rating-badge/enum/rating-badge-status.enum.js +10 -0
- package/dist/rating-badge/ranking-overview.ro.d.ts +65 -0
- package/dist/rating-badge/ranking-overview.ro.js +249 -0
- package/dist/rating-badge/rating-badge-admin.ro.d.ts +7 -0
- package/dist/rating-badge/rating-badge-admin.ro.js +33 -0
- package/dist/rating-badge/rating-badge.ro.d.ts +12 -0
- package/dist/rating-badge/rating-badge.ro.js +50 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/dist/questroom/bind-bookeo.dto.d.ts +0 -4
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IntegrationRequestStatusEnum = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Состояние заявки «подключите меня сами» — кнопки, через которую квест
|
|
6
|
+
* передаёт данные нашему разработчику вместо самостоятельной настройки.
|
|
7
|
+
*/
|
|
8
|
+
var IntegrationRequestStatusEnum;
|
|
9
|
+
(function (IntegrationRequestStatusEnum) {
|
|
10
|
+
/** Заявка создана, мы её ещё не смотрели. */
|
|
11
|
+
IntegrationRequestStatusEnum["NEW"] = "new";
|
|
12
|
+
/** Данных не хватает: ждём ответа квеста. */
|
|
13
|
+
IntegrationRequestStatusEnum["NEED_INFO"] = "need_info";
|
|
14
|
+
/** Взята в работу. */
|
|
15
|
+
IntegrationRequestStatusEnum["IN_PROGRESS"] = "in_progress";
|
|
16
|
+
/**
|
|
17
|
+
* Ждём вендора: запросили доступ к API, статус канала, одобрение
|
|
18
|
+
* приложения. Отдельный статус, потому что ожидание тут измеряется
|
|
19
|
+
* неделями и это не наша задержка — но квесту всё равно надо отвечать.
|
|
20
|
+
*/
|
|
21
|
+
IntegrationRequestStatusEnum["WAITING_VENDOR"] = "waiting_vendor";
|
|
22
|
+
/** Подключение создано и работает. */
|
|
23
|
+
IntegrationRequestStatusEnum["DONE"] = "done";
|
|
24
|
+
/** Отказ: система не поддаётся интеграции или квест передумал. */
|
|
25
|
+
IntegrationRequestStatusEnum["REJECTED"] = "rejected";
|
|
26
|
+
})(IntegrationRequestStatusEnum || (exports.IntegrationRequestStatusEnum = IntegrationRequestStatusEnum = {}));
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Слот в едином внутреннем виде: то, что коннектор обязан вернуть, независимо
|
|
3
|
+
* от того, откуда данные — из нашей CRM, из Bookeo, из MyERP или из Partner
|
|
4
|
+
* API. Из него собирается `OpenapiSlotRO` для виджета и `MortyTimeslotRO` для
|
|
5
|
+
* исходящих партнёрских API, так что здесь должно быть достаточно полей для
|
|
6
|
+
* обоих.
|
|
7
|
+
*
|
|
8
|
+
* **Деньги — всегда в минорных единицах** (копейки/центы), как везде внутри
|
|
9
|
+
* проекта. Внешние системы отдают мажорные, и переводить их обязан коннектор
|
|
10
|
+
* на своей границе через `externalPriceToMinorUnits`. Эта строчка — не
|
|
11
|
+
* формальность: непереведённая цена уже приводила и к «от 51 руб.» вместо
|
|
12
|
+
* «от 5100 руб.» в виджете, и к брони на 350 000 ₽ вместо 3 500 ₽ в CRM
|
|
13
|
+
* квеста (см. `external-price.ts` и ретрай в `aggregator-order.service.ts`).
|
|
14
|
+
*/
|
|
15
|
+
export type NormalizedSlotStatus =
|
|
16
|
+
/** Свободен, можно бронировать. */
|
|
17
|
+
'free'
|
|
18
|
+
/** Занят, прошёл дедлайн, нет ресурсов — забронировать нельзя. */
|
|
19
|
+
| 'busy'
|
|
20
|
+
/** Только по телефону: показываем, но онлайн-бронь недоступна. */
|
|
21
|
+
| 'call'
|
|
22
|
+
/** Слот держится под конкретного игрока (hold). */
|
|
23
|
+
| 'hold';
|
|
24
|
+
export type NormalizedSlotPrice = {
|
|
25
|
+
/** Размер группы, для которого действует цена. */
|
|
26
|
+
players: number;
|
|
27
|
+
/** Цена за всю группу, минорные единицы. */
|
|
28
|
+
price: number;
|
|
29
|
+
};
|
|
30
|
+
export type NormalizedSlot = {
|
|
31
|
+
/**
|
|
32
|
+
* Идентификатор слота во внешней системе — с ним же уходит бронь. Строка,
|
|
33
|
+
* потому что у разных систем это и число, и UUID, и составной ключ.
|
|
34
|
+
* Обязан быть уникальным в пределах подключения, иначе бронь уедет в чужой
|
|
35
|
+
* слот: у MyERP это `quest_time_id`, у Bookeo `eventId`, у Partner API
|
|
36
|
+
* `timeslot.id`.
|
|
37
|
+
*/
|
|
38
|
+
externalSlotId: string;
|
|
39
|
+
/** Ресурс (квест/продукт) внешней системы, к которому относится слот. */
|
|
40
|
+
externalResourceId: string;
|
|
41
|
+
/** Локальная дата игры, `yyyy-MM-dd`. */
|
|
42
|
+
date: string;
|
|
43
|
+
/** Локальное время начала и конца, `HH:mm`. */
|
|
44
|
+
start: string;
|
|
45
|
+
end?: string;
|
|
46
|
+
/**
|
|
47
|
+
* Момент начала в UTC. Нужен отдельно от `date`/`start`: сравнивать слоты
|
|
48
|
+
* между часовыми поясами по локальному времени нельзя.
|
|
49
|
+
*/
|
|
50
|
+
startAt?: string;
|
|
51
|
+
/** IANA-таймзона площадки, например `Europe/London`. */
|
|
52
|
+
timezone?: string;
|
|
53
|
+
durationMinutes?: number;
|
|
54
|
+
status: NormalizedSlotStatus;
|
|
55
|
+
/** Минимальная цена за группу, минорные единицы. */
|
|
56
|
+
basePrice?: number;
|
|
57
|
+
/** Цены по размерам групп, минорные единицы. */
|
|
58
|
+
prices?: NormalizedSlotPrice[];
|
|
59
|
+
/** ISO 4217, например `EUR`. */
|
|
60
|
+
currency?: string;
|
|
61
|
+
seatsAvailable?: number;
|
|
62
|
+
playersMin?: number;
|
|
63
|
+
playersMax?: number;
|
|
64
|
+
/** Приватная (эксклюзивная) игра. */
|
|
65
|
+
privateEvent?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Крайний момент приёма брони, UTC ISO. `null` — отсечки нет. Слот с
|
|
68
|
+
* прошедшим дедлайном отдаём со статусом `busy`, а не выкидываем: игрок
|
|
69
|
+
* должен видеть, что игра существует, но записаться уже нельзя.
|
|
70
|
+
*/
|
|
71
|
+
deadline?: string | null;
|
|
72
|
+
/**
|
|
73
|
+
* Сырой ответ внешней системы по этому слоту. Только для диагностики
|
|
74
|
+
* инцидентов; **бизнес-логика не имеет права его читать**, иначе
|
|
75
|
+
* абстракция протекает и коннекторы перестают быть взаимозаменяемыми.
|
|
76
|
+
* Перед записью в журнал проходит через `redactIntegrationPayload`.
|
|
77
|
+
*/
|
|
78
|
+
raw?: unknown;
|
|
79
|
+
};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Канонический вид Morty-стандарта «на проводе».
|
|
3
|
+
*
|
|
4
|
+
* Одна и та же схема работает у нас в двух направлениях:
|
|
5
|
+
* - **наружу** — `/morty/*` и любой партнёр, который читает наше расписание;
|
|
6
|
+
* сериализуется классами `MortyTimeslotRO`, `MortyAttractionRO`,
|
|
7
|
+
* `MortyBookingRO`;
|
|
8
|
+
* - **внутрь** — Partner Booking API: мы читаем внешнюю систему клиентом
|
|
9
|
+
* `PartnerClientService`.
|
|
10
|
+
*
|
|
11
|
+
* Документ для партнёров обещает побайтовое зеркало: *«If you already expose an
|
|
12
|
+
* API for Morty, you can reuse it as is — just issue us a separate token»*.
|
|
13
|
+
* Пока схема была объявлена дважды (декорированные RO для исходящего и
|
|
14
|
+
* локальные типы в `partner-client.service.ts` для входящего), это обещание
|
|
15
|
+
* держалось на честном слове: правка одной копии не ломала ничего в другой.
|
|
16
|
+
* Здесь — единственное объявление; RO-классы проверяются на совместимость с
|
|
17
|
+
* ним на этапе компиляции (см. `morty-timeslot.ro.ts`).
|
|
18
|
+
*
|
|
19
|
+
* **Цены на проводе — в мажорных единицах** (`60` = £60), в отличие от всего
|
|
20
|
+
* внутреннего кода. Перевод делают мапперы на границе.
|
|
21
|
+
*
|
|
22
|
+
* Имена полей — snake_case и не приводятся к нашему camelCase: это внешний
|
|
23
|
+
* контракт, у него своя совместимость.
|
|
24
|
+
*/
|
|
25
|
+
export type PartnerWireLocation = {
|
|
26
|
+
address?: string;
|
|
27
|
+
longitude?: number | null;
|
|
28
|
+
latitude?: number | null;
|
|
29
|
+
phone?: string;
|
|
30
|
+
/** IANA, например `Europe/London`. */
|
|
31
|
+
timeZone?: string;
|
|
32
|
+
};
|
|
33
|
+
export type PartnerWireAttraction = {
|
|
34
|
+
/** Идентификатор квеста у партнёра. Обязан быть стабильным между синками. */
|
|
35
|
+
id: number | string;
|
|
36
|
+
title: string;
|
|
37
|
+
slug?: string;
|
|
38
|
+
photo?: string;
|
|
39
|
+
/** `escape`, `vr`, `performance`, `outdoor` и т.п. */
|
|
40
|
+
type?: string;
|
|
41
|
+
description?: string | null;
|
|
42
|
+
playersMin?: number;
|
|
43
|
+
playersMax?: number;
|
|
44
|
+
/** Площадка партнёра: группирует квесты одной локации. */
|
|
45
|
+
profile_id?: number | string | null;
|
|
46
|
+
location?: PartnerWireLocation;
|
|
47
|
+
};
|
|
48
|
+
export type PartnerWirePrice = {
|
|
49
|
+
players: number;
|
|
50
|
+
/** Цена за всю группу, мажорные единицы. */
|
|
51
|
+
price: number;
|
|
52
|
+
};
|
|
53
|
+
export type PartnerWireTimeslot = {
|
|
54
|
+
/** Глобально уникальный id слота — возвращается нам как `timeslot_id`. */
|
|
55
|
+
id: string;
|
|
56
|
+
product_id: number | string;
|
|
57
|
+
/** Локальная дата `YYYY-MM-DD`. */
|
|
58
|
+
date: string;
|
|
59
|
+
/** Локальное `HH:MM`. */
|
|
60
|
+
start_time: string;
|
|
61
|
+
end_time: string;
|
|
62
|
+
/** UTC ISO. */
|
|
63
|
+
start_at: string;
|
|
64
|
+
timezone: string;
|
|
65
|
+
duration_minutes: number;
|
|
66
|
+
is_free: boolean;
|
|
67
|
+
is_call_to_book: boolean;
|
|
68
|
+
is_blocked: boolean;
|
|
69
|
+
is_private: boolean;
|
|
70
|
+
seats_available: number;
|
|
71
|
+
players_min: number;
|
|
72
|
+
players_max: number;
|
|
73
|
+
/** ISO 4217. */
|
|
74
|
+
currency: string;
|
|
75
|
+
/** Мажорные единицы. */
|
|
76
|
+
price_from: number;
|
|
77
|
+
prices: PartnerWirePrice[];
|
|
78
|
+
/** UTC ISO либо `null`, если отсечки нет. */
|
|
79
|
+
deadline: string | null;
|
|
80
|
+
};
|
|
81
|
+
export type PartnerWireCustomer = {
|
|
82
|
+
first_name: string;
|
|
83
|
+
last_name: string;
|
|
84
|
+
email: string;
|
|
85
|
+
phone: string;
|
|
86
|
+
};
|
|
87
|
+
export type PartnerWireCreateBooking = {
|
|
88
|
+
timeslot_id: string;
|
|
89
|
+
/**
|
|
90
|
+
* Наш id брони с префиксом (`en_` для Partner API). **Ключ
|
|
91
|
+
* идемпотентности**: повтор после таймаута с тем же значением обязан
|
|
92
|
+
* вернуть уже созданную бронь, а не создать вторую.
|
|
93
|
+
*/
|
|
94
|
+
external_booking_id: string;
|
|
95
|
+
players: number;
|
|
96
|
+
customer: PartnerWireCustomer;
|
|
97
|
+
comment?: string;
|
|
98
|
+
/**
|
|
99
|
+
* Здесь зеркало **не симметрично, и это про деньги**. Morty собирает оплату
|
|
100
|
+
* сам и присылает нам `paid: true` с объектом `payment`. Мы наружу всегда
|
|
101
|
+
* отправляем `paid: false`: бронь неоплаченная, игрок платит на месте.
|
|
102
|
+
* Система, написанная под Morty и автоподтверждающая только предоплаченные
|
|
103
|
+
* брони, поведёт себя с нами иначе — это отдельный пункт в документе для
|
|
104
|
+
* партнёров и проверка в sandbox-валидаторе.
|
|
105
|
+
*/
|
|
106
|
+
paid?: boolean;
|
|
107
|
+
payment?: {
|
|
108
|
+
amount: number;
|
|
109
|
+
currency: string;
|
|
110
|
+
transaction_id: string;
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
export type PartnerWireBookingResponse = {
|
|
114
|
+
success: boolean;
|
|
115
|
+
booking_id: number | string;
|
|
116
|
+
external_booking_id: string;
|
|
117
|
+
confirmation_code: string;
|
|
118
|
+
status: 'confirmed' | 'cancelled' | 'failed';
|
|
119
|
+
/**
|
|
120
|
+
* Причина отказа. Бизнес-ошибки в этом стандарте приходят с HTTP 200 и
|
|
121
|
+
* `success: false`, поэтому сообщение — единственный источник причины.
|
|
122
|
+
*/
|
|
123
|
+
message?: string;
|
|
124
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Канонический вид Morty-стандарта «на проводе».
|
|
4
|
+
*
|
|
5
|
+
* Одна и та же схема работает у нас в двух направлениях:
|
|
6
|
+
* - **наружу** — `/morty/*` и любой партнёр, который читает наше расписание;
|
|
7
|
+
* сериализуется классами `MortyTimeslotRO`, `MortyAttractionRO`,
|
|
8
|
+
* `MortyBookingRO`;
|
|
9
|
+
* - **внутрь** — Partner Booking API: мы читаем внешнюю систему клиентом
|
|
10
|
+
* `PartnerClientService`.
|
|
11
|
+
*
|
|
12
|
+
* Документ для партнёров обещает побайтовое зеркало: *«If you already expose an
|
|
13
|
+
* API for Morty, you can reuse it as is — just issue us a separate token»*.
|
|
14
|
+
* Пока схема была объявлена дважды (декорированные RO для исходящего и
|
|
15
|
+
* локальные типы в `partner-client.service.ts` для входящего), это обещание
|
|
16
|
+
* держалось на честном слове: правка одной копии не ломала ничего в другой.
|
|
17
|
+
* Здесь — единственное объявление; RO-классы проверяются на совместимость с
|
|
18
|
+
* ним на этапе компиляции (см. `morty-timeslot.ro.ts`).
|
|
19
|
+
*
|
|
20
|
+
* **Цены на проводе — в мажорных единицах** (`60` = £60), в отличие от всего
|
|
21
|
+
* внутреннего кода. Перевод делают мапперы на границе.
|
|
22
|
+
*
|
|
23
|
+
* Имена полей — snake_case и не приводятся к нашему camelCase: это внешний
|
|
24
|
+
* контракт, у него своя совместимость.
|
|
25
|
+
*/
|
|
26
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Диапазон расписания для `GET /partners/booking/v1/questrooms/:id/schedule`.
|
|
3
|
+
*
|
|
4
|
+
* Формат проверяется строго: `parseISO` от мусора возвращает `Invalid Date`, и
|
|
5
|
+
* дальше это уезжает в чужую CRM запросом за несуществующий период. Партнёру
|
|
6
|
+
* полезнее 400 с понятной причиной, чем пустое расписание без объяснений.
|
|
7
|
+
*/
|
|
8
|
+
export declare class PartnersBookingV1ScheduleDto {
|
|
9
|
+
from: string;
|
|
10
|
+
to: string;
|
|
11
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.PartnersBookingV1ScheduleDto = void 0;
|
|
13
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
/**
|
|
16
|
+
* Диапазон расписания для `GET /partners/booking/v1/questrooms/:id/schedule`.
|
|
17
|
+
*
|
|
18
|
+
* Формат проверяется строго: `parseISO` от мусора возвращает `Invalid Date`, и
|
|
19
|
+
* дальше это уезжает в чужую CRM запросом за несуществующий период. Партнёру
|
|
20
|
+
* полезнее 400 с понятной причиной, чем пустое расписание без объяснений.
|
|
21
|
+
*/
|
|
22
|
+
class PartnersBookingV1ScheduleDto {
|
|
23
|
+
}
|
|
24
|
+
exports.PartnersBookingV1ScheduleDto = PartnersBookingV1ScheduleDto;
|
|
25
|
+
__decorate([
|
|
26
|
+
(0, swagger_1.ApiProperty)({
|
|
27
|
+
description: 'Первый день диапазона (включительно), локальная дата площадки, yyyy-MM-dd.',
|
|
28
|
+
example: '2026-09-07',
|
|
29
|
+
}),
|
|
30
|
+
(0, class_validator_1.IsString)(),
|
|
31
|
+
(0, class_validator_1.Matches)(/^\d{4}-\d{2}-\d{2}$/, { message: 'from must be in yyyy-MM-dd format' }),
|
|
32
|
+
__metadata("design:type", String)
|
|
33
|
+
], PartnersBookingV1ScheduleDto.prototype, "from", void 0);
|
|
34
|
+
__decorate([
|
|
35
|
+
(0, swagger_1.ApiProperty)({
|
|
36
|
+
description: 'Последний день диапазона (включительно), yyyy-MM-dd. Диапазон длиннее ' +
|
|
37
|
+
'обслуживаемого укорачивается молча: за горизонтом провайдера слотов всё равно нет.',
|
|
38
|
+
example: '2026-09-14',
|
|
39
|
+
}),
|
|
40
|
+
(0, class_validator_1.IsString)(),
|
|
41
|
+
(0, class_validator_1.Matches)(/^\d{4}-\d{2}-\d{2}$/, { message: 'to must be in yyyy-MM-dd format' }),
|
|
42
|
+
__metadata("design:type", String)
|
|
43
|
+
], PartnersBookingV1ScheduleDto.prototype, "to", void 0);
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { IntegrationBookingModeEnum } from './booking-mode.enum';
|
|
2
|
+
/**
|
|
3
|
+
* Опубликованный контракт `/partners/booking/v1/*` — то, что видят внешние
|
|
4
|
+
* потребители расписания: агрегаторы-партнёры (Morty, NowEscape, RU-каталоги) и
|
|
5
|
+
* наш собственный облегчённый шелл записи.
|
|
6
|
+
*
|
|
7
|
+
* **Почему это отдельные типы, а не `NormalizedSlot` наружу.** `NormalizedSlot`
|
|
8
|
+
* — внутренний вид, в нём есть `raw` с сырым ответом чужой системы: он идёт в
|
|
9
|
+
* журнал для разбора инцидентов и наружу попасть не должен ни при каких
|
|
10
|
+
* обстоятельствах. Кроме того, внутренний тип мы правим свободно, а этот —
|
|
11
|
+
* только с новой версией в пути. Пересобирать один в другой на границе дешевле,
|
|
12
|
+
* чем однажды случайно опубликовать поле, которое не собирались.
|
|
13
|
+
*
|
|
14
|
+
* **Почему `v1`, когда проект называется «интеграции v2».** Номер в пути
|
|
15
|
+
* считает версии опубликованного контракта, а не наших внутренних переделок:
|
|
16
|
+
* снаружи этого контракта раньше не было. Прежние внешние диалекты
|
|
17
|
+
* (`/morty/*`, `/aggregators/*`, `/nowescape/*`) версии в пути не имеют вовсе,
|
|
18
|
+
* так что на номер 1 никто не претендует.
|
|
19
|
+
*
|
|
20
|
+
* **Деньги — в минорных единицах** (копейки/центы), и поле называется
|
|
21
|
+
* `priceMinor`, чтобы единицу нельзя было прочитать неправильно. Цена в
|
|
22
|
+
* мажорных уже дважды приводила к порче данных: «от 51 руб.» вместо «от 5100
|
|
23
|
+
* руб.» в виджете и бронь на 350 000 ₽ вместо 3 500 ₽ в CRM квеста.
|
|
24
|
+
*/
|
|
25
|
+
export type PartnersBookingV1SlotStatus =
|
|
26
|
+
/** Свободен, бронировать можно. */
|
|
27
|
+
'free'
|
|
28
|
+
/** Занят или приём броней закрыт. */
|
|
29
|
+
| 'busy'
|
|
30
|
+
/** Показываем, но записаться можно только по телефону. */
|
|
31
|
+
| 'call';
|
|
32
|
+
export type PartnersBookingV1Price = {
|
|
33
|
+
/** Размер группы, для которого действует цена. */
|
|
34
|
+
players: number;
|
|
35
|
+
/** Цена за всю группу, минорные единицы. */
|
|
36
|
+
priceMinor: number;
|
|
37
|
+
};
|
|
38
|
+
export type PartnersBookingV1Slot = {
|
|
39
|
+
/**
|
|
40
|
+
* Идентификатор слота. С ним же придёт бронь, когда появится запись по
|
|
41
|
+
* этому контракту. Строка: у разных систем это число, UUID или составной
|
|
42
|
+
* ключ.
|
|
43
|
+
*/
|
|
44
|
+
slotId: string;
|
|
45
|
+
/** Локальная дата игры, `yyyy-MM-dd`. */
|
|
46
|
+
date: string;
|
|
47
|
+
/** Локальное время, `HH:mm`. */
|
|
48
|
+
start: string;
|
|
49
|
+
end?: string;
|
|
50
|
+
/**
|
|
51
|
+
* Момент начала в UTC, ISO. Отдаётся отдельно от локальных `date`/`start`:
|
|
52
|
+
* сравнивать слоты разных площадок по локальному времени нельзя.
|
|
53
|
+
*/
|
|
54
|
+
startAt?: string;
|
|
55
|
+
durationMinutes?: number;
|
|
56
|
+
status: PartnersBookingV1SlotStatus;
|
|
57
|
+
/** Минимальная цена за группу, минорные единицы. */
|
|
58
|
+
priceMinor?: number;
|
|
59
|
+
/** Цены по размерам групп, минорные единицы. */
|
|
60
|
+
prices?: PartnersBookingV1Price[];
|
|
61
|
+
/** ISO 4217, например `EUR`. */
|
|
62
|
+
currency?: string;
|
|
63
|
+
seatsAvailable?: number;
|
|
64
|
+
playersMin?: number;
|
|
65
|
+
playersMax?: number;
|
|
66
|
+
/** Крайний момент приёма брони, UTC ISO. `null` — отсечки нет. */
|
|
67
|
+
deadline?: string | null;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Почему расписание недоступно. Строка, а не enum наружу: список будет
|
|
71
|
+
* пополняться, и потребитель обязан переживать незнакомое значение, а не падать
|
|
72
|
+
* на нём. Значения стабильны и годятся для показа в поддержке.
|
|
73
|
+
*/
|
|
74
|
+
export type PartnersBookingV1UnavailableReason =
|
|
75
|
+
/** Квест не на нашей CRM и не интегрирован ни с одной системой. */
|
|
76
|
+
'no_connection'
|
|
77
|
+
/** Подключение есть, но квест не связан с ресурсом внешней системы. */
|
|
78
|
+
| 'not_matched'
|
|
79
|
+
/** Настройка не доведена до проверки креденшелов. */
|
|
80
|
+
| 'status_draft'
|
|
81
|
+
/** Ждёт действия вендора или нашего. */
|
|
82
|
+
| 'status_pending'
|
|
83
|
+
/** Креденшелы перестали приниматься. */
|
|
84
|
+
| 'status_failed'
|
|
85
|
+
/** Подключение выключено. */
|
|
86
|
+
| 'status_disabled'
|
|
87
|
+
/** Внешняя система не ответила: сбой, таймаут, разомкнутый предохранитель. */
|
|
88
|
+
| 'provider_unavailable';
|
|
89
|
+
export type PartnersBookingV1Questroom = {
|
|
90
|
+
id: number;
|
|
91
|
+
title: string;
|
|
92
|
+
/** IANA-таймзона площадки, например `Europe/London`. */
|
|
93
|
+
timezone: string | null;
|
|
94
|
+
playersMin: number | null;
|
|
95
|
+
playersMax: number | null;
|
|
96
|
+
/** `false` — расписание сейчас отдать не из чего, смотри `unavailableReason`. */
|
|
97
|
+
scheduleAvailable: boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Как оформляется бронь: мгновенно, через удержание или заявкой с
|
|
100
|
+
* подтверждением квеста. Читать до попытки записи: у части систем нет API
|
|
101
|
+
* записи вовсе, и там всегда `request`.
|
|
102
|
+
*/
|
|
103
|
+
bookingMode: IntegrationBookingModeEnum;
|
|
104
|
+
/** `null`, когда расписание доступно. */
|
|
105
|
+
unavailableReason: PartnersBookingV1UnavailableReason | null;
|
|
106
|
+
/** На сколько дней вперёд имеет смысл спрашивать расписание. */
|
|
107
|
+
scheduleHorizonDays: number | null;
|
|
108
|
+
};
|
|
109
|
+
export type PartnersBookingV1Schedule = {
|
|
110
|
+
questroomId: number;
|
|
111
|
+
/** Запрошенный диапазон локальных дат, включительно. */
|
|
112
|
+
from: string;
|
|
113
|
+
to: string;
|
|
114
|
+
/**
|
|
115
|
+
* `true` — расписание получить **не удалось**. Пустой `slots` при этом не
|
|
116
|
+
* означает «свободных мест нет», и показывать его как «мест нет» нельзя:
|
|
117
|
+
* вместо этого предлагайте игроку заявку. Это единственное поле, которое
|
|
118
|
+
* отличает «квест занят» от «мы не смогли спросить», и ради него оно и
|
|
119
|
+
* заведено.
|
|
120
|
+
*/
|
|
121
|
+
unavailable: boolean;
|
|
122
|
+
unavailableReason: PartnersBookingV1UnavailableReason | null;
|
|
123
|
+
slots: PartnersBookingV1Slot[];
|
|
124
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Заявка, ждущая ответа квеста (режим `request`).
|
|
3
|
+
*
|
|
4
|
+
* Показывается в кабинете рядом с интеграцией. Дублирует то, что уже ушло
|
|
5
|
+
* письмом и в Telegram, и это не избыточность: письмо теряется в папке «спам» и
|
|
6
|
+
* читается с чужого телефона, а кабинет — единственное место, где владелец
|
|
7
|
+
* видит сразу все висящие заявки и понимает масштаб («у меня их четыре»).
|
|
8
|
+
*/
|
|
9
|
+
export type PendingBookingRequest = {
|
|
10
|
+
/** `aggregator-orders.id` — он же идентификатор заявки. */
|
|
11
|
+
orderId: number;
|
|
12
|
+
connectionId: number;
|
|
13
|
+
questroomId: number | null;
|
|
14
|
+
questroomTitle: string;
|
|
15
|
+
/** Дата и время игры так, как их видит игрок. */
|
|
16
|
+
date: string;
|
|
17
|
+
time: string;
|
|
18
|
+
players: number | null;
|
|
19
|
+
playerName: string;
|
|
20
|
+
playerPhone: string;
|
|
21
|
+
playerEmail: string;
|
|
22
|
+
/** Сумма заказа в минорных единицах — как она хранится в заказе. */
|
|
23
|
+
price: number;
|
|
24
|
+
/** До какого момента ждём ответа. `null` — срок не проставлен. */
|
|
25
|
+
deadlineAt: string | null;
|
|
26
|
+
/**
|
|
27
|
+
* Сколько минут осталось. Отрицательное значение означает «срок вышел, но
|
|
28
|
+
* крон ещё не закрыл заявку»: такую заявку подтверждать уже нельзя, и
|
|
29
|
+
* интерфейс обязан показать это до нажатия, а не после.
|
|
30
|
+
*/
|
|
31
|
+
minutesLeft: number | null;
|
|
32
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Код системы бронирования, за которой стоит конкретный коннектор.
|
|
3
|
+
*
|
|
4
|
+
* Почему это отдельное явное поле, а не вывод из того, какая колонка
|
|
5
|
+
* заполнена. Сейчас маршрутизация размазана: расписание выбирается по
|
|
6
|
+
* `profile.integrationType`, а отправка брони — по «есть ли
|
|
7
|
+
* `questroom.partnerAttractionId`, иначе есть ли `integration.postRequest`»
|
|
8
|
+
* (`aggregator-order.service.ts`). У квеста, переехавшего с MyERP на Partner
|
|
9
|
+
* API, старый `postRequest` остаётся в базе, и достаточно потерять связь с
|
|
10
|
+
* attraction, чтобы бронь ушла в прежнюю CRM. В v2 маршрут задаёт ровно одно
|
|
11
|
+
* поле подключения — этот код.
|
|
12
|
+
*/
|
|
13
|
+
export declare enum IntegrationProviderCodeEnum {
|
|
14
|
+
/** Наша собственная CRM: то же расписание через общий интерфейс. */
|
|
15
|
+
CRM = "crm",
|
|
16
|
+
/** Partner Booking API — зеркало Morty-стандарта, реализует партнёр. */
|
|
17
|
+
PARTNER_API = "partner_api",
|
|
18
|
+
/** Легаси: МойЭРП / КвестАдмин / «Мир квестов» — per-quest URL'ы. */
|
|
19
|
+
MYERP = "myerp",
|
|
20
|
+
BOOKEO = "bookeo",
|
|
21
|
+
OFFTHECOUCH = "offthecouch",
|
|
22
|
+
RESOVA = "resova",
|
|
23
|
+
XOLA = "xola",
|
|
24
|
+
BUZZSHOT = "buzzshot",
|
|
25
|
+
REGIONDO = "regiondo",
|
|
26
|
+
FAREHARBOR = "fareharbor",
|
|
27
|
+
/**
|
|
28
|
+
* OCTO — открытый стандарт бронирования для активностей, а не один вендор.
|
|
29
|
+
* Один код на всех, кто его реализует (Ventrata, Zaui, Bókun, Peek Pro, Xola,
|
|
30
|
+
* TuriTop и ещё сотня), потому что коннектор у них общий: различия сводятся к
|
|
31
|
+
* адресу и ключу, то есть к креденшелам подключения.
|
|
32
|
+
*
|
|
33
|
+
* Отдельные коды у `XOLA` и `FAREHARBOR` остаются: у первого есть и свой
|
|
34
|
+
* нативный API, у второго OCTO нет вовсе.
|
|
35
|
+
*/
|
|
36
|
+
OCTO = "octo"
|
|
37
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IntegrationProviderCodeEnum = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Код системы бронирования, за которой стоит конкретный коннектор.
|
|
6
|
+
*
|
|
7
|
+
* Почему это отдельное явное поле, а не вывод из того, какая колонка
|
|
8
|
+
* заполнена. Сейчас маршрутизация размазана: расписание выбирается по
|
|
9
|
+
* `profile.integrationType`, а отправка брони — по «есть ли
|
|
10
|
+
* `questroom.partnerAttractionId`, иначе есть ли `integration.postRequest`»
|
|
11
|
+
* (`aggregator-order.service.ts`). У квеста, переехавшего с MyERP на Partner
|
|
12
|
+
* API, старый `postRequest` остаётся в базе, и достаточно потерять связь с
|
|
13
|
+
* attraction, чтобы бронь ушла в прежнюю CRM. В v2 маршрут задаёт ровно одно
|
|
14
|
+
* поле подключения — этот код.
|
|
15
|
+
*/
|
|
16
|
+
var IntegrationProviderCodeEnum;
|
|
17
|
+
(function (IntegrationProviderCodeEnum) {
|
|
18
|
+
/** Наша собственная CRM: то же расписание через общий интерфейс. */
|
|
19
|
+
IntegrationProviderCodeEnum["CRM"] = "crm";
|
|
20
|
+
/** Partner Booking API — зеркало Morty-стандарта, реализует партнёр. */
|
|
21
|
+
IntegrationProviderCodeEnum["PARTNER_API"] = "partner_api";
|
|
22
|
+
/** Легаси: МойЭРП / КвестАдмин / «Мир квестов» — per-quest URL'ы. */
|
|
23
|
+
IntegrationProviderCodeEnum["MYERP"] = "myerp";
|
|
24
|
+
IntegrationProviderCodeEnum["BOOKEO"] = "bookeo";
|
|
25
|
+
IntegrationProviderCodeEnum["OFFTHECOUCH"] = "offthecouch";
|
|
26
|
+
IntegrationProviderCodeEnum["RESOVA"] = "resova";
|
|
27
|
+
IntegrationProviderCodeEnum["XOLA"] = "xola";
|
|
28
|
+
IntegrationProviderCodeEnum["BUZZSHOT"] = "buzzshot";
|
|
29
|
+
IntegrationProviderCodeEnum["REGIONDO"] = "regiondo";
|
|
30
|
+
IntegrationProviderCodeEnum["FAREHARBOR"] = "fareharbor";
|
|
31
|
+
/**
|
|
32
|
+
* OCTO — открытый стандарт бронирования для активностей, а не один вендор.
|
|
33
|
+
* Один код на всех, кто его реализует (Ventrata, Zaui, Bókun, Peek Pro, Xola,
|
|
34
|
+
* TuriTop и ещё сотня), потому что коннектор у них общий: различия сводятся к
|
|
35
|
+
* адресу и ключу, то есть к креденшелам подключения.
|
|
36
|
+
*
|
|
37
|
+
* Отдельные коды у `XOLA` и `FAREHARBOR` остаются: у первого есть и свой
|
|
38
|
+
* нативный API, у второго OCTO нет вовсе.
|
|
39
|
+
*/
|
|
40
|
+
IntegrationProviderCodeEnum["OCTO"] = "octo";
|
|
41
|
+
})(IntegrationProviderCodeEnum || (exports.IntegrationProviderCodeEnum = IntegrationProviderCodeEnum = {}));
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Состояние привязки внешнего ресурса к нашему квесту. Привязка — самое
|
|
3
|
+
* опасное место интеграции: ошибка здесь означает, что расписание одного
|
|
4
|
+
* квеста показывается на странице другого, а бронь уезжает не туда, куда
|
|
5
|
+
* записался игрок. Поэтому автоматическое сопоставление и подтверждённое
|
|
6
|
+
* различаются на уровне данных.
|
|
7
|
+
*/
|
|
8
|
+
export declare enum IntegrationResourceMatchStatusEnum {
|
|
9
|
+
/** Ресурс найден у вендора, кандидата в каталоге нет. */
|
|
10
|
+
UNMATCHED = "unmatched",
|
|
11
|
+
/**
|
|
12
|
+
* Автоматика нашла кандидата, но уверенности не хватило. Расписание
|
|
13
|
+
* **не показываем** до подтверждения человеком.
|
|
14
|
+
*/
|
|
15
|
+
SUGGESTED = "suggested",
|
|
16
|
+
/** Привязка подтверждена: расписание можно показывать. */
|
|
17
|
+
CONFIRMED = "confirmed",
|
|
18
|
+
/**
|
|
19
|
+
* Ревьюер отклонил кандидата. Хранится, чтобы автоматика не предлагала его
|
|
20
|
+
* снова на каждом синке.
|
|
21
|
+
*/
|
|
22
|
+
REJECTED = "rejected",
|
|
23
|
+
/** Ресурс исчез из выдачи вендора: расписание снимаем. */
|
|
24
|
+
GONE = "gone"
|
|
25
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IntegrationResourceMatchStatusEnum = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Состояние привязки внешнего ресурса к нашему квесту. Привязка — самое
|
|
6
|
+
* опасное место интеграции: ошибка здесь означает, что расписание одного
|
|
7
|
+
* квеста показывается на странице другого, а бронь уезжает не туда, куда
|
|
8
|
+
* записался игрок. Поэтому автоматическое сопоставление и подтверждённое
|
|
9
|
+
* различаются на уровне данных.
|
|
10
|
+
*/
|
|
11
|
+
var IntegrationResourceMatchStatusEnum;
|
|
12
|
+
(function (IntegrationResourceMatchStatusEnum) {
|
|
13
|
+
/** Ресурс найден у вендора, кандидата в каталоге нет. */
|
|
14
|
+
IntegrationResourceMatchStatusEnum["UNMATCHED"] = "unmatched";
|
|
15
|
+
/**
|
|
16
|
+
* Автоматика нашла кандидата, но уверенности не хватило. Расписание
|
|
17
|
+
* **не показываем** до подтверждения человеком.
|
|
18
|
+
*/
|
|
19
|
+
IntegrationResourceMatchStatusEnum["SUGGESTED"] = "suggested";
|
|
20
|
+
/** Привязка подтверждена: расписание можно показывать. */
|
|
21
|
+
IntegrationResourceMatchStatusEnum["CONFIRMED"] = "confirmed";
|
|
22
|
+
/**
|
|
23
|
+
* Ревьюер отклонил кандидата. Хранится, чтобы автоматика не предлагала его
|
|
24
|
+
* снова на каждом синке.
|
|
25
|
+
*/
|
|
26
|
+
IntegrationResourceMatchStatusEnum["REJECTED"] = "rejected";
|
|
27
|
+
/** Ресурс исчез из выдачи вендора: расписание снимаем. */
|
|
28
|
+
IntegrationResourceMatchStatusEnum["GONE"] = "gone";
|
|
29
|
+
})(IntegrationResourceMatchStatusEnum || (exports.IntegrationResourceMatchStatusEnum = IntegrationResourceMatchStatusEnum = {}));
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Операция, которую коннектор выполнял. Журнал разделён по операциям, потому
|
|
3
|
+
* что здоровье подключения по ним разное и смешивать их нельзя: расписание
|
|
4
|
+
* может отдаваться исправно, пока брони не проходят вовсе, и наоборот. Именно
|
|
5
|
+
* это различие сейчас не видно — про недоехавшую бронь мы узнаём от квеста.
|
|
6
|
+
*/
|
|
7
|
+
export declare enum IntegrationRunOperationEnum {
|
|
8
|
+
/** Проверка креденшелов при подключении и по расписанию. */
|
|
9
|
+
VERIFY = "verify",
|
|
10
|
+
/** Синк списка квестов/продуктов аккаунта. */
|
|
11
|
+
LIST_RESOURCES = "list_resources",
|
|
12
|
+
/** Запрос расписания за диапазон дат. */
|
|
13
|
+
SCHEDULE = "schedule",
|
|
14
|
+
/** Перепроверка одного слота перед бронью. */
|
|
15
|
+
CHECK_SLOT = "check_slot",
|
|
16
|
+
/** Удержание слота (режим `hold_then_confirm`). */
|
|
17
|
+
HOLD = "hold",
|
|
18
|
+
/** Создание брони. */
|
|
19
|
+
BOOKING = "booking",
|
|
20
|
+
/** Отмена брони. */
|
|
21
|
+
CANCEL = "cancel"
|
|
22
|
+
}
|