GH GambleHub

Feature Flags і випуск фіч

Feature Flag (FF) - це керована умова, яка включає/вимикає поведінку системи без релізу коду. Прапори дозволяють: викочувати фічі безпечно, таргетувати групи користувачів/ринків/тенантів, швидко відключати проблемні компоненти, проводити експерименти і конфігурувати параметри в рантаймі.

Ключові цілі:
  • Знизити blast radius при релізах.
  • Розділити розгортання та активацію.
  • Дати прозоре управління змінами з аудитом, SLO і відкатом «в один клік».

1) Типи прапорів і коли їх застосовувати

Release flags - поетапне включення нової фічі (dark → canary → ramp-up → 100%).
Ops/kill-switch - миттєве відключення залежностей (провайдер, підсистема, важкі обчислення).
Experiment (A/B, multi-variant) - поділ трафіку на варіанти (weights, sticky bucketing).
Permission/Entitlement - доступ до фічів за ролями/планами/юрисдикціями.
Remote Config - параметри поведінки (поріг, таймаут, формула) з прапора/конфіга.
Migration flags - перемикання схем/шляхів даних (переїзд на новий індекс/БД/ендпоінт).

Анти-патерн: один і той же прапор «про все» - дробіть на фічу, комп-світч і параметри.

2) Модель даних прапора (мінімум)

yaml flag:
key: "catalog. new_ranker"
type: "release"    # release      ops      kill      experiment      permission      config     migration description: "New Directory Ranking"
owner: "search-team@company"
created_at: "2025-10-01T10:00:00Z"
ttl: "2026-01-31" # delete deadline after 100% enable rules:
- when:
tenant_id: ["brand_eu","brand_latam"]
region: ["EE","BR"]
user_pct: 10 # progressive percentage then: "on"
- when:
kyc_tier: ["unverified"]
then: "off"
variants: # for experiments
- name: "control"; weight: 50
- name: "v1"; weight: 30
- name: "v2"; weight: 20 payload:
v1:
boost_freshness: 0. 3 boost_jackpot:  0. 2 v2:
boost_freshness: 0. 2 boost_jackpot:  0. 4 prerequisites: # dependent flags/schema versions
- key: "catalog. index_v2_ready"
must_be: "on"
audit:
require_ticket: true change_window: "09:00-19:00 Europe/Kyiv"
safeguards:
max_rollout_pct: 50 # stop threshold auto_rollback_on:
p95_ms: ">200"
error_rate: ">2%"

3) Оцінка і таргетинг (evaluation)

Ключі таргетингу: `tenant_id, region/licence, currency, channel, locale, role, plan, device, user_id, cohort, kyc_tier, experiment_bucket`.
Порядок оцінки: prerequisites → deny-правила → allow-правила → дефолт.
Sticky bucketing: для експериментів хешируйте стабільний ідентифікатор (наприклад,'hash (user_id, flag_key)') - щоб користувач завжди отримував один варіант.

Псевдокод:
ts result = evaluate(flag, context)  // pure function if (!prereqs_ok(result)) return OFF if (deny_match(result, ctx)) return OFF if (allow_match(result, ctx)) return resolve_variant_or_on(result, ctx)
return flag. default

4) Розподіл та архітектура FF

Варіанти:
  • Server-side SDK (рекомендовано): джерела істинності і кеш в бекенді; уніфікація логіки.
  • Edge/CDN evaluation: швидкий таргетинг на периметрі (де немає PII/секретів).
  • Client-side SDK: коли потрібна персоналізація UI, але - тільки з мінімальним контекстом і без чутливих правил.
  • Config-as-Code: зберігання прапорів в репозиторії, валідація CI, rollout через CD.
Кеш стратегій:
  • Startup bootstrap + streaming updates (SSE/gRPC) + fallback до останнього снапшоту.
  • SLA «freshness» прапорів: p95 ≤ 5 с.

5) Стратегії випуску

5. 1 Dark Launch

Фіча включена, але невидима користувачеві; збираємо метрики і помилки.

5. 2 Canary

Включаємо 1-5% трафіку в одній юрисдикції/тенанті; моніторимо p95/p99, помилки, конверсію.
Stop conditions - порогові тригери автокатофа за метриками.

5. 3 Progressive Rollout

10% → 25% → 50% → 100% за розкладом з ручною/авто-верифікацією.

5. 4 Shadow / Mirroring

Дублюємо запити в новий шлях (без видимого ефекту) і порівнюємо результати/латентність.

5. 5 Blue/Green + FF

Розгортаємо дві версії; прапор рулить трафіком і перемикає залежності по сегментах.

6) Залежності та крос-сервісна консистентність

Використовуйте prerequisites і «health-прапори» готовності: індекс побудований, міграція завершена.
Координація через події: `FlagChanged(flag_key, scope, new_state)`.

Для критичних сценаріїв використовуйте двофазне включення:

1. включити read-шлях → 2) перевірити метрики → 3) включити write/side-effects.

  • Сервісні контракти: дефолт повинен бути безпечним (fail-safe OFF).

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

Метрики на прапор/варіант/сегмент:
  • `flag_eval_p95_ms`, `errors_rate`, `config_freshness_ms`.
  • Бізнес-метрики: 'ctr','conversion','ARPU','retention', guardrails (наприклад, RG-інциденти).
  • Автоматичні SLO-пороги для автокатофа.

Логи/трейсинг: добавляйте `flag_key`, `variant`, `decision_source` (server/edge/client), `context_hash`.

Дашборди: «сходи» rollout з порогами, heatmap помилок по сегментах.

8) Безпека та комплаєнс

PII-мінімізація в контексті.
RLS/ACL: хто може змінювати які прапори (по доменах/ринках).
Часові вікна змін (change windows) і «подвійне підтвердження» для чутливих прапорів.
Незмінний аудит: хто/коли/що/чому (ticket/incident link).
Юрисдикції: прапори не повинні обходити регуляторні заборони (наприклад, включати гру в забороненій країні).

9) Управління «довгоживучими» прапорами

У кожного прапора є TTL/дата видалення.
Після 100% включення - створіть task на видалення гілок коду, інакше виросте «прапор-борг».
Відзначайте прапори як «migration »/« one-time», відокремлюйте їх від постійних «permission/config».

10) Приклад API/SDK контракту

Evaluation API (server-side)

http
POST /v1/flags/evaluate
Headers: X-Tenant: brand_eu
Body: { "keys":["catalog. new_ranker","rgs. killswitch"], "context": { "user_id":"u42", "region":"EE" } }
→ 200
{
"catalog. new_ranker": { "on": true, "variant":"v1", "as_of":"2025-10-31T12:10:02Z" },
"rgs. killswitch":  { "on": false, "variant":null, "as_of":"2025-10-31T12:10:02Z" }
}

Client SDK (кэш, fallback)

ts const ff = await sdk. getSnapshot()     // bootstrap const on = ff. isOn("catalog. new_ranker", ctx)
const payload = ff. payload("catalog. new_ranker", "v1")

11) Взаємодія з іншими контурами

Rate limits/квоти: прапори можуть знижувати RPS/включати троттлінг на час інциденту.
Circuit breaker/degradation: kill-switchи відключають важкі шляхи і включають деградацію.
Каталог/персоналізація: прапори змінюють ваги/правила ранжування (через Remote Config).
Міграції БД: прапори поетапно переводять читання/записи на нову схему (read-replica → dual-write → write-primary).

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

1. Інцидент після включення 25%

Автокатоф спрацював → прапор OFF для всіх/сегмента, тікет в on-call, збір статів, RCA.
Тимчасово включити деградацію/стару гілку через migration-прапор.

2. Зростання p95 за каталогом

Поріг'p95 _ ms> 200'- автокатоф; зафіксувати снапшот логів з'flag _ key = catalog. new_ranker`.
Увімкнути спрощені сигнали ранжування (payload config).

3. Невідповідність юрисдикції

Прапор permission помилково відкрив гру в'NL'- OFF + пост-факт аудит, додавання guard-правила «region deny».

4. Дисперсія в A/B

Зупинити експеримент, виконати CUPED/stratified аналіз, перерозкатати з оновленими вагами.

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

Unit: детермінована оцінка правил/пріоритетів/пререквізитів.
Contract: схема прапорів (JSON/YAML), валідатори, CI-перевірка перед мерджем.
Property-based: «deny> allow», «most specific wins», стабільний bucketing.
Replay: відтворення реальних контекстів на новій конфігурації.
E2E: канарні скрипти (step-up/step-down), перевірка автокатофа і аудит-подій.
Chaos: обрив стрімінгу, застарілий снапшот, масове оновлення прапорів.

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

Секретна логіка в клієнтських прапорах (витоки/підміна).
Відсутність TTL → «кладовище» прапорів в коді.
«Універсальні» прапори без сегментації → неможливо локалізувати проблему.
Немає guardrails/автокатофів - ручні інциденти.
Несумісні залежності між прапорами → цикли/розсинхрон.
Оцінка прапорів в кожному запиті без кеша → сплески латентності.
Відсутність аудиту/вікна змін - ризики комплаєнсу.

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

  • Прапор створений з типом, owner, описом, TTL і вимогою тікету.
  • Правила таргетингу визначені;'deny'на небажані регіони/ролі.
  • Sticky bucketing детермінований; ідентифікатор вибраний стабільно.
  • Пререквізити і health-прапори готові; Дефолт безпечний.
  • Дашборди і алерти на p95/p99, error_rate, бізнес-guardrails.
  • Автокатоф налаштований; стоп-поріг rollout і умови відкату.
  • Канарковий план: відсотки/етапи/вікно змін/відповідальні.
  • Конфіги валідуються в CI; снапшот розподілений по кластерах/регіонах.
  • Документація для підтримки/продукту; плейбуки інцидентів.
  • План видалення гілок коду і самого прапора після 100%.

16) Приклад «міграційного» прапора (БД/індекс)

yaml flag:
key: "search. use_index_v2"
type: "migration"
description: "Switching reads to index v2"
prerequisites:
- key: "search. index_v2_built"
must_be: "on"
rules:
- when: { tenant_id: ["brand_eu"], user_pct: 5 } then: "on"
- when: { tenant_id: ["brand_eu"], user_pct: 25 } then: "on"
safeguards:
auto_rollback_on:
search_p95_ms: ">180"
error_rate: ">1%"
ttl: "2026-02-01"

Висновок

Feature Flags - це не тільки «вкл/викл», а дисципліна управління ризиками змін. Чіткі типи прапорів, детермінований таргетинг, прогресивні викладки з guardrails, автокатоф, аудит і план видалення роблять релізи передбачуваними, а інциденти - короткими і контрольованими. Вбудовуйте прапори в архітектуру як перший клас громадян - і ви зможете доставляти цінність частіше, безпечніше і осмисленіше.

Contact

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

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

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

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

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

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