# Активный контекст ## Текущее состояние Собран полный вертикальный 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.