GH GambleHub

Рушій каталогу контенту

Рушій каталогу - це ядро вітрин ігор і промо-добірок на фронті: він збирає і нормалізує метадані від провайдерів (RGS), забезпечує пошук/фільтри/ранжування, застосовує правила доступності по юрисдикціях і брендам, підмішує персоналізацію і промо-плейсменти, а потім віддає швидкі відповіді через API з передбачуваним SLO.


1) Цілі та принципи

Швидкі читання: p95 ≤ 100-150 мс на запит каталогу/пошуку.
Правда і свіжість: гарантована актуальність ключових атрибутів (доступність, джекпоти, провайдерські статуси).
Гнучкість: редакторські колекції та промо-слоти без релізів.
Відповідність: правила гео/віку/контенту, ліцензії, обмеження відповідальної гри.
Мульти-тенант/регіон: ізоляція брендів і дотримання data residency.
Спостережуваність: метрики якості видачі, A/B, конверсія в гру/ставку.


2) Доменна модель (мінімум)

Сутності:
  • Game - гра/продукт провайдера.
  • Provider - RGS/студія.
  • Variant - варіанти однієї гри (волатильність, лінії, ліміти, сервер).
  • Collection - редакторська/автоматична добірка (наприклад, «Новинки», «Джекпоти»).
  • Placement - закріплена позиція/банер/тайл на сторінці/в слоті.
  • Capability/Feature - атрибути гри (free spins, buy feature, джекпот).
  • JurisdictionRule - правила доступності/обмежень.
  • Signals - поведінкові/операційні сигнали (популярність, CTR, revenue).
  • Asset - медіа (іконки, постери, демо-відео) з варіантами для пристроїв/щільностей.

Ключі: 'game _ id'( стабільний внутрішній, не дорівнює provider_game_id),'tenant _ id','region','locale'.


3) Ingest і нормалізація

Конвеєр:

1. Source Adapters (пулери): інтеграції з RGS/студіями (каталоги, фічі, RTP, теги).

2. Sanitize & Map: маппінг зовнішніх полів в єдиний словник (ACL), валідація і дедуплікація.

3. Enrich: локалізації, категорії, семантичні теги, рейтинги вікових обмежень.

4. Moderate: контент-прапори (NSFW/релігійні символи/чутливі теми) по ринках.

5. Publish: події'GameUpserted/ProviderStatusChanged'→ проекції каталогу.

Ідемпотентність: всі повідомлення з'source _ id'+'version _ ts'; повтор обробляється без побічних ефектів.
Схема еволюції: 'schema _ version'в адаптерах + міграції мапперів.


4) Нормалізована схема (спрощено)

json
{
"game_id": "g_3f92",
"tenant_id": "brand_eu",
"provider": { "id": "pr_evolution", "name": "Evolution" },
"title": { "en": "Lightning Roulette", "de": "Lightning Roulette" },
"capabilities": ["live","roulette","multiplier","bonus"],
"rtp": 97.3,
"volatility": "high",
"limits": { "min": 0.1, "max": 1000.0, "currency": "EUR" },
"jurisdiction": {
"allowed": ["MT","EE","DE"],
"blocked": ["NL","BE"],
"age_rating": 21
},
"assets": {
"tile": { "1x":"...", "2x":"..." },
"poster": { "web":"...", "mobile":"..." }
},
"tags": ["new","jackpot"],
"release_date": "2025-09-12",
"status": "active",
"variants": [{ "id":"v1","server":"eu-central-1","rtp":97.3 }]
}

5) Пошук, фільтри, фасети

Індекси: повнотекст за назвою/синонімами, фасети за'provider','capabilities','volatility','rtp _ bucket','tags'.
Фільтри: юрисдикція/регіон/мова/пристрій/вік, тільки активні/сертифіковані.
Синоніми/стемінг: карта призначених для користувача термінів («книжки», «фрукти», «кулі»).
Помилки: tolerant search (edit distance ≤1 -2) з обмеженням по довжині.


6) Ранжування: сигнали і формула

Сигнали (приклад):
  • Freshness (час з релізу).
  • Popularity (запуски/година, унікальні гравці).
  • Quality (CTR з каталогу в гру, утримання 1/7 день).
  • Business (маркетингові бусти, угоди, промо-слоти).
  • Compliance (м'які зниження для чутливого контенту, якщо потрібно).
  • Player-fit (сумісність профілю/уподобань).
Комбінація (концепт):

score = w1freshness + w2popularity + w3ctr + w4player_fit + w5boost

Ваги управляються конфігурацією/експериментами; всі сигнали нормалізовані на [0; 1].


7) Персоналізація

Коротка пам'ять: останні запуски і жанри, RYW - користувач відразу бачить свіжі дії.
Довга пам'ять: ембеддинги ігор і профілю гравця (ігрові жанри/волатильність/сесії).
Безпека: персоналізація ніколи не порушує юрисдикційні/вікові правила.
Fallback: якщо сигналів мало - нейтральне ранжування + редакторські колекції.


8) Колекції та промо-плейсменти

Колекції:
  • Авто: правило/запит (напр.,'capabilities contains'jackpot'AND release_date> = NOW () -30d').
  • Редакторські: ручний список з порядком і термінами.
  • Плейсменти: закріплені позиції на сторінках (hero, row-1-slot-3), A/B, таргетинг за сегментами/юрисдикціями.
  • Терміни та пріоритети: 'starts _ at/ends _ at', пріоритет колізій, прев'ю перед публікацією.

9) Комплаєнс і політика доступності

Гео/юрисдикція: білі/чорні списки країн/регіонів, перевірка ліцензій/сертифікатів.
Віковий рейтинг: мінімальний вік, попередження, приховування для несумісних ринків.
Тематика/символіка: прапори чутливого контенту по країнах (релігія, алкоголь і т.п.).
Відповідальна гра: приховування/зниження для гравців з лімітами/тайм-аутом.
Аудит: незмінний лог змін доступності з причинами.


10) Мульти-тенант і мульти-регіон

Всі дані позначені'tenant _ id'і'region'.
Ізоляція: кворуми/сховища по регіонах; крос-регіональні проекції - тільки агрегати.
Fairness: квоти на ingest/публікації per tenant, щоб «галасливий» бренд не затримував інших.


11) Архітектурний контур

Write-ядро каталогу (CP): нормалізація + транзакційний outbox подій.
Проекції/Read Models (EC): індекси пошуку, матеріалізовані колекції, лічильники популярності.

Кеш-шари:
  • Edge/CDN для «холодних» сторінок/зображень.
  • In-memory кеші для гарячих запитів (key = фільтри + сторінка + tenant + region).
  • Фічефлагі: прокатка правил ранжування/колекцій без релізу.

12) API (REST/GraphQL, приклади)

REST


GET /v1/catalog?tenant=brand_eu&region=EE&locale=ru
&filter=jackpot,true&sort=score_desc&page=1&size=24
→ 200 { items:[...], facets:{...}, as_of:"2025-10-31T12:10:02Z" }

GraphQL (фрагмент)

graphql query Catalog($tenant:String!,$region:String!,$q:String,$filters:Filters){
catalog(tenant:$tenant, region:$region, q:$q, filters:$filters){
items { gameId title provider { name } score badges assets { tile } }
facets { providers { key,count } capabilities { key,count } }
freshnessMs
}
}
Контракти:
  • Завжди повертайте'as _ of/freshnessMs', пейджинг, фасети.
  • Для персоналізації - маркер сесії (RYW) без PII.

13) Сигнали і потік даних

Популярність: інкременти при запуску ігор → хвилинні бакети → агрегати в проекції.
CTR/конверсія: лічильники кліків/запусків на плейсментах/колекціях.
Операційні статуси: health провайдерів (RGS), джекпоти/ліміти (стрім подій).
Маркетинг-бусти: тимчасові коефіцієнти для ігор/категорій/постачальників.


14) Спостережуваність і SLO

Метрики каталогу:
  • `catalog_p95_ms`, `catalog_p99_ms`, `error_rate`.
  • 'index _ freshness _ ms'( проектна затримка),'ingest _ lag _ ms'.
  • 'ctr','click-to-launch','collection _ coverage'(% видачі з колекцій).
Персоналізація:
  • `lift_ctr`, `lift_conversion`, «explore vs exploit» доля.
Комплаєнс:
  • % коректно застосованих гео/вікових правил, число блоків/год.

Алерти: зростання'ingest _ lag _ ms', падіння CTR на ключових колекціях, деградація провайдера (мітки у видачі).


15) Продуктивність і кешування

Стратегія: гарячі запити - кеш на 30-120 з ключем за фільтрами; персональні блоки - короткий TTL (10-30 с) або без кешу.
Інвалідація: за подіями'GameUpserted/AvailabilityChanged/PlacementUpdated'.
Пагінація: стабільні курсори, щоб не «скакали» картки при оновленні сигналів.


16) Робота з медіа

Рендер-профілі: розміри/щільності для web/mobile/TV.
Оптимізація: WebP/AVIF, lazy-load, sprite/atlas для плиток.
Контент-безпека: сканування, водяні знаки, заборона inline-PII.


17) Тестування

Contract/Schema tests для адаптерів і API.
Relevancy tests: золоті набори запитів → очікувані результати/порядок.
Персоналізація: offline AUC/NDCG + online A/B з guardrail-метриками (час в грі, депозити, RG-сигнали).
Chaos: деградації провайдерів, сплески ingest, затримки індексації.


18) Плейбуки (runbooks)

1. Лаг індексу> SLO: зупинити вторинні колекції, підвищити пріоритет ingest, тимчасово спростити ранжування.
2. Провайдер «червоний»: знизити/приховати його ігри, підняти альтернативні колекції.
3. Стрибок помилок API: перевірити кеш/бекенд, включити захисні таймаути, зменшити розмір сторінок.
4. Некоректні доступності: відкотити останнє правило, включити «білий список» критичних ринків, провести аудит змін.
5. Реліз ранжування: канарний rollout (5% → 25% → 50% → 100%), відкат по CTR/конверсії.


19) Типові помилки

Змішування зовнішніх схем провайдерів з внутрішньою моделлю (відсутність ACL).
Відсутність'as _ of/freshness'→ суперечки про «застарілому» каталозі.
Персоналізація, що порушує юрисдикційні правила.
Єдина «магічна» формула ранжування без розкладання сигналів і A/B.
Великі сторінки без кешування і курсорів → p99 «стріляють».
Dual-write в індекс і OLTP замість подій + проекцій.


20) Чек-лист перед продом

  • Нормалізований словник полів і ACL для всіх провайдерів.
  • Ідемпотентний ingest, outbox/inbox, DLQ і редрайв.
  • Проекції каталогу та індекси пошуку з SLO свіжості.
  • Ранжування з керованими вагами, розкладання сигналів і A/B.
  • Комплаєнс-правила (гео/вік/тематика) і аудит змін.
  • Мульти-тенант/регіон: ізоляція даних, fairness, residency.
  • API з'as _ of', фасетами, курсорами; кеш та інвалідація щодо подій.
  • Метрики p95/p99, ingest/індексація, CTR/конверсія; алерти.
  • Плейбуки інцидентів; канарські релізи і фічефлаги.
  • Тести релевантності, контрактів, хаосу і персоналізації.

Висновок

Рушій каталогу - це «пошуковик + правилова система + вітрина» над ігровим контентом. Сильний ACL, нормалізовані дані, проекції для швидких читань, прозорі сигнали ранжування, персоналізація з guardrail-метриками і строгий комплаєнс перетворюють каталог в стійкий і вимірний продуктовий важіль зростання - без сюрпризів в продакшені і без компромісів з регуляторами.

Contact

Зв’яжіться з нами

Звертайтеся з будь-яких питань або за підтримкою.Ми завжди готові допомогти!

Розпочати інтеграцію

Email — обов’язковий. Telegram або WhatsApp — за бажанням.

Ваше ім’я необов’язково
Email необов’язково
Тема необов’язково
Повідомлення необов’язково
Telegram необов’язково
@
Якщо ви вкажете Telegram — ми відповімо й там, додатково до Email.
WhatsApp необов’язково
Формат: +код країни та номер (наприклад, +380XXXXXXXXX).

Натискаючи кнопку, ви погоджуєтесь на обробку даних.