Domain Model — Центральная доменная модель платформы
Версия: 1.0
Дата: 23.04.2026
Статус: Готов к обсуждению
Назначение документа
Этот документ фиксирует центральную доменную модель vitiana-api-platform как главный смысловой каркас всей платформы.
Его задача — жёстко определить:
- какие сущности являются каноническими;
- какие сущности являются supplier-derived, operational или transactional;
- где проходят границы ответственности между сущностями;
- как сущности связаны между собой;
- какие жизненные циклы являются ключевыми;
- где находятся источники истины;
- какие доменные различия нельзя больше размывать в других документах.
Пока такой документ не зафиксирован, все остальные материалы будут продолжать либо спорить друг с другом, либо подменять домен UI, API, БД или инфраструктурой.
Опорные документы
- Архитектурная основа платформы vitrip.store
- Главные выводы и проблемные зоны платформы
- Documentation Master Plan — Project 15 Structure Snapshot
- Business Services — Сервисная декомпозиция платформы
- Database Schema — Каноническая модель хранения платформы
- Storage Layer — Модель хранения и жизненный цикл данных
- Ingestion Layer — Приём, нормализация, маппинг и governance
- API Contracts — Surface Contracts и правила внешнего взаимодействия
- Clients Layer — Клиентские поверхности и рабочие модели
- Suppliers Layer — Поставщики, source boundaries и управление внешней реальностью
Почему Это Главный Документ Следующего Слоя
В Главные выводы и проблемные зоны платформы зафиксировано, что самая важная незакрытая проблема — отсутствие канонической доменной модели.
Практический смысл этого вывода простой:
- без неё
database-schema.mdрискует быть либо слишком ранним, либо слишком механическим; - без неё
api-contracts.mdбудет вынужден гадать, какие resource families являются настоящими; - без неё
clients.mdиbusiness-services.mdбудут описывать разные представления одной и той же реальности; - без неё
identity,offer,quote,booking,tour builderиgovernanceостанутся распылёнными по нескольким документам.
Поэтому этот документ должен стать смысловой опорой для следующих шагов.
Главный Доменный Принцип
Платформа строится не вокруг "отеля", не вокруг "API", не вокруг "бронирования" и не вокруг "сайта". Она строится вокруг канонического продуктового ядра, которое соединяет:
- stable content and inventory identity;
- supplier-specific product reality;
- operational offer state;
- commercial and quote context;
- transactional booking state;
- tour composition and proposal lifecycle.
Это означает, что доменная модель платформы должна одновременно удерживать:
- стабильное и изменчивое;
- каноническое и supplier-specific;
- read-oriented и commit-oriented;
- human-facing и machine-facing;
- внутреннее и внешнее.
Главные Классы Доменных Сущностей
На текущем этапе сущности нужно различать по их роли в truth-модели платформы.
1. Canonical Master Entities
Это долгоживущие сущности платформенного ядра.
Сюда входят:
PropertyCanonicalProductOrganizationUserPartnerAgencyPolicySetGovernanceDecision
2. Supplier-Derived Entities
Это сущности, которые выражают supplier reality и не должны маскироваться под canonical truth.
Сюда входят:
SupplierSupplierPropertySupplierProductSupplierPayloadSupplierSyncRunSupplierCapabilityProfileSupplierBookingReference
3. Operational Offer Entities
Это сущности краткоживущего, но доменно важного операционного слоя.
Сюда входят:
OfferAvailabilitySnapshotPriceSnapshotQuoteRevalidationResultSearchSession
4. Transactional Entities
Это сущности транзакционного и audit-critical слоя.
Сюда входят:
BookingBookingItemBookingEventPaymentIntentRefundAmendmentRequest
5. Composition Entities
Это сущности, связанные со сборкой составного продукта.
Сюда входят:
TourDraftTourDraftItemTourProposalProposalVersionProposalArtifact
6. Governance And Review Entities
Это сущности управления качеством, конфликтами и ручным решением.
Сюда входят:
ReviewCaseMappingDecisionMergeDecisionAnomalyFieldLineageSourcePrecedenceRule
7. Identity, Tenancy And Access Entities
Это сущности организационного и access-контекста.
Сюда входят:
TenantWorkspaceRoleAssignmentCapabilityGrantApiClientApiCredential
Канонические Сущности Платформенного Ядра
Ниже зафиксированы сущности, без которых платформа не может считаться доменно определённой.
1. Property
Property — каноническая мастер-сущность объекта размещения как устойчивого объекта платформы.
Она отвечает за:
- доменную идентичность объекта;
- канонический адрес и географическую привязку;
- устойчивые категории и классификацию;
- базовый контентный каркас;
- связь с регионами и destination model;
- привязку supplier representations к одной платформенной сущности.
Property не является:
- ценой;
- доступностью;
- booking unit;
- supplier truth;
- готовым к продаже offer.
2. SupplierProperty
SupplierProperty — supplier-specific представление того, что потенциально соответствует Property.
Оно нужно для:
- хранения supplier IDs;
- traceability источника;
- различий в контенте и структуре;
- понимания, какие поля пришли от какого source;
- mapping and merge logic.
SupplierProperty не должен напрямую подменять canonical Property.
3. CanonicalProduct
CanonicalProduct — каноническая продуктовая единица внутри property context.
Она нужна, чтобы не мыслить всё только через room_type, потому что в реальном travel domain продуктовая единица может включать:
- тип размещения;
- occupancy capacity;
- meal semantics;
- cancellation semantics;
- supplier-specific variants;
- policy-sensitive distinctions.
CanonicalProduct — это не обязательно окончательная sellable единица. Но это базовый стабильный продуктовый каркас платформы.
4. SupplierProduct
SupplierProduct — supplier-specific продаваемая или квазипродаваемая единица.
Она важна для:
- связи с supplier property;
- mapping to canonical product;
- понимания supplier-specific условий;
- offer generation;
- booking correlation.
5. Offer
Offer — центральная operational сущность платформы.
Именно Offer является основной единицей:
- для показа;
- для сравнения;
- для перехода к quote;
- для revalidation;
- для потенциального booking intent.
Offer должен описывать:
- product basis;
- property context;
- supplier basis;
- date scope;
- occupancy scope;
- price view;
- availability status;
- cancellation and restriction summary;
- freshness and validity hints;
- eligibility for next action.
Offer не является:
- stable master entity;
- окончательным booking commitment;
- простой hotel-card summary.
6. Quote
Quote — это фиксированный коммерческий и операционный снимок, который связывает Offer с конкретным actor/tenant/channel context.
Он нужен, когда платформа должна зафиксировать:
- что именно было выбрано;
- какая price view была рассчитана;
- какие assumptions действовали;
- как долго эта фиксация считается пригодной;
- на каких условиях возможен переход к booking.
Quote — не просто "пересчитанная цена". Это самостоятельная доменная единица между discovery и booking commitment.
7. Booking
Booking — транзакционная сущность платформы, отражающая попытку, процесс и результат коммерческого commit-действия.
Она должна удерживать одновременно:
- platform booking identity;
- source quote or validated context;
- traveler data;
- payment/commercial context;
- supplier-side correlation;
- state machine;
- audit trail;
- failure and amendment history.
Booking не должен мыслиться как простая запись выбора отеля.
8. TourDraft
TourDraft — рабочая композиционная сущность, позволяющая собрать будущий продукт без обязательного немедленного commit-а.
Она нужна для:
- работы агентства;
- подготовки вариантов;
- ручной сборки маршрута;
- добавления и замены элементов;
- экспериментирования с составом предложения.
9. TourProposal
TourProposal — коммерчески представляемая форма собранного продукта.
Она должна:
- иметь versioning;
- фиксировать состав продукта на момент предложения;
- связываться с клиентским или partner-facing presentation;
- сохранять trace to underlying draft, offers and quotes.
10. Organization Family
Платформа не может ограничиться одной сущностью "компания". Уже сейчас нужно различать:
AgencyPartnerInternalOrganizationUnit, если понадобитсяTenant
Потому что эти сущности имеют разную роль в:
- коммерческой модели;
- доступе;
- API contracts;
- видимости данных;
- reporting and settlement.
11. User And Actor
User как identity-сущность недостаточен сам по себе. В платформе важно различать:
- identity субъекта;
- организационную принадлежность;
- рабочий контекст;
- capability scope;
- actor type в конкретном сценарии.
Поэтому User и ActorContext должны мыслиться раздельно, даже если в БД часть этого хранится совместно.
Связи Между Главными Сущностями
Ниже — не ERD, а смысловая карта связей.
Property ↔ SupplierProperty
- один
Propertyможет иметь многоSupplierProperty; - один
SupplierPropertyдолжен вести к одному canonical mapping outcome в конкретный момент времени; - mapping может быть auto, reviewed or unresolved.
Property ↔ CanonicalProduct
- один
Propertyсодержит один или многоCanonicalProduct; CanonicalProductне обязан один в один соответствовать supplier room type.
CanonicalProduct ↔ SupplierProduct
- один canonical product может иметь много supplier products;
- один supplier product может быть unmapped, ambiguously mapped or explicitly mapped.
SupplierProduct ↔ Offer
- один supplier product может порождать много
Offerпо датам, occupancy и policy combinations; Offerвсегда должен сохранять trace to supplier basis.
Offer ↔ Quote
- один offer может порождать много quote-ов;
- quote всегда фиксирует actor/channel/commercial context;
- quote должен уметь стареть и истекать.
Quote ↔ Booking
- booking ideally должен возникать из quote или equivalent validated basis;
- один quote может привести к нулю, одному или нескольким booking-related actions, в зависимости от домена;
- booking не должен терять связь с quote basis.
TourDraft ↔ Offer / Quote / Booking
- draft может включать offers and quotes;
- proposal может ссылаться на несколько underlying quote snapshots;
- часть draft/proposal элементов может перейти в booking artifacts;
- при этом композиционный слой не должен терять traceability.
Organization / Tenant / User ↔ Quote / Booking / Proposal
- quote виден и валиден в конкретном actor context;
- booking имеет ownership and responsibility context;
- proposal создаётся не "анонимным UI", а конкретным actor в конкретном tenancy/commercial scope.
Truth Boundaries Между Сущностями
Одна из самых важных задач этого документа — развести truth boundaries.
Stable Master Truth
К ней относятся:
Property- часть
CanonicalProduct Organization/Tenant/UseridentityPolicySet- reviewed governance outcomes
Supplier Truth
К ней относятся:
SupplierPropertySupplierProductSupplierPayload- supplier-specific policy fragments
- source-side availability and price signals
Operational Truth
К ней относятся:
OfferAvailabilitySnapshotPriceSnapshotQuoteRevalidationResult
Transactional Truth
К ней относятся:
BookingBookingEventPaymentIntentRefundAmendmentRequest
Governance Truth
К ней относятся:
ReviewCaseMergeDecisionMappingDecisionFieldLineageSourcePrecedenceRule
Эти truth layers нельзя смешивать в одни и те же поля и одни и те же API-объекты без явного указания.
Главные Доменные Границы
1. Property Boundary
Это граница stable identity and content.
Она не должна включать:
- quote state;
- booking state;
- volatile price truth.
2. Offer Boundary
Это граница между stable product basis и short-lived commercially meaningful opportunity.
Именно здесь сходятся:
- supplier-derived signals;
- availability;
- pricing;
- restrictions;
- actionability.
3. Quote Boundary
Это граница между actionable opportunity и actor-specific commercial fixation.
Без этой границы platform contracts будут либо нечестными, либо нестабильными.
4. Booking Boundary
Это граница commit-oriented transactional state.
Здесь уже нельзя мыслить сущность как read model.
5. Tour Composition Boundary
Это граница составного продукта, который живёт поверх offer/quote/booking, но не редуцируется к ним.
6. Governance Boundary
Это граница, где автоматизация заканчивается и начинается управляемое объяснимое решение.
Жизненные Циклы, Которые Нужно Считать Основными
Обновление под Фазы 5–6 каноничной архитектуры (28.04.2026)
После Фаз 4–6 каноничной архитектуры (25–27.04.2026) ряд жизненных циклов и составов сущностей этого документа дополнен и углублён в специализированных документах второго круга. Этот документ остаётся как сводный базовый каркас, но детальная истина по жизненным циклам теперь живёт в специализированных документах ниже.
Booking lifecycle — каноничная истина в booking-state-machine.md
Запись в этом документе («draft intent → submitted → pending revalidation → pending supplier confirmation → confirmed / failed → amended / cancelled / completed») — упрощённая для смыслового каркаса. Каноничная истина — 14 состояний в reference/booking-state-machine.md:
draft_intent → submitted → pending_revalidation
→ pending_supplier_confirmation
→ supplier_confirmed → platform_confirmed
→ partially_failed
→ failed
→ unknown_external_state ← критическое 8-е состояние
→ cancel_requested → cancel_pending → cancelled
→ amendment_requested → amendment_in_progress
→ completed
Ключевые отличия каноничной модели от упрощённой записи выше:
confirmedразделён наsupplier_confirmed(ack от поставщика) иplatform_confirmed(запись в платформенной transactional truth) — это разные истины, нельзя смешивать (правило 00000);- появилось каноничное состояние
unknown_external_state— поставщик не отвечает или ответил некорректно, платформа не знает существует ли бронирование. Это базовый SLI платформы (см. operations/sla-and-on-call-model.md, SLI 6, target менее 1%); cancelledразделён на 3 шага (cancel_requested → cancel_pending → cancelled) для корректной обработки supplier-side delays;amendmentразделён на 2 шага (amendment_requested → amendment_in_progress).
Все internal/agency/operator контракты обязаны различать эти состояния.
TourDraft / TourProposal lifecycle — каноничная истина в tour-builder-operational-model.md
Запись в этом документе («draft → iterated → proposed → versioned → partially consumed / archived») — упрощённая. Каноничная истина в overview/canonical-domain-spine.md и reference/tour-builder-operational-model.md:
TourDraft lifecycle:
created → editing → structured
→ awaiting_repricing ← подождать актуализацию цен
→ awaiting_revalidation ← подождать revalidation underlying offers
→ ready_for_proposal
→ archived
TourProposal lifecycle:
prepared → published → shared → viewed
→ superseded → expired → accepted_for_conversion → archived
Ключевое отличие: появились состояния ожидания (awaiting_repricing, awaiting_revalidation) — отражают, что Tour Builder работает поверх operational truth (Offer/Quote), которая может устареть, и композиция должна явно ждать обновления, не публиковать stale данные.
Composition entities — расширение состава
В этом документе перечислены: TourDraft, TourDraftItem, TourProposal, ProposalVersion, ProposalArtifact.
Каноничный состав в overview/canonical-domain-spine.md дополнительно включает DraftVariant — альтернативный вариант элемента композиции, нужен для exploration вариантов в agency workflow и saga-coordinated swap при drift detection (см. reference/tour-builder-operational-model.md).
Identity / Tenancy / Access entities — расширение состава
В этом документе перечислены: Tenant, Workspace, RoleAssignment, CapabilityGrant, ApiClient, ApiCredential.
Каноничный состав в overview/canonical-domain-spine.md дополнительно включает ActorContext — текущий рабочий контекст identity. Один и тот же User может быть в разных actor-контекстах (внутренний оператор, сотрудник партнёра-агентства, customer success agent) с разным capability set. Без ActorContext capability-aware surfaces (см. reference/clients.md) не могут работать корректно.
Sub-states из Фазы 5 — расширения
Фаза 5 каноничной архитектуры зафиксировала ряд дополнительных понятий, которые опираются на эту модель и не противоречат ей:
- reference/booking-state-machine.md — полная state machine bookings;
- reference/tour-builder-operational-model.md — операционная модель Tour Builder с saga, drift detection, compensation;
- reference/multi-tenant-isolation-strength.md — три уровня тенантной изоляции (logical / dedicated_compute / dedicated_infrastructure).
Каноничный итог обновления
Этот документ остаётся как смысловой каркас (что есть Property, Offer, Quote, Booking и так далее, какие границы между ними). Детальные жизненные циклы и расширения составов — в специализированных документах фазы 5. При конфликте между этим документом и специализированным фазы 5 — истина в специализированном (single source of truth per domain, согласно development/documentation-governance.md).
Это обновление выполнено согласно правилу no-destruction: текст этого документа выше не правится; уточнение добавлено как explicit секция-обновление с явными ссылками на канонические источники.
1. Property Lifecycle
candidate -> mapped -> canonicalized -> enriched -> revised -> governed
2. Offer Lifecycle
computed -> surfaced -> compared -> quoted -> expired / revalidated / superseded
3. Quote Lifecycle
created -> active -> revalidated / stale -> expired / consumed
4. Booking Lifecycle
draft intent -> submitted -> pending revalidation -> pending supplier confirmation -> confirmed / failed -> amended / cancelled / completed
5. TourDraft / Proposal Lifecycle
draft -> iterated -> proposed -> versioned -> partially consumed / archived
6. Review Lifecycle
detected -> queued -> reviewed -> decided -> applied / rejected -> audited
Эти жизненные циклы потом нужно будет развернуть в отдельные специализированные документы, но уже здесь они должны быть названы как часть canonical domain thinking.
Что Нельзя Больше Путать В Других Документах
После фиксации этой модели следующие смешения должны считаться ошибкой:
PropertyиOfferSupplierPropertyиPropertyCanonicalProductиSupplierProductOfferиQuoteQuoteиBookingTourDraftиTourProposalUser identityиActor contextPartnerиAgencysupplier truthиplatform canonical truthcached previewиcommit-ready state
Как Эта Модель Связана С Уже Переписанными Документами
Overview
Архитектурная основа платформы vitrip.store уже задаёт базовый канонический набор сущностей. Этот документ делает его жёстче и доменно точнее.
Business Services
Business Services — Сервисная декомпозиция платформы выводит сервисные контуры из этой модели. Без неё сервисная декомпозиция повисает в воздухе.
Database Schema
Database Schema — Каноническая модель хранения платформы должен трактоваться как persistent projection этой доменной модели, а не как её замена.
Storage
Storage Layer — Модель хранения и жизненный цикл данных раскрывает, как truth layers из этой модели живут физически и operationally.
API Contracts
API Contracts — Surface Contracts и правила внешнего взаимодействия должен опираться на resource families, выведенные из этой модели, а не из старого списка endpoint-ов.
Clients
Clients Layer — Клиентские поверхности и рабочие модели должен строить рабочие поверхности вокруг use cases этих сущностей, а не вокруг случайных UI-страниц.
Suppliers And Ingestion
Suppliers Layer — Поставщики, source boundaries и управление внешней реальностью и Ingestion Layer — Приём, нормализация, маппинг и governance отвечают за то, как supplier reality доходит до границ этой модели.
Что Должно Быть Перепроверено После Этого Документа
После фиксации центральной доменной модели следующий порядок должен быть таким:
- зафиксировать
identity / tenancy / roles / accessкак отдельную доменную систему; - зафиксировать
offer / pricing / booking semantics; - зафиксировать
tour builderкак домен композиции; - зафиксировать
data governance and matching; - затем вернуться к дополнительной синхронизации API, storage, schema и client-facing semantics.
Текущий Практический Вывод
Платформе больше нельзя жить с расплывчатым набором слов “отели, комнаты, цены, бронирования, агентства, партнёры, туры”. Для промышленной архитектуры этого недостаточно.
Теперь смысловой каркас должен быть таким:
PropertyиCanonicalProductдержат стабильную доменную основу;SupplierPropertyиSupplierProductдержат supplier reality;OfferиQuoteдержат operational and commercial transition;Bookingдержит transactional commitment;TourDraftиTourProposalдержат composition layer;Tenant,Agency,Partner,User,ActorContextдержат организационный и access-контекст;ReviewCase,MergeDecision,FieldLineageи связанные сущности держат governance layer.
Именно от этой модели дальше должны зависеть API, storage, services, clients и будущие специализированные документы.
Связанная Документация
- Архитектурная основа платформы vitrip.store
- Главные выводы и проблемные зоны платформы
- Documentation Master Plan — Project 15 Structure Snapshot
- Business Services — Сервисная декомпозиция платформы
- Database Schema — Каноническая модель хранения платформы
- Storage Layer — Модель хранения и жизненный цикл данных
- Ingestion Layer — Приём, нормализация, маппинг и governance
- API Contracts — Surface Contracts и правила внешнего взаимодействия
- Clients Layer — Клиентские поверхности и рабочие модели
- Suppliers Layer — Поставщики, source boundaries и управление внешней реальностью