Skip to main content

Budget Control & Luck Pool

1. Summary

Goal: Контроль экономики крафтов и поощрение активных игроков через систему буста вероятностей.

User Value: Активные игроки (50%+ прогресс крафта) получают × 3-13 увеличение шансов на материалы для целевых скинов через Boost.


2. Business Logic

Budget Periods

Экономика разбита на периоды для контроля расходов:

ПараметрЗначение
Длительность периода10 дней
Периодов в месяце3
Бюджет периода3333₽ (333₽/день)
Перенос бюджета
  • Внутри месяца: остаток переносится в следующий период
  • В конце месяца: остаток сгорает

Luck Pool

Механика поощрения активных игроков через увеличение вероятностей.

Вкратце: Игроки с ≥50% прогрессом крафта получают буст × 3-13 к материалам.

Подробная документация

См. Luck Pool для полного описания механики, seniority, anti-abuse, edge cases.

Budget Exhausted

При исчерпании бюджета периода

Штрафной множитель: × 0.01 (99% снижение вероятности)

Применяется к FRAGMENT/BLUEPRINT для скинов в пуле. Остальные награды не затрагиваются.

Определение: available = baseBudget + carriedOver - spent <= 0

Уведомление: Админ получает alert только при переходе из "хватает" в "не хватает".

Budget НЕ блокирует крафты

Игроки могут крафтить даже при исчерпанном бюджете. Система только логирует траты для администратора.

Admin Notifications (TG Alerts)

Budget Control отправляет уведомления администраторам через Telegram при критических событиях:

СобытиеТипКогда отправляетсяInline кнопки
Бюджет исчерпанBUDGET_EXHAUSTEDПри первом исчерпании бюджета периода+500₽, +1000₽, +2000₽, +5000₽, Открыть админку
Подозрительная активностьSUSPICIOUS_CRAFTSПри >2 крафтах за 24ч одним пользователем
Смена периодаPERIOD_TRANSITIONПри автоматическом переходе между периодами
Формат уведомлений

BUDGET_EXHAUSTED:

⚠️ Бюджет периода исчерпан!

Сезон: {seasonNumber}
Период: {periodNumber}/9
День периода: {dayOfPeriod}/10

[+500₽] [+1000₽] [+2000₽] [+5000₽]
[Открыть админку]

SUSPICIOUS_CRAFTS:

🚨 Подозрительная активность!

Пользователь: {username || userId}
Крафтов за 24ч: {craftsIn24h}
Порог: {threshold}

[Открыть профиль]

PERIOD_TRANSITION:

📅 Смена периода бюджета

Сезон: {seasonNumber}
Переход: период {fromPeriod} → {toPeriod}
Перенесено: {budgetCarriedOver}₽
Сгорело: {budgetExpired}₽
Callback handlers

Кнопки admin:budget_add_{amount} обрабатываются в backend/src/domains/telegram/handlers/admin-callback.handler.ts и вызывают BudgetAdminService.incrementBudget().

Edge Cases

СитуацияПоведение
Бюджет исчерпанШтраф × 0.01 к материалам в пуле
Конец месяцаОстаток бюджета сгорает
Конец периодаОстаток переносится в следующий период
Крафт в сезоне A, вывод в сезоне BspentRub учтён в сезоне A (по крафту). Withdrawal не привязан к сезону — это delivery, не commitment
Luck Pool Edge Cases

Edge cases связанные с пулом удачи (вход, выход, seniority) описаны в Luck Pool.


3. ADR (Architectural Decisions)

Luck Pool ADRs

Архитектурные решения по Luck Pool (буст, seniority) описаны в Luck Pool ADR.

Почему Budget не блокирует крафты?

Проблема: При блокировке крафтов игроки потеряют прогресс.

Решение: Budget — инструмент мониторинга, а не ограничения.

Последствия:

  • Админ контролирует экономику через отмену выводов
  • Игроки не теряют прогресс из-за бюджета

Почему расход фиксируется при крафте, а не при выводе?

Проблема: Крафт и вывод могут произойти в разных сезонах. Игрок крафтит скин в последний день сезона A, но выводит уже в сезоне B.

Решение: Budget трекает commitment (обязательство платформы), а не delivery (фактическую доставку).

Аналогия: Бухгалтерский "accrued expense" — расход фиксируется когда возникает обязательство, а не когда деньги уходят.

Последствия:

  • spentRub = сумма обязательств платформы за период
  • Withdrawal не имеет periodId — это operational detail
  • Админ контролирует реальные расходы через отмену выводов
  • Скин в инвентаре = платформа уже "должна" его игроку

4. Architecture

Integration Overview

Key Components

КомпонентПутьОписание
BudgetServicebackend/src/domains/budget/services/budget.service.tsCore: статус, запись расходов, проверки
BudgetAdminServicebackend/src/domains/budget/services/budget-admin.service.tsAdmin: increment/decrement/reset бюджета
BudgetLifecycleServicebackend/src/domains/budget/services/budget-lifecycle.service.tsLifecycle: создание периодов, transitions
LuckPoolServicebackend/src/domains/luck-pool/services/luck-pool.service.tsУправление пулом и бустом
BudgetRepositorybackend/src/domains/budget/repositories/budget.repository.tsCRUD для BudgetPeriod
Constantsshared/src/constants/budgetControl.tsВсе константы системы
Константы системы
BUDGET_CONTROL = {
PERIOD_DAYS: 10,
PERIODS_PER_MONTH: 3,
DAILY_BUDGET_RUB: 333,
PERIOD_BUDGET_RUB: 3333,

MIN_PROGRESS_FOR_POOL: 0.5,
INACTIVE_DAYS_THRESHOLD: 14,
POOL_CHECK_INTERVAL_HOURS: 12,

BASE_BOOST_MULTIPLIER: 3.0,
SENIORITY: {
MULTIPLIER_PER_PERIOD: 1.2,
MAX_ACTIVE_PERIODS: 9,
},

BUDGET_EXHAUSTED_MULTIPLIER: 0.01,
}

5. Database Schema

Models

МодельОписаниеКлючевые поля
BudgetPeriodПериод бюджетаbaseBudgetRub, carriedOverRub, spentRub, isActive
LuckPoolEntryУчастник пулаactivePeriods, boostMultiplier, isActive, blockedSkinIds
CraftBudgetLogЛог крафтовcostRub, hadBoost, seniorityMultiplier, totalBoostMultiplier

Relationships


6. API Endpoints

МетодЭндпоинтОписание
GET/admin/budget/statusСтатус текущего периода
GET/admin/budget/periodsВсе периоды сезона
POST/admin/budget/periods/:id/incrementУвеличить бюджет
POST/admin/budget/periods/:id/decrementУменьшить бюджет
GET/admin/budget/craft-logsЛоги крафтов

  • Luck Pool — полная документация по пулу удачи
  • Cases — использует Luck Pool для буста материалов
  • Daily Spins — использует Luck Pool для буста материалов
  • Craft — триггерит выход из пула и записывает расходы
  • Seasons — контекст для периодов и пула