Перейти к основному содержимому

API Contracts — Surface Contracts и правила внешнего взаимодействия

Версия: 2.0
Дата: 23.04.2026
Статус: Готов к обсуждению

Назначение документа

Этот документ фиксирует не просто набор REST endpoints и не попытку заранее заморозить OpenAPI-файл для всей платформы. Его задача — определить, как промышленная платформа должна мыслить свои внешние и внутренние API-контракты, какие surface-ы у неё реально существуют, какие типы запросов они обслуживают, где проходит граница между стабильным контрактом и внутренней доменной реализацией, а также какие правила обязательны для поиска, quote, бронирования, tour builder, identity и governance-сценариев.

Иными словами, этот документ отвечает на вопрос не "как красиво оформить OpenAPI", а "какие контрактные обязательства у платформы вообще есть перед разными типами потребителей, чтобы система оставалась масштабируемой, проверяемой и пригодной для реального промышленного роста".

Опорные документы

Что Второй Несущий Круг Требует От API Contracts

После появления второго круга документов api-contracts.md уже нельзя считать просто “правильным общим документом про surface-ы”.

Теперь контрактный слой обязан явно удерживать следующие требования:

Практический вывод:

API contracts должны описывать не только surface shape, но и честные контрактные обещания относительно истины, видимости, публикации, revalidation и завершённости действия.

Что Исправляет Новый Подход

Старый вариант документа исходил из трёх неверных посылок.

Во-первых, он слишком рано объявлял, что у платформы есть единая финальная OpenAPI 3.0-спецификация для всех сценариев сразу. Для реальной платформы это опасно: на раннем этапе получается не контрактная дисциплина, а фиксация случайного чернового набора endpoint-ов.

Во-вторых, старый документ описывал мир как hotel search -> room availability -> pricing -> booking, то есть вокруг hotelId и roomTypeId. После переосмысления платформы этого уже недостаточно. Внешние контракты должны опираться на offer, quote, booking, tour draft, partner scope, agency scope, identity, commercial context.

В-третьих, старый текст смешивал разные surface-ы как будто они обязаны жить под одним и тем же контрактным лицом. Но internal operations, agency workbench, partner API, client-facing API и service-to-service взаимодействия имеют разную степень стабильности, разный ритм эволюции и разные требования к безопасности, versioning и совместимости.

Новый документ исправляет это и переводит API в правильный порядок:

  1. Сначала определяется surface и его контрактная роль.
  2. Затем определяется доменная ответственность этого surface.
  3. Только потом описываются ресурсы, сценарии, versioning и формат OpenAPI/AsyncAPI/внутренних IDL.

Что Такое API Contracts В Контексте Платформы

В контексте vitiana-api-platform API contracts — это совокупность формальных обязательств платформы перед любым внешним или внутренним потребителем:

  • какие операции доступны;
  • на каких сущностях они работают;
  • какие поля считаются обязательными и стабильными;
  • какие данные являются окончательными, а какие предварительными;
  • какие состояния допустимы;
  • какие ошибки являются бизнес-ошибками, а какие инфраструктурными;
  • как обеспечиваются idempotency, traceability, access control и revalidation.

Контракт здесь не равен конкретному формату сериализации. Один и тот же контрактный смысл может быть выражен через:

  • REST + JSON;
  • webhook / event delivery;
  • внутренний gRPC / Protobuf;
  • batch export;
  • async command / event pattern.

Важно не название технологии, а сохранение одного и того же контрактного смысла и одинаковых доменных гарантий.

Главный Контрактный Принцип

Платформа не должна обещать наружу то, что она ещё не способна гарантировать доменно.

Из этого следуют жёсткие выводы:

  • нельзя публиковать наружу API, будто цена окончательна, если для неё ещё нужна supplier revalidation;
  • нельзя выдавать hotel-level сущность как конечный transactional object, если бронируется на самом деле offer;
  • нельзя путать content read API с booking API;
  • нельзя смешивать internal mutation surfaces и partner integration surfaces;
  • нельзя делать API versioning просто по вкусу команды, без фиксации contract stability policy.

Surface Map Платформы

В рамках текущей логики платформы нужно различать пять основных contract surfaces.

1. Internal Operational Surface

Это внутренний surface для операторов, контент-редакторов, governance-команд, support, finance, ручного review и внутренних административных инструментов.

Для него характерно:

  • более богатая и техническая модель данных;
  • возможность видеть lineage, source precedence, review state, anomaly flags;
  • наличие mutation-операций, которых не должно быть во внешних API;
  • более быстрый темп изменения контрактов;
  • сильная зависимость от внутренних доменных процессов.

Это важный surface, но его нельзя считать образцом для внешнего Partner API. Internal surface может быть богаче, менее дружелюбным и более "операционным".

2. Agency Working Surface

Это рабочий surface для турагентств, агентских кабинетов и внутренних/внешних пользователей, которые собирают предложения, формируют quote, создают и сопровождают booking, работают с клиентом, ведут тур и историю изменений.

Для него характерно:

  • работа с поиском, предложениями, quote и бронированиями;
  • обязательная связь с identity / tenancy / commercial context;
  • потребность в explainable response-ах, пригодных для работы людей;
  • наличие draft/stateful сценариев;
  • требования к auditability и доступу по scope.

Этот surface ближе всего к реальной ежедневной работе платформы. Он не должен быть упрощён до public search API.

3. Partner API Surface

Это внешний стабильный B2B surface для интеграций партнёров, агентств, white-label каналов, реселлеров и потенциальных downstream systems.

Для него характерно:

  • более узкая и стабильная контрактная модель;
  • жёсткий versioning и backward-compatibility policy;
  • чёткие auth scopes, quotas, environment separation;
  • ограниченный доступ к внутренним полям и процессам;
  • сильная ориентация на predictable machine integration.

Partner API должен быть уже и строже, чем internal/agency surfaces. Это не "копия внутреннего API наружу".

4. B2C / Client-Facing Surface

Это surface для клиентских витрин, публичного сайта, мобильных приложений, white-label витрин, customer-facing pages.

Для него характерно:

  • high-volume read-heavy traffic;
  • сильная зависимость от latency и caching policy;
  • минимизация внутренних деталей;
  • акцент на discoverability, clarity и безопасное представление предварительных данных;
  • часто отдельная presentation-oriented агрегация поверх доменного ядра.

Этот surface нельзя заставлять жить по тем же payload-ам, что internal operator UI или partner integration.

5. Service-to-Service Surface

Это внутренние технические контракты между доменными сервисными контурами.

Для него характерно:

  • высокая связность с внутренней доменной моделью;
  • возможность richer event/context payload-ов;
  • другие требования к эволюции;
  • акцент на reliability, idempotency, replayability и observability.

Этот surface не должен проектироваться как будто он сразу является public contract.

Surface-First, Not Endpoint-First

API документ должен строиться не от списка endpoint-ов, а от набора surface-ов и сценариев. Правильная последовательность такая:

  1. Определить тип потребителя.
  2. Определить, какой surface ему нужен.
  3. Зафиксировать доменные use cases этого surface.
  4. Зафиксировать разрешённые ресурсы и операции.
  5. Только потом описывать URI, JSON-schema, pagination и headers.

Это особенно важно для платформы, где один и тот же Offer Service может кормить:

  • internal operations;
  • agency UI;
  • partner integrations;
  • client-facing storefront;
  • downstream async processing.

Сервис может быть общий. Контрактный surface — нет.

Канонические Ресурсные Семейства

На текущем этапе платформы API-контракты должны группироваться вокруг следующих ресурсных семейств.

1. Search Context

Это не просто find hotels. Это контракт на формирование search intent и получение релевантного набора candidate results.

Search contract должен уметь выражать:

  • географический или destination context;
  • временной интервал;
  • occupancy;
  • channel / tenant / user context;
  • языковую и валютную локализацию;
  • фильтры и сортировку;
  • tracing search request;
  • связь результата с последующим quote path.

Search результат не должен выдавать себя за финальное transactional commitment.

2. Property Content

Это read-oriented контракты для канонического контента объекта размещения или иного travel product-а.

Сюда входят:

  • property summary;
  • property detailed content;
  • media;
  • amenities;
  • location and geography;
  • policies;
  • content localization.

Property content — это не booking object и не price commitment.

3. Offer

Это центральное ресурсное семейство платформы. Внешний API должен постепенно смещаться к offer-centric модели.

Offer contract должен выражать:

  • какой supplier/product basis за ним стоит;
  • на какие даты и occupancy он релевантен;
  • какие условия включены;
  • какая price view показывается текущему actor-у;
  • какая freshness у offer;
  • нужна ли revalidation;
  • какие ограничения и policy attached;
  • можно ли из него переходить к quote или booking.

Offer не равен property, room type или просто "цена от".

4. Quote

Quote — это особое ресурсное семейство между offer discovery и booking commitment.

Quote contract нужен там, где платформа обязана:

  • зафиксировать конкретный коммерческий и продуктовый срез;
  • выполнить расчёт цены под tenant/channel/user;
  • отразить applied markups, commissions, fees, taxes, discounts;
  • зафиксировать quote validity window;
  • подготовить проверяемый переход к booking.

Если этот слой не выделен, booking API становится либо слишком хрупким, либо обманчиво простым.

5. Booking

Booking contract — это уже transactional surface, а не read model.

Он должен выражать:

  • вход из quote или explicit booking intent;
  • guest/traveler data;
  • payer/commercial context;
  • booking state machine;
  • supplier confirmation state;
  • cancellation / amendment rules;
  • payment dependency;
  • audit trail и trace identifiers.

Booking contract нельзя сводить к POST /bookings с набором hotel/room полей.

6. Tour Draft / Tour Proposal

Для tour builder платформе нужны stateful контракты отдельного класса.

Они должны позволять:

  • создавать и изменять draft;
  • добавлять продуктовые блоки;
  • работать с вариантами и альтернативами;
  • хранить manual decisions;
  • связывать tour с offers/quotes/bookings;
  • готовить proposal для клиента;
  • генерировать publish/export artifacts без потери traceability.

7. Identity / Tenancy / Access

Это не техническая мелочь, а контрактное ядро.

Почти любой внешний surface должен учитывать:

  • кто делает запрос;
  • к какому tenant он относится;
  • в каком channel/scope работает;
  • какие actor capabilities ему доступны;
  • какой коммерческий контекст применяется;
  • какие объекты он вообще имеет право видеть и изменять.

8. Governance / Review

Эти контракты не должны быть публичными по умолчанию, но они обязательны для industrial platform.

Они нужны для:

  • review cases;
  • anomaly resolution;
  • mapping decisions;
  • conflict explanation;
  • manual overrides;
  • audit and reconciliation.

Типы Контрактов По Степени Стабильности

Не все API в платформе должны жить под одним compatibility regime.

Stable External Contracts

Это partner API и иные публично поддерживаемые интеграционные поверхности.

Для них обязательны:

  • versioning;
  • deprecation policy;
  • additive-first evolution;
  • documented compatibility window;
  • formal changelog;
  • sandbox/prod separation.

Managed Application Contracts

Это контракты для собственных UI-клиентов, agency surfaces и контролируемых first-party clients.

Для них допустима более быстрая эволюция, но при условиях:

  • изменения синхронно отражаются в связанных документах;
  • breaking changes проходят через release discipline;
  • surface semantics не противоречат partner model;
  • field meaning не меняется тихо.

Internal Service Contracts

Это внутренние сервисные и event contracts.

Для них допустима большая подвижность, но обязательны:

  • strong observability;
  • schema discipline;
  • idempotency;
  • replay safety;
  • contract tests на критические потоки.

Основные Контрактные Принципы

1. Offer-Centric Over Hotel-Centric

Снаружи можно продолжать иметь property-oriented read APIs для discovery и content browsing. Но transactional и pricing-sensitive flows должны строиться вокруг offer и quote, а не вокруг hotelId и roomTypeId как якобы достаточного ключа.

2. Explicit Freshness

Любой контракт, связанный с availability, price, cancellation policy, booking feasibility или itinerary viability, должен явно показывать freshness и необходимость revalidation.

3. No Hidden Commercial Logic

Если цена зависит от tenant, partner, agency, markup policy, commission agreement, user scope или currency policy, контракт должен либо явно включать эту зависимость, либо жёстко фиксировать, какая price view возвращается.

3A. Quoted Promise Must Be Traceable

Если surface возвращает Quote, контракт обязан позволять понять:

  • что именно считается quoted promise;
  • какая commercial policy была применена;
  • действует ли quote ещё сейчас;
  • произошёл ли revalidation или repricing;
  • может ли downstream consumer считать эту цену final visible promise или только intermediate working state.

4. Read Model And Commit Model Are Different

Search results, property pages, indicative offers и cached previews не должны маскироваться под commit-ready objects.

5. Actor And Scope Are Contractual

Auth недостаточно. Контракт должен учитывать actor type, tenant scope, role scope и commercial scope.

6. Publication State Must Be Honest

Контракт обязан различать:

  • internal working object;
  • externally visible object;
  • proposal artifact;
  • governance-cleared published state;
  • draft or pending state, ещё не пригодный для внешнего обещания.

7. Errors Must Be Actionable

Ошибки должны быть пригодны не только для логов, но и для автоматической обработки и human recovery.

8. Contract Meaning Must Outlive Technology

REST today, gRPC tomorrow, webhooks later — но meaning offer_revalidation_required или booking_pending_supplier_confirmation не должен меняться от транспорта.

Search And Discovery Contracts

Search surface нужен как отдельный класс контрактов.

Что Он Должен Принимать

  • destination context;
  • travel dates;
  • occupancy/travel party;
  • filters;
  • sorting;
  • localization;
  • actor/tenant/channel context;
  • optional search strategy hints;
  • pagination or cursor model.

Что Он Должен Возвращать

  • список candidate results;
  • summary content;
  • indicative pricing or offer summary;
  • filter facets;
  • trace/search identifier;
  • freshness hints;
  • next action affordances.

Что Он Не Должен Обещать

  • что любой result уже готов к booking;
  • что price окончательная;
  • что supplier availability точно жива без revalidation;
  • что hotel entity сама по себе является transactional unit.

Offer And Quote Contracts

Это главный контрактный переход от "что найдено" к "что можно реально продавать и бронировать".

Offer Contract Должен Включать

  • offer_id;
  • ссылку на underlying product context;
  • property/product summary;
  • occupancy and date scope;
  • currency and price view;
  • policy summary;
  • applied inclusions/exclusions;
  • freshness timestamps;
  • revalidation requirement;
  • optional commercial labels;
  • eligibility for quote/booking.

Quote Contract Должен Включать

  • quote_id;
  • source offer reference;
  • quote creation time;
  • quote validity window;
  • actor/tenant/commercial context;
  • workspace or ownership context, where applicable;
  • final visible price breakdown;
  • commercial policy reference or contract-safe policy descriptor;
  • cancellation and change implications;
  • assumptions and unresolved constraints;
  • freshness / revalidation basis;
  • repricing semantics or repricing-required signal;
  • publication scope/readiness;
  • next-step contract for booking submission.

Что Quote Contract Должен Явно Различать

  • indicative price vs quoted price;
  • quoted price vs booking-time confirmed price;
  • quoted promise vs settlement-relevant downstream figures;
  • revalidation-required vs repricing-required;
  • internal monetary breakdown vs presentation-safe public view.

Практический Вывод

Для партнёров и agency surfaces цена не должна оформляться как "всегда бери hotelId и считай дальше сам". Платформа должна уметь выдавать более честный и более устойчивый transactional handoff через offer/quote.

Booking Contracts

Booking — это домен повышенной строгости.

Booking Contract Должен Строиться Вокруг

  • booking intent;
  • source quote or equivalent validated context;
  • traveler data;
  • payer data;
  • contact data;
  • commercial ownership;
  • actor context and tenant/workspace ownership;
  • supplier placement attempt;
  • internal booking state;
  • external supplier state;
  • payment state, если применимо;
  • settlement-aware follow-up, если surface имеет право это видеть;
  • cancellation/amendment path.

Базовые Доменные Состояния Booking Surface

  • draft
  • submitted
  • pending_revalidation
  • pending_supplier_confirmation
  • confirmed
  • partially_confirmed
  • failed
  • cancel_requested
  • cancelled
  • amendment_in_progress
  • completed

Конкретная state machine ещё должна быть вынесена в отдельный документ второго слоя, но surface уже обязан исходить из того, что booking lifecycle сложнее, чем pending/confirmed/cancelled.

Критические Контрактные Правила Для Booking

  • создание booking должно быть idempotent;
  • должен существовать client-supplied idempotency key для create/confirm-like операций;
  • booking response должен не скрывать pending-state;
  • supplier booking identifier не может подменять platform booking identifier;
  • cancellation и amendment — это отдельные управляемые операции, а не просто DELETE;
  • history и audit identifiers должны быть доступны хотя бы внутренним и agency-oriented surface-ам.
  • booking contract не должен делать вид, что quoted promise и settlement reality всегда совпадают без остатка.

Tour Builder Contracts

Tour builder нельзя описывать как набор случайных CRUD-операций над "турами".

Контрактный Смысл Tour Builder

Tour builder — это stateful composition surface, в котором:

  • создаются draft-сценарии;
  • собираются элементы маршрута;
  • сопоставляются предложения и альтернативы;
  • фиксируются ручные решения;
  • формируется клиентский proposal;
  • при необходимости отдельные части переходят в booking.

Что Должен Поддерживать Surface

  • создание и чтение draft;
  • patch/update draft blocks;
  • variant handling;
  • attaching offers/quotes;
  • hotel/product replacement without loss of history;
  • pricing recalculation;
  • validation against itinerary rules;
  • proposal versioning;
  • export/publication actions;
  • link to downstream booking artifacts.

Что Нельзя Делать

  • сводить tour builder к одному POST /tours;
  • хранить только "финальную PDF-программу";
  • терять связь между draft decision и underlying offers;
  • смешивать публичный клиентский proposal и внутренний рабочий draft как один и тот же объект.

Identity, Tenancy, Access And Commercial Context

API contracts платформы должны быть actor-aware по определению.

Контракт Обязан Учитывать

  • user identity;
  • actor type;
  • tenant or agency ownership;
  • partner integration identity;
  • delegated access;
  • role or capability scope;
  • commercial profile;
  • environment separation.

Практически Это Означает

  • одинаковый запрос от разных actor-ов может иметь разный допустимый scope;
  • одинаковый offer может вернуться с разным visible price view;
  • одинаковый offer может перейти в разные quote contracts с разным breakdown visibility;
  • одинаковый quote_id не обязан быть видим или валиден вне своего tenant/workspace context;
  • часть mutation-операций доступна только internal/agency actors;
  • часть полей должна быть скрыта на partner or client-facing surfaces;
  • API key scope и user session scope не являются взаимозаменяемыми сущностями.

Commercial Context As Contract Surface Concern

После фиксации Commercial Model — Коммерческая модель, цена, settlement и канальные условия контрактный слой обязан признавать, что цена сама по себе является surface-sensitive сущностью.

Это Означает

  • agency surface может получать richer price breakdown;
  • partner API surface может получать contract-safe machine-readable monetary structure;
  • B2C surface может получать только presentation-safe visible price;
  • internal operational surface может видеть override source, policy trace и settlement preparation context.

Контракт при этом не обязан раскрывать всем один и тот же объём коммерческой информации, но он обязан честно фиксировать, какая именно price view возвращена.

Аутентификация И Авторизация

На уровне документов платформе нужно мыслить не "JWT или API key", а уровни subject authentication.

Возможные Классы Auth

  • first-party user sessions;
  • agency user access tokens;
  • partner API keys;
  • service-to-service credentials;
  • webhook signing credentials;
  • sandbox credentials.

Что Должно Быть Зафиксировано Для Каждого Класса

  • кто является субъектом;
  • какой surface доступен;
  • какие scopes/capabilities доступны;
  • какие rate limits применяются;
  • какая rotation policy требуется;
  • как происходит revocation;
  • как разделяются sandbox и production.

Версионирование Контрактов

Версионирование должно идти не по внутренней структуре кода, а по public contract boundary.

Для External Partner API Обязательно

  • явная major/minor version policy;
  • additive changes как основной путь эволюции;
  • documented deprecation window;
  • дата отключения старых версий;
  • release notes для интеграторов.

Для First-Party Application Surfaces

  • допускается более подвижная эволюция;
  • breaking changes допустимы только как управляемое изменение связанного приложения;
  • всё равно нужна фиксация контрактного смысла и changelog хотя бы на уровне docs.

Для Internal Service Contracts

  • допустимы schema migrations без public versioning facade;
  • но критические event contracts должны иметь schema compatibility discipline.

Идемпотентность, Повторы И Безопасность Повторной Доставки

Для industrial platform это не факультативная деталь.

Контракты для create / submit / confirm / cancel / publish / dispatch-like операций должны учитывать:

  • client retries;
  • duplicate submissions;
  • network timeouts;
  • webhook redelivery;
  • background job reprocessing;
  • supplier-side partial response scenarios.

Обязательные Механизмы

  • idempotency key для критических mutation endpoints;
  • deduplication semantics;
  • trace identifiers;
  • retry-safe response model;
  • distinction between accepted, processing, completed, failed.

Ошибки И Отказы

Ошибки должны быть разделены по смыслу, а не только по HTTP status.

Минимальные Классы Ошибок

  • validation errors;
  • authentication/authorization errors;
  • scope violations;
  • resource state conflicts;
  • revalidation required;
  • supplier unavailable;
  • commercial rule violation;
  • rate limiting;
  • transient infrastructure failure;
  • asynchronous processing delay.

Error Contract Должен Давать

  • machine-readable code;
  • human-readable message;
  • request/correlation id;
  • optional field-level details;
  • retry hint или явный запрет на retry;
  • next action guidance, где это возможно.

Особенно важно отделять:

  • offer_not_found от offer_not_visible_for_scope;
  • booking_conflict от booking_revalidation_required;
  • supplier_timeout от platform_processing_pending.

Пагинация, Фильтрация, Сортировка

Контрактная дисциплина здесь нужна так же, как в транзакционных flow.

Базовые Правила

  • list endpoints не должны возвращать неограниченные выборки;
  • pagination strategy должна быть согласованной внутри surface-а;
  • для high-volume result sets предпочтителен cursor-based подход;
  • filters должны быть explicit и documented;
  • sort semantics должны быть стабильны внутри версии контракта.

Практический Вывод

Не нужно насильно стандартизировать весь мир под один page/pageSize, если search surface и governance review queue имеют разные operational characteristics. Но внутри каждого surface-а стратегия должна быть единообразной.

Локализация И Валюты

Контракты платформы должны быть готовы к мультиязычности и multi-currency работе, но без подмены доменной истины.

Для Локализации Нужно Различать

  • source language;
  • canonical language policy;
  • requested presentation language;
  • fallback behavior;
  • localized content fields;
  • non-localizable operational fields.

Для Валют Нужно Различать

  • supplier/source currency;
  • canonical settlement currency, где применимо;
  • quote display currency;
  • booking payment currency;
  • conversion reference and timestamp.

Нельзя допускать ситуацию, где API возвращает цену "в EUR", но неясно, это supplier amount, converted display amount или уже tenant-specific commercial amount.

Что Commercial Model Требует От API Contracts

После фиксации коммерческого слоя api-contracts.md должен явно удерживать:

  • Quote как contract-grade commercial promise;
  • repricing как отдельную контрактную реальность, а не неявное изменение цены;
  • разные уровни видимости monetary breakdown для agency, partner, B2C и internal surfaces;
  • различие между booking confirmation flow и downstream settlement-aware reporting or eventing;
  • обязательную traceability applied commercial policy там, где это влияет на смысл returned price.

Webhooks И Async Delivery Contracts

Платформе почти наверняка понадобится не только request/response API.

Типовые События Для Внешних Или Полувнешних Surface-ов

  • booking status changed;
  • booking confirmation received;
  • booking failed;
  • quote expired;
  • tour proposal published;
  • reconciliation issue detected;
  • governance review completed.

Для Webhook/Event Contracts Обязательны

  • stable event type names;
  • event identifiers;
  • delivery timestamps;
  • signature verification;
  • retry/redelivery semantics;
  • ordering assumptions или честное признание их отсутствия;
  • versioning of payload schema.

Что Важно Для Publication And Governance Events

Если платформа публикует события вроде tour proposal published, governance review completed или booking status changed, контракт обязан быть честным относительно:

  • является ли это окончательным published fact или промежуточным internal transition;
  • какой actor/tenant/surface инициировал переход;
  • требует ли следующий шаг дополнительной revalidation или manual review;
  • может ли downstream consumer безопасно трактовать событие как final business fact.

OpenAPI, AsyncAPI И Внутренние IDL

Из этого документа не следует, что OpenAPI не нужен. Наоборот, он нужен, но как производный артефакт.

Правильный Порядок Такой

  1. Сначала surface contract model.
  2. Затем ресурсные семейства и доменные сценарии.
  3. Затем compatibility policy.
  4. Затем machine-readable specs:
    • OpenAPI для REST surfaces;
    • AsyncAPI для event/webhook contracts;
    • protobuf/IDL для service-to-service contracts.

Что Это Меняет Практически

Новый api-contracts.md не пытается делать вид, что весь surface уже описан одной финальной YAML-спецификацией. Вместо этого он задаёт правила, по которым эти спецификации должны дальше рождаться и проверяться.

Минимальный Каркас Будущих Спецификаций

Когда платформа перейдёт к следующему уровню детализации, machine-readable спецификации нужно будет разворачивать как минимум по следующим наборам:

External Partner API

  • search endpoints;
  • property content endpoints;
  • offer endpoints;
  • quote endpoints;
  • booking endpoints;
  • webhook subscriptions/events;
  • auth and key management surface.

Agency Working API

  • search and offer workspace;
  • quote operations;
  • booking operations;
  • tour draft/proposal operations;
  • client/workspace context;
  • operational history and audit-friendly reads.

Internal Operations API

  • governance queues;
  • mapping/review actions;
  • anomaly cases;
  • manual overrides;
  • manual lock actions;
  • reconciliation tools;
  • support and finance-specific reads/actions.

Service-to-Service Contracts

  • ingestion update events;
  • canonical content publication events;
  • offer refresh events;
  • booking state events;
  • governance decision events.

Что Должно Быть Перепроверено После Этого Документа

После фиксации нового подхода нужно пересмотреть и синхронизировать следующие документы:

Роль Старых Черновиков

Старый вариант документа не нужно считать бесполезным. Он полезен как источник ранних идей о поиске, базовых endpoint-группах, auth-механизмах, pagination и shape response-ов. Но его нельзя больше считать актуальным архитектурным основанием, потому что он:

  • преждевременно фиксировал OpenAPI как финальный слой;
  • описывал hotel-centric контрактный мир;
  • смешивал partner, user и internal semantics;
  • слишком рано объявлял "один API для всех" как уже решённую проблему.

Старый текст сохранён в архивной версии:

Текущий Практический Вывод

Для vitiana-api-platform API больше нельзя описывать как простой список REST endpoints поверх отелей, комнат и бронирований. Платформе нужен surface-based, offer-centric, actor-aware и contract-disciplined подход.

Это означает:

  • внешний API должен вырастать из доменной модели, а не заменять её;
  • partner contracts должны быть уже и стабильнее внутренних;
  • search/content, offer/quote и booking contracts должны быть разведены;
  • quote и booking path нужно считать отдельным обязательным уровнем зрелости;
  • будущие OpenAPI и AsyncAPI артефакты должны строиться уже на этой основе.

Уточнение под Фазы 4–7 (28.04.2026) — обновлённая Surface Map и связи с новыми доменами

После Фаз 4–7 каноничной архитектуры (24–27.04.2026) Surface Map платформы расширена и интегрирована с новыми доменами. Этот документ остаётся как базовый каркас контрактной дисциплины (surface-first, offer-centric, actor-aware), но детальные surface boundaries и интеграции с фазами 4–6 — в специализированных источниках.

Surface Map — обновление с 5 на 6 поверхностей

В этом документе зафиксировано 5 surfaces (Internal Operational, Agency Working, Partner API, B2C / Client-Facing, Service-to-Service). Каноничная архитектура в overview/layers.md (версия 3.0 от 25.04.2026) фиксирует 6 surfaces — добавлена Tour Builder Closed Surface как отдельный коммерческий контракт.

Каноничные 6 surface contracts (источник истины — layers.md):

#SurfaceТип контрактаКоммерческая модель
1Internal Operationalвнутренний — нет внешнего контракта
2Agency Workingfirst-party — managed applicationподписка + комиссия
3Partner APIвнешний stable contract с версионированиемdynamic pricing per tier (Free/Starter/Professional/Enterprise)
4B2C Storefrontfirst-party — managed presentationмаржа платформы на туристических продуктах
5Service-to-Serviceвнутренний между сервисами
6Tour Builder Closedспециальный paid contractотдельный paid tier (Professional+)

Tour Builder Closed Surface был перечислен в этом документе как resource family (раздел «6. Tour Draft / Tour Proposal»), но в каноничной архитектуре он выделен как отдельный surface contract с собственной коммерческой моделью (не часть Partner API tier).

Соответствие с client surfaces (clients.md)

Согласно reference/clients.md (Фаза 7) и уточнению в overview/layers.md, существуют две ортогональные таксономии:

  • Surface Contracts (этот документ + layers.md) — формально-контрактная сторона;
  • Client Surfaces (clients.md) — продуктовая декомпозиция UI/SDK.

При проектировании контракта API использовать Surface Contracts; при проектировании UI/SDK packaging — Client Surfaces. Полное соответствие — в layers.md, секция «Уточнение под Фазу 7».

Каноничные ресурсные семейства — расширение под Фазы 4–6

В этом документе перечислены 8 ресурсных семейств (Search, Property, Offer, Quote, Booking, Tour Draft/Proposal, Identity/Tenancy, Governance/Review). После Фаз 4–6 добавились новые каноничные домены, требующие собственных contract families:

Дополнительное ресурсное семействоКаноничный источникPhase
Payment (PaymentIntent, Refund, Chargeback, Settlement, PayoutBatch, PaymentMethod)payment-domain.md4
Notifications (NotificationTemplate, NotificationEvent, ConsentLog, Webhook)notification-and-communication.md4
Media & Content (MediaAsset, ContentBundle, ContentTranslation)media-and-content.md4
i18n (SupportedLanguage, SupportedCurrency, FxRateSnapshot)internationalization-and-localization.md4
Analytics (analytical projections, partner-facing dashboards)analytics-and-bi.md4
A/B Testing (Experiment, Variant, Assignment, Exposure, FeatureFlag)ab-testing-platform.md4
API as Product (Partner, PartnerApplication, ApiKey, Tier, Quota)api-as-product.md4
Search & Discovery (SearchProjection, RankingPolicy, расширение Search context)search-and-discovery.md4
Booking State Machine (14 каноничных состояний, transitions)booking-state-machine.md5
Tour Builder Operational (CompositionRule, TourBookingTransaction saga, DriftEvent)tour-builder-operational-model.md5
Multi-Tenant Isolation (isolation_level, IsolationBoundaryCheck, CrossTenantAccess)multi-tenant-isolation-strength.md5
Compliance (DSR API, ConsentLog, BreachNotificationLog)compliance-and-legal.md4

Каждое семейство имеет свои контрактные правила (versioning, visibility, rate limits) согласно tier модели в api-as-product.md.

Принцип OpenAPI-first для polyglot

Согласно открытому proposal development/proposal-openapi-first-polyglot-codegen.md:

  • все sync API контракты — single source of truth в формате OpenAPI 3.1;
  • все async API — AsyncAPI;
  • code generation per language (oapi-codegen для Go, OpenAPI Generator для остальных);
  • documentation portal через Redoc (public) + Swagger UI (sandbox).

Этот proposal — открытый вопрос на стадию 1 implementation baseline, но фиксирует направление развития контрактной дисциплины.

Связь с программным интерфейсом как продуктом

Согласно reference/api-as-product.md:

  • Partner API Surface имеет 4 tier (Free / Starter / Professional / Enterprise);
  • каждый tier определяет SLA, rate limits, isolation level, DR class, certification обязательства;
  • partner lifecycle — sandbox → certification → production → deprecation;
  • versioning — explicit version в URL, deprecation ≥ 6 месяцев notice;
  • Tour Builder Closed Surface — доступен только Professional+ tier с отдельным paid доступом.

Связь с safety / compliance / security

  • Compliance (compliance-and-legal.md) — каждый external surface имеет собственные регуляторные обязательства (GDPR DSR API, PSD2 SCA для платежей, EU TOMS VAT, Package Travel Directive для Tour Builder);
  • Security architecture (security-architecture.md) — каноничная STRIDE threat model, IAM RBAC+ABAC, encryption at-rest/in-transit, secret lifecycle. Каждый surface имеет своё authentication level (Internal — Level 2 MFA, Partner Machine — signed requests, B2C — Level 1 baseline + Level 2 для payment);
  • IsolationBoundaryCheck (multi-tenant-isolation-strength.md) — continuous automated check для всех contract surfaces, target 0 cross-tenant breaches за rolling 90 дней.

Каноничный итог уточнения

Этот документ остаётся как базовый каркас контрактной дисциплины платформы: surface-first thinking, offer-centric over hotel-centric, explicit freshness, no hidden commercial logic, contract-disciplined evolution. Расширения и реализация:

При конфликте с этим документом — истина в каноничном специализированном (правило single source of truth per domain).

Уточнение выполнено через no-destruction.

Связанная Документация