Files
mixmaker/memory_bank/active_context.md
lemintare 966c81ba12
Some checks failed
CI / backend (push) Has been cancelled
CI / frontend (push) Has been cancelled
CI / compose (push) Has been cancelled
Add RSVP role synchronization and localization support for Discord
This commit introduces functionality for managing event-specific RSVP roles in Discord, including roles for "Registered", "Going", "Maybe", and "Not Going". The `RoleWorker` has been enhanced to handle these roles based on user registrations, with localization support for role names in Russian and English. Additionally, the database schema has been updated to accommodate new role types and actions, and the service layer has been modified to trigger role synchronization upon relevant event updates. Tests have been added to ensure the correct behavior of the new RSVP handling logic.
2026-07-19 11:42:40 +03:00

11 KiB
Raw Blame History

Активный контекст

Текущее состояние

Собран полный вертикальный production-пайплайн скрима: закрытие регистрации → versioned балансировка → ручная правка и подтверждение составов 1/2/2 → капитаны → drag-and-drop редактор произвольного графа матчей → атомарный старт готовых Bo3 → жеребьёвка → баны карт → баны героев → результаты и динамическое разрешение Winner/Loser-переходов. Состояние события, roster draft, bracket draft и серии сохраняется в PostgreSQL с optimistic locking, аудитом и глобальной SSE-синхронизацией.

Admin UI содержит пошаговый workflow и roster editor с same-role swap, резервом и запуском. Live, spectator и bracket используют реальные API-команды и realtime refresh; участник турнира автоматически открывает собственный матч, остальные попадают в spectator mode, а актуальная сетка и соседние параллельные матчи доступны прямо над серией. Demo fixtures остались только локальным showcase. Добавлена роль Moderator: она имеет все операционные права Admin, но управление списком модераторов доступно только Admin. До состояния Live workflow можно откатить на один этап назад. Добавлен Discord-анонс нового микса: после успешного создания Event backend через Bot REST API публикует локализованный embed и кнопку регистрации. При создании staff может оставить включённой галочку уведомления @everyone или отправить тихий анонс без пинга. Ошибка Discord логируется, но не отменяет создание события; без bot token и channel ID интеграция отключена. Добавлен PostgreSQL-backed Discord role worker. После подтверждения составов он создаёт и выдаёт роли по актуальным Team.Name, Captain и slot Tank/Damage/Support, учитывает live-переименование и аварийную замену, а при завершении/отмене/удалении/откате удаляет временные роли. Повтор jobs идемпотентен; guest и отсутствующие в guild игроки сохраняются как предупреждения и не блокируют микс. При любом RSVP тот же worker создаёт event-specific роли «Зарегистрирован», «Идёт», «Возможно», «Не идёт», выдаёт общую роль ответа и ровно один текущий статус, обновляет названия при rename Event и снимает назначения после удаления RSVP. Registration close роли не удаляет; общий event teardown очищает их вместе с team/captain roles.

Подтверждённые требования

  • сообщество из 20+ игроков;
  • backend на Go с Clean Architecture;
  • современный frontend на фреймворке;
  • Discord OAuth и самостоятельное заполнение игроком рейтингов Tank, Damage и Support;
  • выбор игроком предпочитаемых ролей, до трёх желаемых союзников и до трёх avoid-игроков;
  • переключение всего интерфейса между RU и EN;
  • календарь запланированных миксов со статусами Going / Maybe / NotGoing;
  • административная панель управления событиями, игроками и регистрациями;
  • Admin может отменить событие с сохранением его в календаре или полностью удалить событие и связанные данные;
  • возможность Admin отметить участие за другого игрока;
  • автоматическая балансировка полных команд 1 Tank / 2 Damage / 2 Support;
  • резерв для участников, не вошедших в полные команды;
  • назначение Admin капитана каждой сформированной команды;
  • жеребьёвка на сайте;
  • последовательные баны карт и героев;
  • серии Bo3;
  • фиксация исхода каждой карты, счёта серии и итогового победителя;
  • актуальная турнирная сетка с параллельными матчами, умным live-входом и переключением spectator/control;
  • production-развёртывание единым Docker Compose resource в Coolify;
  • PostgreSQL в том же Compose-стеке с persistent volume;
  • мобильный и десктопный интерфейс.
  • карточки отменённых событий отображаются красными, завершённых — зелёными, активных — розовыми с меткой LIVE.
  • новый микс автоматически анонсируется в настроенном Discord-канале со ссылкой на регистрацию; @everyone можно отключить при создании.
  • подтверждённые составы автоматически проецируются в управляемые Discord-роли и очищаются по завершении их жизненного цикла.
  • явные RSVP автоматически проецируются в локализованные event-specific Discord-роли ответа и статуса.

Исходный регламент

  • основной Bo3: Control → Hybrid/Escort → Control;
  • альтернативный Bo3: Control → Push → Escort;
  • первая карта определяется банами: первый бан задаёт жеребьёвка, затем команды банят по очереди до одной оставшейся;
  • вторую и последующие карты напрямую выбирает команда, проигравшая предыдущую карту;
  • после ничьей следующую карту выбирает команда, проигравшая начальный жребий;
  • тайбрейкер Control не повторяет уже сыгранную Control-карту;
  • перед каждой картой команды делают по два бана героев в порядке A → B → A → B;
  • два бана одной команды должны относиться к разным ролям;
  • команда не повторяет собственный бан героя в пределах серии;
  • повторить героя, которого ранее банил соперник, разрешено;
  • первой героев банит команда, проигравшая начальный жребий.

Предлагаемый стек

  • backend: Go, PostgreSQL, REST, SSE;
  • frontend: React, TypeScript, Vite, TanStack Query/Router, Tailwind CSS, shadcn/ui;
  • контракт: OpenAPI;
  • локальная инфраструктура: Docker Compose;
  • production: Coolify + Docker Compose без пользовательских сетей.

Принятые решения для MVP

  • игрок входит через Discord;
  • игрок самостоятельно указывает Overwatch-ранг от Bronze 5 до Champion 1 для каждой роли;
  • балансировщик автоматически назначает роли и собирает команды 1/2/2;
  • предпочтения ролей, союзников и avoid-списки учитываются как мягкие штрафы после требований баланса;
  • участники сверх полного состава остаются в резерве;
  • сетка редактируется как последовательный граф Team / Winner / Loser; последний матч определяет общего победителя;
  • игрок отмечается на микс через календарь;
  • Admin может изменить RSVP за игрока, а действие сохраняет автора;
  • капитан назначается отдельно для каждой команды и должен входить в её состав;
  • Admin закрывает регистрацию и фиксирует список участников перед балансировкой;
  • до подтверждения составов Admin может менять игроков одной роли местами и заменять игрока резервным;
  • подтверждённые составы и капитаны являются обязательным условием запуска скрима;
  • запуск скрима создаёт серверную серию и переводит событие в последовательный конечный автомат жеребьёвки, банов и результатов;
  • после запуска обычное редактирование составов блокируется; аварийная замена выполняется Admin отдельно и фиксируется в аудите;
  • исход карты задаётся как победа одной из команд или ничья;
  • сервер автоматически пересчитывает счёт Bo3 и победителя серии;
  • frontend, API и PostgreSQL разворачиваются одним Compose-стеком;
  • Coolify управляет сетью и публичным маршрутом, PostgreSQL хранит данные в named volume.

Ближайший следующий шаг

Проверить миграции 006_event_workflow.sql, 011_discord_role_sync.sql и 012_discord_rsvp_roles.sql с реальной PostgreSQL (TEST_DATABASE_URL), затем на staging проверить RSVP transitions, анонс, подтверждение roster, rename/emergency substitution и cleanup Discord-ролей перед первым production-миксом.

Публичная вкладка FAQ описывает регистрацию, балансировку, полномочия капитанов, выбор карт, баны героев и подсчёт Bo3.