Files
mixmaker/memory_bank/active_context.md
lemintare e5646ba33d
Some checks failed
CI / backend (push) Has been cancelled
CI / frontend (push) Has been cancelled
CI / compose (push) Has been cancelled
Enhance Discord role management by adding hoist functionality
This commit introduces a new `hoist` attribute for Discord roles, allowing team roles and the registered role to be displayed in separate groups within the Discord member list. The `RoleWorker` has been updated to ensure team roles are positioned above the registered role, improving visibility and organization. Database schema changes have been made to support the new `hoist` field, and corresponding updates have been implemented in the service layer and tests to validate the new behavior.
2026-07-19 11:52:57 +03:00

12 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. В Discord member list отдельными hoisted-группами отображаются роли команд и общая роль регистрации. Team-группы располагаются выше registered-группы; Captain, slot и конкретный RSVP-статус остаются негруппирующими служебными ролями.

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

  • сообщество из 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 и 013_discord_role_hoist.sql с реальной PostgreSQL (TEST_DATABASE_URL), затем на staging проверить RSVP transitions, member-list grouping, подтверждение roster, rename/emergency substitution и cleanup Discord-ролей перед первым production-миксом.

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