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

Медиа и контент

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

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

Документ определяет доменный контур медиа и контента (media and content contour) Vitiana — каноничную модель медиафайлов (изображений, видео, документов) и текстового контента (описаний, заголовков, атрибутов), процесс их обработки, многоязычные переводы, правила публикации, контроль качества, обогащение через машинное обучение, доставку через сеть распространения контента (content delivery network, CDN), фазы развёртывания.

Документ читается после:

В корневых документах зафиксировано что платформа делает с контентом и где он используется. Этот документ описывает как — каноничные сущности, процесс обработки, доставку, обогащение, фазы.

Медиа и контент — главный визуальный носитель доверия к платформе. Партнёр выбирает платформу за качество контента не меньше, чем за полноту инвентаря. Конечный клиент бронирует тур, который выглядит надёжно. Контент — это продукт, не «обвес».

Реальное состояние реализации (home-to-go-api): загружены 127 304 объекта размещения и 4.6 миллиона фотографий через Stuba ContentClient. Это сильный стартовый актив. Платформа не теряет этот актив, а структурирует его в каноничную модель.

Правило 00000 (платформа главенствует над поставщиками) применяется здесь напрямую: каноничная модель медиа и контента не подгоняется под формат конкретного поставщика. Платформа задаёт каноничную структуру; контент от любого поставщика нормализуется через слой приёма данных. Stuba, HomeToGo и любой будущий поставщик попадают в одну каноничную модель.

Главное решение

Медиа и контент — отдельный доменный контур со своей каноничной моделью, своей политикой жизненного цикла и своей инфраструктурой доставки.

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

  • Медиа отделены от метаданных бронированияMediaAsset живёт отдельно от Property, ссылка из Property на медиа через идентификатор. Замена изображения не требует изменения Property.
  • Контент имеет свой жизненный цикл — приём → обработка → ревью → публикация → переводы → обогащение ML → архивация. Каждый этап — каноничный.
  • Многоязычность — первоклассная — каждое текстовое поле имеет переводы для базового набора языков. Перевод — отдельная сущность с историей.
  • Доставка через CDN — медиа никогда не отдаются с серверов платформы напрямую. Всегда через сеть распространения контента с географической оптимизацией.
  • Авторские права отслеживаются — каждое медиа имеет каноничные атрибуты прав (источник, лицензия, ограничения использования).
  • Контроль качества — автоматический (через ML — детекция плохих изображений, водяных знаков, неподходящего содержимого) и ручной для премиум-классов.
  • ML-обогащение — генерация описаний из изображений, автоматический подбор тегов, выделение комнат и удобств, кросс-язычные эмбеддинги для поиска.
  • Защита от потерь — Object Storage с репликацией, исходные файлы хранятся отдельно от обработанных производных.

Каноничная модель медиа и контента

Главные сущности

MediaAsset — медиаактив

Сущность, представляющая единицу медиа (изображение, видео, документ).

{
asset_id: UUID,
asset_namespace: string,
asset_class: enum,
source_type: enum,
source_supplier_id: UUID,
source_external_id: string,
source_url: string,
ingested_at: timestamp,
original_format: string,
original_size_bytes: integer,
original_dimensions: object,
storage_uri: string,
variants: array,
rights_class: enum,
rights_attribution: string,
rights_expiry: timestamp,
quality_score: numeric,
quality_review_state: enum,
ml_tags: array,
ml_confidence: object,
language_independent: boolean,
associated_entity_type: enum,
associated_entity_id: UUID,
display_priority: integer,
semantic_role: enum,
is_active: boolean,
retention_class: string,
created_at: timestamp,
updated_at: timestamp
}

Поля:

  • asset_class — класс медиа (image_photo / image_floor_plan / image_logo / video_promo / video_360 / document_pdf / audio_description).
  • source_type — источник (supplier_intake — от поставщика; partner_upload — загрузил партнёр; tenant_upload — загрузил тенант для своего тура; platform_curated — закуплен или произведён платформой; ml_generated — синтез через ML, фаза 4).
  • source_supplier_id, source_external_id, source_url — для трассировки до источника.
  • storage_uri — путь к исходному файлу в Object Storage (защищённое хранилище, не публичный URL).
  • variants — массив производных вариантов: миниатюра, превью, мобильное, ретина, квадратная обрезка для соцсетей. Каждый вариант — со своим публичным URL через CDN.
  • rights_class — класс прав (platform_owned / supplier_licensed / partner_licensed / royalty_free / creative_commons / editorial_use_only).
  • rights_attribution — обязательная атрибуция при отображении.
  • rights_expiry — для лицензированных медиа — срок действия лицензии.
  • quality_score — численный показатель качества (от 0 до 100), рассчитан ML-моделью качества медиа (фаза 3).
  • quality_review_state — состояние ревью (pending / auto_approved / manually_approved / rejected_low_quality / rejected_inappropriate).
  • ml_tags — теги, выделенные ML (например, pool, beach_view, bedroom, breakfast_buffet).
  • semantic_role — каноничная роль (hero_image — главное изображение; room_view — вид номера; amenity_view — изображение удобства; exterior — фасад; food — еда; floor_plan — план; map_overlay).
  • associated_entity_type — к какой каноничной сущности привязан (property / tour_template / tour_segment / region / partner_brand).
  • display_priority — порядок отображения в карусели (от 0 до N, чем меньше — тем выше).
  • language_independent — для большинства изображений true; для скриншотов с текстом — false, тогда нужны языковые варианты.

MediaProcessingJob — задача обработки медиа

Сущность, представляющая процесс трансформации исходного медиа в производные варианты.

{
job_id: UUID,
asset_id: UUID,
job_type: enum,
parameters: object,
state: enum,
produced_variants: array,
ml_models_applied: array,
started_at: timestamp,
completed_at: timestamp,
failure_reason: string
}

Поля:

  • job_type — тип задачи (generate_variants — создание производных; analyze_quality — оценка качества; detect_inappropriate — детекция неподходящего; extract_tags — выделение тегов; generate_embedding — векторное представление для поиска; extract_dominant_colors; crop_focal_point — обрезка с учётом фокусной точки).
  • parameters — параметры задачи.
  • produced_variants — список созданных производных.
  • ml_models_applied — какие ML-модели применены (для аудита).

ContentBundle — пакет контента

Сущность, представляющая связный текстовый контент для одного объекта (например, описание гостиницы со всеми атрибутами).

{
bundle_id: UUID,
bundle_namespace: string,
associated_entity_type: enum,
associated_entity_id: UUID,
content_class: enum,
language_payloads: object,
authorship: enum,
source_supplier_id: UUID,
quality_score: numeric,
review_state: enum,
publication_state: enum,
effective_from: timestamp,
effective_to: timestamp,
schema_version: string,
created_at: timestamp,
updated_at: timestamp
}

Поля:

  • content_class — класс контента (property_description / room_description / tour_template_description / amenity_description / region_description / pre_arrival_instructions / marketing_promotion).
  • language_payloads — объект с содержимым на каждом языке. Структура зависит от класса (для property_description — заголовок, краткое описание, длинное описание, ключевые точки).
  • authorship — кто автор (supplier_provided — от поставщика; platform_curated — переписан платформой; partner_authored — для тура партнёра; ml_generated — синтезирован ML; crowd_sourced — отзывы клиентов).
  • publication_state — состояние публикации (draft / pending_review / published / withdrawn).
  • effective_from / effective_to — окно действия (для сезонного контента).

ContentTranslation — перевод

Сущность, представляющая перевод одного языкового варианта пакета контента в другой.

{
translation_id: UUID,
bundle_id: UUID,
source_language: string,
target_language: string,
translation_type: enum,
translator_identity: string,
original_content: object,
translated_content: object,
quality_score: numeric,
review_state: enum,
applied_at: timestamp,
schema_version: string
}

Поля:

  • translation_type — тип перевода (human_professional — профессиональный человек-переводчик; machine_translation — машинный; machine_translation_post_edited — машинный с пост-редактированием; crowd_sourced — сообществом).
  • translator_identity — для аудита (имя профессионала, идентификатор сервиса машинного перевода).
  • original_content — снимок исходного содержимого, на основе которого делался перевод (для отслеживания актуальности — если оригинал изменился, перевод устарел).
  • translated_content — переведённое содержимое.

ContentReview — ревью контента

Сущность, представляющая факт ручного или автоматического ревью медиа или контента.

{
review_id: UUID,
reviewed_entity_type: enum,
reviewed_entity_id: UUID,
review_class: enum,
reviewer_type: enum,
reviewer_identity: string,
review_decision: enum,
review_notes: string,
review_criteria_applied: array,
reviewed_at: timestamp
}

Поля:

  • review_class — класс ревью (quality_check / appropriateness_check / rights_verification / translation_quality / marketing_compliance).
  • reviewer_type — кто ревьюер (automated_ml / platform_operator / supplier_review_team / external_compliance_audit).
  • review_decision — решение (approved / approved_with_notes / rejected / escalated_for_human_review).

Связь с другими каноничными сущностями

Жизненный цикл медиаактива

Поступление от источника (supplier intake / upload / curation)

Регистрация в MediaAsset с source_type

Проверка прав (rights_class определяется политикой источника)

Сохранение исходника в Object Storage (private bucket)

MediaProcessingJob: generate_variants

Создание стандартных вариантов (thumbnail, preview, mobile, retina, social_square)

MediaProcessingJob: analyze_quality

Расчёт quality_score через ML-модель

MediaProcessingJob: detect_inappropriate

Детекция неподходящего содержимого (откровенный контент, водяные знаки, реклама)

├── Подходит — review_state: auto_approved
└── Подозрительно — review_state: pending, эскалация ручному ревью

MediaProcessingJob: extract_tags + extract_focal_point

Выделение тегов и фокусной точки для умной обрезки

Активация ассета (is_active = true)

Публикация в CDN (варианты доступны по публичным URL)

Связывание с ассоциированной сущностью (property_id или tour_id)

Включение в SearchProjection и в API ответы

Эксплуатация (отображения учитываются для метрик популярности)

Периодическое перевычисление (если ML-модель обновлена)

├── Обновление поставщика — пересборка вариантов
├── Истечение прав (rights_expiry) — деактивация
└── Архивация по retention policy

Производные варианты медиа

Стандартный набор вариантов

Каждое изображение порождает следующие варианты автоматически:

ВариантРазмерПрименение
thumbnail200×200 px, центрированная обрезкаСписки, миниатюры в выдаче
preview600×400 pxКарточки в поисковой выдаче
card_main1200×800 pxГлавное изображение карточки
mobile800×600 pxМобильные интерфейсы
retina2400×1600 pxHigh-DPI дисплеи
social_square1080×1080 pxСоциальные сети
social_landscape1200×630 px (Open Graph)Превью при делении ссылок
originalбез измененийЗагрузка партнёром через специальный программный интерфейс

Обрезка с учётом фокусной точки (focal point cropping)

Каждое изображение анализируется ML-моделью, выделяющей фокусную точку — область наибольшего интереса (например, центр номера, главный объект). Обрезка для разных пропорций ориентируется на эту точку, а не центр изображения. Это даёт качественно лучший результат для мобильных миниатюр.

Форматы доставки

  • Современные форматы — WebP, AVIF — для современных браузеров (типично 30–50% меньше JPEG при том же качестве).
  • JPEG fallback — для устаревших браузеров.
  • Прогрессивный JPEG — для медленных соединений.
  • Согласование контента (content negotiation) — CDN автоматически отдаёт оптимальный формат на основе заголовков клиента.

Видео

Видеоассеты обрабатываются отдельным потоком:

  • Конвертация в адаптивный битрейт (HTTP Live Streaming, HLS).
  • Создание набора качеств (240p / 480p / 720p / 1080p).
  • Извлечение постера (video_poster) — кадра-обложки.
  • Длительность как индекс для поиска видео.

Запрет на серверный рендеринг для медиа

Платформа не рендерит медиа в момент запроса. Все варианты создаются заранее и хранятся в Object Storage. Это:

  • Исключает деградацию задержки при росте трафика.
  • Позволяет агрессивное кеширование на CDN.
  • Даёт предсказуемую стоимость (известное число файлов в хранилище, не зависящее от трафика).

CDN — сеть распространения контента

Главный принцип

Медиа отдаются только через CDN, не с серверов платформы. Это:

  • Обеспечивает географическую близость к получателю (низкая задержка).
  • Снимает нагрузку на платформу.
  • Снижает стоимость трафика (CDN типично дешевле прямого исходящего трафика).
  • Защищает от пиковых нагрузок.

Архитектура CDN

Object Storage (исходники + варианты)

Origin layer (защищённый доступ только для CDN)

CDN edge layer (мировое присутствие)

Получатель (браузер / мобильное приложение / партнёрский интерфейс)

Защищённые медиа

Для медиа, требующих авторизации (например, документы партнёра, медиа за платным тарифом):

  • Подписанные URL (signed URLs) с ограничением по времени.
  • Платформа генерирует подписанный URL при запросе через программный интерфейс.
  • CDN проверяет подпись перед доставкой.

Инвалидация кеша

При обновлении медиа (например, поставщик прислал новую версию):

  • Создаётся новый MediaAsset (старый помечается is_active: false).
  • URLs нового включают версию (например, cdn.<домен>/asset/<asset_id>/preview/v3.jpg).
  • Кеш старой версии истекает естественным путём по TTL.
  • При критичности (юридическое требование) — явная инвалидация через CDN API.

Multi-region

С фазы 4 — multi-region CDN с локализацией данных. Медиа, релевантные для региона, ближе к получателю.

Многоязычный контент и переводы

Базовый набор языков

С фазы 1 — базовый набор: украинский, русский, чешский, польский, английский, казахский. Каждый ContentBundle должен иметь содержимое на всех языках или иметь явный resv с указанием fallback-языка.

Стратегия переводов по фазам

Фаза 1–2 — Машинный перевод с человеческим ревью

  • Источник — типично английский (от поставщика).
  • Машинный перевод на остальные языки через сторонний сервис (DeepL / Google Cloud Translation / Yandex Translate).
  • Ручное ревью для тарифов с высоким приоритетом (Property с высоким quality_score, Property премиум-поставщиков).
  • Сообщение о низком качестве перевода в интерфейсе пользователя (например, «перевод автоматический»).

Фаза 3 — Платформенная модель перевода

  • Собственная многоязычная модель обучена на каноничной ttravel-семантике (термины, специфичные для индустрии).
  • Качество выше общих машинных переводчиков для нашего домена.
  • Контекстная согласованность — в одной карточке термины переводятся консистентно.

Фаза 4 — Crowd-sourced улучшения

  • Платформа агентств позволяет агентам корректировать переводы для своих регионов.
  • Краудсорсинг улучшений с проверкой и оплатой за качественные правки.

Отслеживание актуальности перевода

Каждый ContentTranslation содержит снимок original_content. При изменении оригинала:

  • Перевод помечается как outdated.
  • Включается в очередь на повторный перевод.
  • В интерфейсе при отображении показывается значок «перевод устарел» (для критических классов контента).

Запрет на смешение языков

В рамках одного language_payload[lang]только один язык. Английский термин внутри русского описания — допустим только если нет устоявшегося русского перевода (например, имя бренда). При наличии — обязательный перевод.

Контроль качества

Автоматический контроль (фаза 2)

Каждое поступившее медиа проходит автоматические проверки:

Проверка технического качества

  • Разрешение — минимум для каждого класса (например, image_photo минимум 800×600).
  • Соотношение сторон — допустимые диапазоны.
  • Размер файла — максимум для исходника (типично 10 МБ для изображения).
  • Корректность формата — отсутствие повреждений.
  • Отсутствие EXIF-данных, угрожающих приватности — координаты GPS чистятся для всех медиа из пользовательских загрузок.

Проверка содержимого через ML

  • Детекция неподходящего содержимого (NSFW, насилие, откровенно неуместный текст).
  • Детекция водяных знаков (платформа блокирует медиа с чужими водяными знаками — это нарушение прав).
  • Детекция сток-фото (сток-фото снижают доверие — помечаются для ручного ревью).
  • Детекция лиц людей — для соответствия обязательствам по защите изображений людей в публичных материалах.

Действия по результату

  • Прошлоauto_approved, активация.
  • Подозрительноpending, отправка ручному ревьюеру.
  • Не прошлоrejected, медиа не активируется. Поставщику или партнёру направляется уведомление с причиной.

Ручной контроль (фаза 2 — опционально, фаза 3 — расширенно)

  • Команда модерации обрабатывает очередь pending и эскалированные случаи.
  • Sampling — выборочный ручной контроль auto_approved медиа для калибровки ML-моделей.
  • Премиум-классы контента (например, Tour Templates с quality_score >= 90) проходят обязательное ручное ревью.

Метрики качества для тенантов

Тенанты, размещающие свой контент (партнёры, агентства, поставщики), получают метрики качества в консоли:

  • Доля медиа, прошедших автомат.
  • Доля отклонённых.
  • Распределение quality_score.
  • Рекомендации по улучшению.

Это обратная связь, помогающая тенантам поддерживать высокое качество.

ML-обогащение контента

Применения

Каждое применение интегрировано через Платформа машинного обучения:

  • Извлечение тегов из изображений — классификатор сцен (бассейн / пляж / спальня / завтрак / вид с балкона / план номера / лобби и т.д.).
  • Извлечение фокусной точки — для умной обрезки.
  • Расчёт показателя качества — нейросетевая оценка эстетики.
  • Детекция неподходящего содержимого — модель безопасности.
  • Генерация описаний из изображений (image captioning) — фаза 3+.
  • Кросс-язычные эмбеддинги текста — для многоязычного поиска.
  • Расширение коротких описаний поставщика — фаза 4 через LLM (с обязательным ревью).
  • Распознавание именованных сущностей в описаниях (имена брендов, географические названия) для связывания с каноничными сущностями.
  • Классификация удобств из описаний — извлечение упоминаний удобств для сверки с каноничным справочником.

Обогащение как поток событий

Каждое поступившее медиа порождает каскад ML-задач через очередь:

MediaAsset.created

job: generate_variants

job: analyze_quality

job: detect_inappropriate (параллельно)

job: extract_tags (параллельно)

job: extract_focal_point

job: extract_dominant_colors

job: generate_embedding (для поиска)

MediaAsset.fully_enriched

При обновлении ML-моделей — массовое перевычисление через batch-задачи без блокировки активного контента.

Авторские права и лицензии

Каноничные классы прав

КлассОписаниеАтрибуция
platform_ownedПроизведено платформой или закуплено в собственностьБез атрибуции
supplier_licensedЛицензировано от поставщика, действует на время договораИмя поставщика обязательно
partner_licensedЛицензировано от партнёра, действует на время договораИмя партнёра обязательно
royalty_freeЗакуплено или получено бесплатно с разрешением неограниченного использованияПо требованию лицензии
creative_commonsПод лицензией Creative CommonsИмя автора и тип лицензии
editorial_use_onlyТолько для редакторского использования (новости, обзоры), не для коммерческого продвиженияИмя автора и ограничение применения

Срок действия лицензии

MediaAsset.rights_expiry — дата окончания лицензии. После истечения:

  • Медиа автоматически деактивируется.
  • В каноничной системе предупреждение за 30 дней.
  • Платформа может либо обновить лицензию, либо заменить медиа.

Права получателя

Партнёры, использующие медиа платформы через программный интерфейс, получают сублицензию на использование в рамках своего интерфейса. Сублицензия:

  • Зависит от тарифа партнёра.
  • Имеет ограничения (запрет на скачивание и использование вне платформенного потока, запрет на удаление атрибуции).
  • Отслеживается через журнал доставок.

Защита от пиратства

  • Подписанные URL для премиум-медиа.
  • Водяные знаки (опционально) на медиа определённых классов.
  • Журнал скачиваний для аудита.
  • Trademark монтирования — для брендов поставщиков.

Каноничный справочник удобств и атрибутов

Контент содержит структурированные атрибуты (звёздность, тип кровати, наличие Wi-Fi и т.д.) и свободный текст (описание).

Каноничный справочник

Каноничный справочник (canonical amenity catalog, canonical attribute catalog) содержит:

  • Стандартные удобства — Wi-Fi, бассейн, парковка, кондиционер, и так далее. С иерархической структурой (категории).
  • Стандартные атрибуты — звёздность, тип проживания, вместимость, и так далее.
  • Многоязычные имена для каждого удобства и атрибута.
  • Иконки для интерфейсов.

Реализация уже существует в home-to-go-api (см. AMENITY_PLAN.md — 145 глобальных концептов в public.amenities).

Маппинг от поставщиков

При приёме данных от поставщика — маппинг сырых атрибутов поставщика на каноничные:

  • Стандартные удобства из справочника поставщика — сопоставляются по правилам.
  • Нестандартные — в очередь ручного ревью с предложением каноничного эквивалента.
  • Невалидные — игнорируются.

Подробности — в Слой приёма данных (Ingestion Layer).

Использование контента в поверхностях

В поисковой выдаче

media_summary в SearchProjection (см. Поиск и обнаружение) содержит:

  • Главное изображение (semantic_role: hero_image).
  • 2–3 дополнительных миниатюры.
  • Без полного описания.

В карточке объекта

Полная карточка через отдельный программный интерфейс возвращает:

  • Все активные медиа.
  • Полное описание из ContentBundle.
  • Список удобств (структурированный).
  • Информацию о расположении (геоданные, расстояния до точек интереса).
  • Описания номеров (вложенные ContentBundle).

В поверхности конструктора туров

Tour Builder использует:

  • Главное медиа каждого сегмента тура.
  • Описание поставщика конкретного компонента.
  • Атрибуты для расчёта совместимости компонентов.

В уведомлениях

Уведомления (особенно email-подтверждения, маркетинговые) включают медиа:

  • Главное изображение объекта в email с подтверждением бронирования.
  • Маркетинговые рассылки с галереей.

Учёт потребления

Медиа — потенциально дорогостоящий ресурс. Учёт:

  • Объём CDN-трафика — основная коммерческая метрика. Не учитывается в тарифах партнёров напрямую (партнёру не выгодно платить за каждое отображение), но влияет на общие операционные расходы платформы.
  • Объём хранилища — для медиа, загруженных партнёром (через специальный программный интерфейс) — учитывается в storage_usage метрике (см. Учёт потребления и квоты).
  • ML-инференс — каждая задача обогащения учитывается как ml_inference_calls (см. Платформа машинного обучения).

Защита от потерь

Многоуровневое хранение

  • Хранилище исходников (origin storage) — Object Storage с versioning (каждое изменение сохраняет предыдущую версию).
  • Производные варианты — в Object Storage с возможностью пересоздания из исходника.
  • Холодный архив (cold archive) — для деактивированных и старых медиа, не отображаемых, но сохранённых для аудита.

Восстановление

  • Удаление по ошибке — восстановление из versioning Object Storage.
  • Корумпция в обработке — пересоздание производных из исходника.
  • Catastrophic loss — восстановление из multi-region копий (фаза 4).

Запрет на удаление исходников

Запрещено: удаление исходного файла из Object Storage. Деактивация ассета (is_active: false) не удаляет файл — он остаётся для возможного восстановления и аудита.

Удаление возможно только по запросу субъекта данных (право быть забытым) при работе с медиа, содержащим персональные данные клиента.

События платформы медиа и контента

СобытиеКогдаГлавные потребители
media.asset.ingestedПоступление медиа от источникаКонтур наблюдаемости, ML-задачи
media.asset.processedЗавершение всех процессов обработкиПлатформа поиска (для обновления проекций)
media.asset.activatedМедиа активирован и доступенВсе потребители контента
media.asset.deactivatedДеактивация (обновление, истечение прав)Платформа поиска, кеш CDN
media.processing.failedОтказ обработкиКонтур наблюдаемости, оперативная команда
media.quality.review_requiredЭскалация ручному ревьюКоманда модерации
media.review.completedЗавершение ревьюКонтур аудита, поставщик/партнёр
media.rights.expiring_soonПриближение истечения прав (за 30 дней)Команда контента, поставщик/партнёр
content.bundle.publishedПубликация пакета контентаПлатформа поиска
content.translation.completedЗавершение переводаПлатформа поиска
content.translation.outdatedУстаревание переводаОчередь повторных переводов
content.review.flag_raisedЖалоба на содержимое от пользователяКоманда модерации

Полная таксономия — в Первоначальная таксономия событий.

Технологический выбор по фазам

ФазаХранилище медиаCDNML-обогащениеМашинный перевод
BootstrapObject Storage в одном регионеОдин CDN-провайдер базовыйПростая ML-модель для тегов и качестваСторонний сервис (DeepL / Google)
2Object Storage с versioningCDN с географической оптимизациейРасширенный набор ML-моделей через сервис обслуживанияСторонний сервис с пост-редактированием
3Multi-region хранилищеMulti-region CDNСобственные модели для специфики туризмаСобственная модель перевода для travel-семантики
4Multi-region с локализацией данныхEdge compute для динамической трансформацииLLM-based обогащение, image captioningLLM-based перевод с контекстом

Конкретный выбор провайдеров CDN, Object Storage и ML — открытые развилки.

Фазы развёртывания

Фаза Bootstrap (0–6 месяцев)

Что разворачивается:

  • Каноничная модель (MediaAsset, MediaProcessingJob, ContentBundle, ContentTranslation, ContentReview) зафиксирована.
  • Основные потоки приёма медиа от первого поставщика (Stuba — продолжение существующей реализации в home-to-go-api).
  • Базовая обработка изображений (генерация стандартного набора вариантов).
  • Object Storage в одном регионе.
  • Один CDN-провайдер.
  • Базовый машинный перевод на 6 языков первой волны.

Триггер выхода:

  • Готовность к приёму медиа от второго поставщика — необходим зрелый процесс маппинга.
  • Появление потребительской витрины с высокими требованиями к качеству.

Фаза 2 — Production media platform (6–18 месяцев)

Что разворачивается:

  • Полный набор производных вариантов с фокусной точкой.
  • ML-обогащение (теги, качество, детекция неподходящего).
  • Современные форматы (WebP, AVIF) с согласованием контента.
  • Управление правами (rights_class, rights_expiry).
  • Журнал переводов с отслеживанием актуальности.
  • Сервис подписанных URL для премиум-медиа.
  • Видео-pipeline (HLS, постеры).
  • Метрики качества для тенантов.
  • Автоматическая модерация с ручным ревью эскалаций.

Триггер выхода:

  • Появление платформенных моделей перевода — нужны собственные ML-модели.
  • Появление пользовательской загрузки (контент от партнёров) на масштабе — нужны строгие правила.

Фаза 3 — Smart content (18–30 месяцев)

Что разворачивается:

  • Собственные ML-модели качества и тегов.
  • Платформенная модель перевода для travel-семантики.
  • Image captioning для синтеза описаний из изображений.
  • Расширенный rights management.
  • Crowd-sourced улучшения переводов.
  • Multi-region CDN.

Фаза 4 — Multi-region и LLM (30+ месяцев)

Что разворачивается:

  • Multi-region хранилище с локализацией данных.
  • Edge compute для динамической трансформации.
  • LLM-based обогащение и расширение описаний.
  • LLM-based контекстный перевод.
  • Платформа курирования контента для тенантов.

Архитектурные решения с тезисным обоснованием

Решение 1. Медиа отделены от метаданных каноничных сущностей

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

Тезисы:

  1. Каноничные сущности (Property, Tour*) обновляются с разной частотой, чем медиа. Связывание через идентификатор позволяет независимое обновление.
  2. Один и тот же медиаактив может быть привязан к нескольким сущностям (например, региональное изображение применимо к множеству туров).
  3. Современные платформы (Booking.com, Airbnb, Trivago) — все строят медиа как отдельный домен.

Решение 2. CDN — единственный путь доставки

Цель: обеспечить географическую близость, снять нагрузку с платформы, гарантировать стоимость.

Тезисы:

  1. Прямая отдача с серверов платформы не масштабируется (медиатрафик может в десятки раз превышать API-трафик).
  2. CDN-стоимость предсказуема (за единицу трафика), серверная — нет.
  3. Согласование контента и WebP/AVIF поддерживается CDN-провайдерами из коробки.

Решение 3. Производные варианты — заранее, не в момент запроса

Цель: обеспечить предсказуемую задержку и стоимость.

Тезисы:

  1. Серверный рендеринг в момент запроса деградирует под нагрузкой.
  2. Хранение всех вариантов дороже по дисковому пространству, но дешевле по CPU и предсказуемо.
  3. Современные CDN-провайдеры (Cloudflare, Fastly) предлагают on-the-fly трансформацию, но при росте — собственные предварительные варианты дешевле.

Решение 4. ML-обогащение как первоклассный поток

Цель: обеспечить высокое качество поиска, рекомендаций, представления контента.

Тезисы:

  1. Без структурированных тегов поиск ограничен текстовыми описаниями (плохо в многоязычной среде).
  2. Без оценки качества поиск возвращает плохо выглядящие предложения, снижая конверсию.
  3. Современные платформы (Airbnb с миллиардом изображений) — ML-обогащение это база.

Решение 5. Многоязычные переводы — отдельная сущность с историей

Цель: обеспечить качественный многоязычный поиск и отслеживание актуальности.

Тезисы:

  1. Без отдельной сущности перевод смешан с оригиналом — невозможно отследить, какие переводы устарели.
  2. Снимок оригинала на момент перевода (original_content) — единственный способ обнаружить устаревание.
  3. Машинный перевод — приемлемое начало; платформа должна расти к собственной модели для качества.

Открытые развилки

Развилка 1. Конкретный CDN-провайдер

Cloudflare vs Fastly vs CloudFront vs Bunny CDN. Конкретный выбор зависит от стоимости, географического покрытия (особенно для Украины и Казахстана), интеграционных возможностей.

Эскалируется: при подготовке к фазе 2 (production launch).

Развилка 2. Конкретный сервис машинного перевода в фазе 1–2

DeepL vs Google Cloud Translation vs Yandex Translate vs Microsoft Translator. Качество для пары английский → восточно-европейские языки + казахский — главный критерий.

Эскалируется: при подготовке к фазе 2.

Развилка 3. Глубина пользовательских загрузок

Партнёрская загрузка медиа через программный интерфейс — есть с фазы 1 (для туров партнёра). Расширение до пользовательских загрузок (отзывы клиентов с фотографиями) — открытая возможность фазы 3+.

Эскалируется: при появлении потребности на потребительской витрине.

Развилка 4. Собственная ML-модель качества vs готовый сервис

В фазе 2 — готовый сервис качества (например, Aesthetic Quality API). В фазе 3 возможно — собственная модель, обученная на специфике travel.

Эскалируется: при выходе из фазы 2.

Развилка 5. Платформа курирования контента как продукт для тенантов

В фазе 4 — возможно расширение до платформы курирования контента для крупных тенантов (рабочее место для редактирования описаний и фотографий тенантного канала). Коммерческая возможность.

Эскалируется: при появлении партнёрских запросов.

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

Корневые архитектурные документы

Связанные доменные документы

Документы развития

Реализационная база home-to-go-api

  • AMENITY_PLAN.md — 145 глобальных концептов удобств, маппинг 224 от поставщика Stuba (продолжение этого справочника в каноничную модель).
  • CONTENT_PIPELINE.md — текущий pipeline загрузки контента и медиа.
  • HOTEL_LOADER.md — архитектура загрузчика, через который загружены 4.6M фотографий.
  • STUBA_CONTENT_API.md — справочник Stuba Content API.

Операционная сторона

Архитектурные правила

Уточнение под Фазы 5–6 (28.04.2026) — связи с tour saga, isolation, security, DR

Документ опубликован 26.04.2026 (Фаза 4). После Фаз 5–6 интеграция требует фиксации.

Связь с saga Tour Builder

reference/tour-builder-operational-model.md (Фаза 5) — Tour Builder использует MediaAsset / ContentBundle для compositions:

  • TourProposal reference на MediaAsset для preview images;
  • ProposalArtifact (PDF, share-link) — generated assets;
  • DriftEvent может trigger media re-validation (changed images).

Связь с tenant isolation

reference/multi-tenant-isolation-strength.md (Фаза 5):

  • MediaAsset per-tenant aware (tenant-uploaded media);
  • partner-specific media (white-label branding) — explicit tenant scope;
  • canonical media (от поставщиков) — shared с RLS на tenant-aware metadata.

Связь с security architecture

reference/security-architecture.md (Фаза 10):

  • upload validation — anti-malware scanning (упомянуто в threat model);
  • content moderation ML — для inappropriate content detection;
  • access logging для sensitive media (например, copies of identity documents);
  • encryption at-rest в object storage.

Связь с DR — Tier 2

operations/disaster-recovery-and-capacity.md (Фаза 6) — media data:

  • MediaAsset metadata — Tier 2 (RTO 4ч, RPO 30м);
  • raw media files — Object Storage с cross-AZ replication;
  • transform cache — Tier 3 (rebuildable);
  • archived media (старше 2 лет без access) — Tier 4 cold storage.

Связь с правом на удаление (GDPR)

reference/compliance-and-legal.md — DSR right to erasure:

  • user-uploaded media обязательно удаляется при DSR delete;
  • supplier media (общественная) — не удаляется (no PII);
  • audit log media access.

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

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