Иерархия лимитов
Лимит — это формализованное ограничение операции во времени/объеме/стоимости. В iGaming и финтехе лимиты — основа безопасности, соответствия регуляциям и управления рисками. Иерархия лимитов задает, чье правило главнее и где оно исполняется, чтобы не допустить двойной траты, превышения ставок/депозитов, злоупотреблений бонусами и нарушений ответственной игры.
1) Классификация лимитов
По силе применения
Hard — непреодолимые (запрет операции).
Soft — предупреждение/фрикция (капча, подтверждение), эскалация до hard при повторе.
По природе
Денежные: сумма депозита/ставки/выплаты; дневные/недельные/месячные пределы.
Временные: длительность сессии, перерывы, «охлаждение», тайм-ауты.
Количественные: число транзакций, спинов, запросов API.
Скоростные (rate limits): RPS/конкурентность.
Квоты: бюджет действий за окно (N в сутки/неделю).
Контекстные: по игре/провайдеру/методу оплаты/устройству/стране.
По владельцу
Регуляторные/брендовые (тенант/регион)
Системные (платформа, защита инфраструктуры)
Пользовательские (self-limits в рамках RG)
2) Измерения и ключи (scoping)
Каждый лимит привязывается к контексту (ключу):
tenant_id · region · license · currency · channel · brand player_id · kyc_tier · rg_state · age game_id · provider_id · product (casino/sports/live)
payment_method · device_fingerprint · ip_asn
Чем точнее ключ, тем выше приоритет (см. иерархию ниже).
3) Иерархия и приоритеты (most specific wins)
Упорядочим уровни от общего к частному:
GLOBAL_DEFAULT
< TENANT/BRAND
< REGION/LICENCE
< PRODUCT/PROVIDER/GAME
< CURRENCY/CHANNEL/PAYMENT_METHOD
< PLAYER (KYC/RG)
< SESSION/DEVICE
<REQUEST (idempotency-key operation)
Правила:
- Более узкий контекст перекрывает широкий: player > region.
- Любое явное deny побеждает allow.
- Конфликты soft/hard решаются в пользу hard.
- При мердже квот/окон побеждает минимально допустимое значение (min-cap).
4) Модель данных (упрощенно)
sql
CREATE TABLE limits (
id bigserial primary key,
scope jsonb, -- context keys (tenant, region, player_id,...)
kind text, -- bet_amount, deposit_daily, rps_api, payout_single, session_duration type text, -- HARD SOFT QUOTA RATE value numeric, -- sum/qty/seconds/ops window_sec int, -- for QUOTA/RATE, else null burst int, -- for RATE token-bucket currency text, -- if applicable reason_code text, -- regulator/product/security valid_from timestamptz,
valid_to timestamptz,
priority int default 0, -- manual specificity overlide created_by text,
created_at timestamptz default now()
);
CREATE TABLE limit_counters (
key_hash text primary key, -- hash(scope,kinda,window_start)
window_start timestamptz,
consumed numeric, -- money/pcs/sec updated_at timestamptz
);
Идемпотентность: все операции несут `operation_id`; инкремент счетчика выполняется один раз (inbox/outbox или compare-and-swap по версии).
5) Алгоритм оценки (evaluation)
1. Сбор кандидатов по `kind` и пересечению `scope`.
2. Ранжирование по специфичности (число совпавших измерений) и `priority`.
3. Мердж параметров: жесткость (hard>soft), min-cap, min-window.
4. Проверка квот/рейт-лимита: токен-бакет (RATE) + фикс/скользящее окно (QUOTA).
5. Решение: `ALLOW | SOFT_WARN | DENY` + `retry_after`/`remaining`.
6. Запись следа: аудит события и метрики.
json
{
"decision":"DENY",
"kind":"deposit_daily",
"remaining":0,
"window_reset_at":"2025-10-31T21:00:00Z",
"matched_limit_id":12345,
"policy":"REGULATORY",
"reason":"DAILY_CAP_REACHED"
}
6) Точки применения (enforcement points)
API Gateway — защита инфраструктуры: RATE (RPS), CONCURRENCY, burst.
Доменные сервисы — смысловые лимиты: депозиты, ставки, выплаты, сессии.
Провайдерские адаптеры — дублирующие/локальные лимиты провайдеров (валидировать до вызова).
Клиентский UX — превентивные подсказки (SOFT), «осталось N», таймеры.
Правило: единожды списываем квоту/токены — там, где операция становится необратимой (после резервирования кошелька/валидного аутентифицированного шага).
7) Денежные лимиты: депозит/ставка/выплата
Per currency: храните лимиты в валюте операции, а не через FX «на лету».
Min/Max: `min_bet`, `max_bet`, `max_payout_single`.
Окна: `deposit_daily/weekly/monthly` с фиксированными границами (например, в таймзоне лицензии).
Композиция: итоговый разрешенный диапазон = пересечение (региональные ∩ брендовые ∩ пользовательские).
8) Ответственная игра (RG)
Self-limits (игрок задал сам) всегда жестче брендовых.
Временные ограничения: `session_duration`, `cool_off`, `self_exclusion`.
Эскалация: превышение soft-лимита → предупреждение, повтор → hard (в рамках окна).
Аудит: каждое изменение RG фиксируется незатираемо (кто/когда/почему).
9) Rate limit vs Quota: когда что
Rate limit (token-bucket/leaky): защита от всплесков; применять на gateway/адаптерах.
Quota (fixed/sliding window): управление суммарным бюджетом действий/денег; применять в домене (deposit_daily, bet_count_hourly).
Часто используются вместе: `RATE` (мгновенные пики) + `QUOTA` (суточный бюджет).
10) Мульти-тенант и мульти-регион
Лимиты всегда содержат `tenant_id` и `region/licence`.
Residency: счетчики и хранение — в «домашнем» регионе.
Fairness: разделяйте пулы RATE/QUOTA per tenant, чтобы «шумный» не срывал SLO других.
11) Идемпотентность и консистентность
Команды с `operation_id`; повтор не должен увеличивать `consumed`.
Для денег — strict path: резерв кошелька и инкремент counters в одной транзакции/саге (TCC).
Для RATE — используйте атомарные инкременты/склады текущее окно.
12) Наблюдаемость
Метрики:- `limit_eval_p95_ms`, `decision_rate{ALLOW,DENY,SOFT}`,
- `quota_remaining_percent` по основным видам,
- `rate_throttled`, `burst_dropped`,
- `rg_self_limit_hits`, `regulatory_hits`.
Логи/трейсинг: `matched_limit_id`, `scope_hash`, `operation_id`, `window_start/reset`, `remaining`.
Алерты: рост `DENY`/`429` сверх порога, частое достижение регуляторных капов, «hot key» по игроку/устройству.
13) Версионирование и аудит
Каждое правило — с `valid_from/valid_to`, `created_by`, `reason_code`.
События: `LimitCreated/Updated/Deleted`, `LimitHit`, `LimitDenied`.
Храните «снимок» активных правил для воспроизведения исторических решений (dispute-ready).
14) Тестирование
Contract tests: схема и мердж специфичностей/приоритетов.
Property-based: «most specific wins», «deny побеждает allow», «min-cap».
Golden cases: набор эталонных конфликтов (тенант vs регион, RG vs бренд).
Chaos: всплески запросов (RATE), гонки по счетчикам, повтор команд (идемпотентность).
E2E: матчинги лимитов на чек-листах регулятора (депозит/неделя/месяц).
15) Плейбуки
1. Шторм 429/ throttling на gateway
Снизить concurrency, увеличить токен-бакет временно, включить приоритизацию критических путей, проанализировать источники (ASN/IP).
2. Массовые отказы по регуляторному лимиту
Проверить расписание окон и таймзону; пролонгировать soft-UX (объяснения), уведомить комплаенс.
3. Ложно-положительные отказы из-за гонок
Включить сериализацию по ключу `player_id/kind`, перейти на CAS/дедуп по `operation_id`.
4. Расхождение с провайдерским лимитом
Синхронизировать min/max per game, добавить предвалидацию в адаптер, временно понизить каталог/плейсмент игры.
16) Типичные ошибки
Отсутствие иерархии → «перетягивание каната» между правилами.
Вычисление лимитов в UI без серверной валидации.
Подмена квот рейт-лимитами (и наоборот).
Игнорирование валют/шагов при денежных лимитах (CLP/JPY).
Нет идемпотентности → двойное списание квоты.
Единый пул RATE на всех тенантов → шейринг проблем.
Отсутствие аудита → невозможно объяснить отказ.
17) Быстрые рецепты
Прием ставки: `max_bet` = min(регион, игра, провайдер, пользовательский RG); RATE на `/bets.place` = 20 rps/player, QUOTA = 500 ставок/день.
Депозиты: `deposit_daily/monthly` + `deposit_single`; пред-валидировать PSP-лимиты.
Сессии: `session_duration` hard + напоминания каждые N минут (soft).
API-защита: глобальный RATE по ключам `ip_asn` и `tenant_id`; канареечные окна для релизов.
18) Чек-лист перед продом
- Зафиксирована иерархия специфичности и политика мерджа (most specific wins, deny > allow).
- Модель данных с `scope`, `kind`, `type`, окнами, валютами и приоритетами.
- Точки применения: gateway (RATE), домен (QUOTA/денежные), адаптеры (провайдерские).
- Идемпотентность (`operation_id`) и сериализация по ключам; счетчики атомарны.
- Наблюдаемость: метрики решений, лаги окон, алерты; трассировка с `matched_limit_id`.
- Версионирование и неизменяемый аудит изменений и срабатываний.
- Тест-пакет: contract/property/golden/chaos/E2E.
- Мульти-тенант fairness и data residency соблюдены.
- UX для SOFT-лимитов: понятные сообщения, `remaining/retry_after`.
- Плейбуки инцидентов согласованы с комплаенсом и поддержкой.
Заключение
Иерархия лимитов — это система принятия решений, а не набор разрозненных чисел. Четкая специфичность и порядок приоритетов, единая модель данных, правильные точки применения, идемпотентность и наблюдаемость превращают лимиты в надежный контур безопасности и соответствия, который масштабируется по тенантам, регионам и продуктам — и не мешает росту.