Skip to main content

Обзор

Система конкурсов состоит из двух подсистем:
  • Ежедневные игры — мини-игры с мгновенными призами (дни подписки, баланс)
  • Реферальные конкурсы — соревнования по привлечению рефералов с рейтингами
Обе подсистемы управляются общим флагом CONTESTS_ENABLED, но работают на разных моделях данных.
CONTESTS_ENABLED=true
CONTESTS_BUTTON_VISIBLE=true
Участие в конкурсах доступно только пользователям с активной подпиской (платной или триальной).

Ежедневные игры

Архитектура

ContestTemplate → ContestRound → ContestAttempt
    (шаблон)       (раунд)       (попытка)
  • Шаблон — определяет тип игры, расписание, призы
  • Раунд — конкретный экземпляр игры с временным окном
  • Попытка — одна попытка пользователя (уникальна: один раунд — одна попытка)

7 типов игр

ИграМеханикаВводОписание
Quest ButtonsСетка 3x3КнопкаНайти скрытую ноду в сетке
Lock Hack20 замковКнопкаНайти единственный открытый замок
Server Lottery10 флагов странКнопкаУгадать правильный сервер
Blitz ReactionОдна кнопкаКнопкаКто первый нажмёт — тот победил
Letter CipherЧисловой шифрТекстРасшифровать слово (A=1, B=2…)
Emoji GuessПеремешанные эмодзиТекстУгадать название сервиса по подсказкам
AnagramПеремешанные буквыТекстСоставить слово из букв

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

Каждый шаблон имеет:
  • schedule_times — список времён запуска (формат HH:MM, через запятую)
  • cooldown_hours — длительность раунда (по умолчанию 24ч)
  • is_enabled — вкл/выкл для конкретной игры
Фоновый сервис ContestRotationService проверяет расписание каждые 60 секунд. При наступлении времени создаёт новый раунд и:
  1. Анонсирует в канале подписки (CHANNEL_SUB_ID)
  2. Рассылает всем пользователям с активной подпиской

Призы

Тип призаОписание
daysПродление подписки на N дней
balanceНачисление на баланс (в копейках)
customПроизвольный текст (ручное выполнение)

Определение победителя

Используется атомарная проверка с блокировкой строки (SELECT FOR UPDATE):
  1. Пользователь отправляет ответ
  2. Стратегия игры проверяет правильность
  3. Если верно — блокируется строка раунда, проверяется winners_count < max_winners
  4. При победе приз выдаётся автоматически

Настройки шаблонов по умолчанию

ИграРасписаниеМакс. победителейПриз
Quest Buttons10:00, 18:0031 день
Lock Hack09:00, 19:0015 дней
Letter Cipher12:00, 20:0011 день
Server Lottery15:0017 дней
Blitz Reaction11:00, 21:0011 день
Emoji Guess13:0011 день
Anagram17:0011 день
Все 7 шаблонов создаются автоматически при первом запуске, но отключены по умолчанию. Включайте их по мере необходимости.

Реферальные конкурсы

Как работают

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

Типы конкурсов

ТипЧто считается очком
referral_paidРеферал зарегистрировался и купил подписку
referral_registeredРеферал просто зарегистрировался

Создание конкурса (FSM)

  1. Выбор режима: referral_paid или referral_registered
  2. Название конкурса
  3. Описание (опционально, - для пропуска)
  4. Текст призов (опционально)
  5. Дата начала (дд.мм.гггг ЧЧ:ММ)
  6. Дата окончания
  7. Время ежедневной сводки (ЧЧ:ММ или несколько через запятую)

Ежедневные сводки

  • Отправляются в канал подписки и чат администраторов
  • Поддержка нескольких времён в день (daily_summary_times)
  • По завершении конкурса — финальная сводка (отправляется один раз)
  • Содержание: название, топ-5, общее количество рефералов, призы, оставшееся время

Виртуальные участники

Администраторы могут добавлять “призраков” для создания видимости конкуренции:
  • Индивидуально — имя + количество рефералов
  • Массово (“Массовка”) — 1-50 призраков с одинаковым количеством рефералов и случайными именами
  • В админке отмечены иконкой призрака
  • В публичном канале выглядят как обычные участники

Лидерборд

Лидерборд объединяет реальных участников (из referral_contest_events) и виртуальных. Доступен из админки (топ-10) и в ежедневных сводках (топ-5).

Управление (админ-панель)

Ежедневные игры

ДействиеОписание
Список шаблоновВсе 7 игр с состоянием вкл/выкл
Вкл/ВыклПереключение конкретной игры
Запуск раундаНемедленный запуск (ручной или с автовключением)
РедактированиеТип приза, значение, макс. победителей, расписание, cooldown
Сброс попытокСбросить попытки активного раунда
Закрытие раундаПринудительно завершить текущий раунд
Массовые операцииЗакрыть все раунды, сбросить все попытки, запустить все

Реферальные конкурсы

ДействиеОписание
Список конкурсовС пагинацией (5 на страницу)
ДеталиСтатус, период, призы, топ-5, всего событий
Вкл/ВыклПереключение активности
СтатистикаУчастники, рефералы, платные/бесплатные, суммы
СинхронизацияСинхронизация событий с реальными платежами
ОчисткаУдаление невалидных событий
Виртуальные участникиДобавление, редактирование, удаление, массовое создание

Видимость

Конкурсы имеют многоуровневую систему видимости:
  1. CONTESTS_ENABLED — глобальный переключатель (фоновые сервисы, обработчики)
  2. CONTESTS_BUTTON_VISIBLE — видимость кнопки “Конкурсы” в главном меню
  3. Вкл/выкл шаблона — каждая ежедневная игра переключается отдельно
  4. Активность конкурса — каждый реферальный конкурс переключается отдельно
  5. Требование подписки — только пользователи с активной/триальной подпиской

Настройка

ПеременнаяПо умолчаниюОписание
CONTESTS_ENABLEDfalseГлобальный переключатель системы конкурсов
CONTESTS_BUTTON_VISIBLEfalseПоказывать кнопку “Конкурсы” в меню
TIMEZONEUTCЧасовой пояс для расписания
CHANNEL_SUB_IDID канала для анонсов

Cabinet и Web API

Cabinet (для пользователей)

  • GET /contests/count — количество доступных (неотыгранных) игр
  • GET /contests — список доступных игр со статусом
  • GET /contests/{round_id} — данные игры
  • POST /contests/{round_id}/answer — отправка ответа

Web API (для администраторов)

Полный CRUD для шаблонов, раундов, попыток (ежедневные игры) и реферальных конкурсов с аутентификацией по API-токену.