From d401e9009c47dc77fc4e35c9748abb0daf2ab812 Mon Sep 17 00:00:00 2001 From: lemintare Date: Sat, 18 Jul 2026 23:32:11 +0300 Subject: [PATCH] first commit --- .cursor/rules/frontend-ui.mdc | 18 ++++ .cursor/rules/go-clean-architecture.mdc | 18 ++++ .cursor/rules/project-context.mdc | 21 ++++ .cursor/rules/testing-and-quality.mdc | 16 +++ memory_bank/active_context.md | 68 +++++++++++++ memory_bank/architecture.md | 126 ++++++++++++++++++++++++ memory_bank/domain_model.md | 109 ++++++++++++++++++++ memory_bank/project_context.md | 44 +++++++++ memory_bank/roadmap.md | 76 ++++++++++++++ 9 files changed, 496 insertions(+) create mode 100644 .cursor/rules/frontend-ui.mdc create mode 100644 .cursor/rules/go-clean-architecture.mdc create mode 100644 .cursor/rules/project-context.mdc create mode 100644 .cursor/rules/testing-and-quality.mdc create mode 100644 memory_bank/active_context.md create mode 100644 memory_bank/architecture.md create mode 100644 memory_bank/domain_model.md create mode 100644 memory_bank/project_context.md create mode 100644 memory_bank/roadmap.md diff --git a/.cursor/rules/frontend-ui.mdc b/.cursor/rules/frontend-ui.mdc new file mode 100644 index 0000000..2808d67 --- /dev/null +++ b/.cursor/rules/frontend-ui.mdc @@ -0,0 +1,18 @@ +--- +description: Frontend and UI rules for Mixmaker +globs: frontend/**/*.{ts,tsx,css} +alwaysApply: false +--- + +# Frontend And UI + +- Build mobile-first screens first, then scale up to desktop. +- Use React, TypeScript, Vite, TanStack Router, TanStack Query, Tailwind CSS, shadcn/ui, and accessible primitives. +- Organize code by product capabilities; keep reusable primitives in `shared`. +- Keep the live match screen focused: show the current step, active team, allowed actions, score, and concise validation feedback. +- Use orange and blue team accents on a dark graphite base, with accessible contrast and non-color status indicators. +- Make touch targets large and keep the primary action reachable on phones. +- Treat server state as authoritative; use optimistic updates only when rollback is clear and safe. +- Keep API access behind typed client functions generated from or aligned with OpenAPI. +- Prefer subtle motion that communicates state changes; respect reduced-motion preferences. +- Do not encode map pools, hero catalogs, or draft rules directly in UI components. diff --git a/.cursor/rules/go-clean-architecture.mdc b/.cursor/rules/go-clean-architecture.mdc new file mode 100644 index 0000000..fb1be9e --- /dev/null +++ b/.cursor/rules/go-clean-architecture.mdc @@ -0,0 +1,18 @@ +--- +description: Go Clean Architecture rules for Mixmaker backend +globs: backend/**/*.go +alwaysApply: false +--- + +# Go Backend Architecture + +- Keep dependency direction strict: `domain` has no outward dependencies; `application` depends on domain and ports; adapters depend on application contracts; `cmd/api` performs wiring. +- `backend/internal/domain` must not import HTTP routers, SQL drivers, configuration, loggers, or framework code. +- `backend/internal/application` must depend on domain types and consumer-owned ports, never concrete adapters. +- Put request and response DTOs in HTTP adapters, not in domain entities. +- Prefer explicit domain errors and small interfaces owned by their consumers. +- Keep SQL, migrations, and PostgreSQL-specific types inside output adapters. +- Make transactions explicit at the application boundary for multi-step state changes. +- Keep balancing and draft validation deterministic and free of infrastructure dependencies. +- Pass clocks, random sources, and ID generators through ports when behavior must be testable. +- Add focused unit tests whenever domain behavior or a use case changes. diff --git a/.cursor/rules/project-context.mdc b/.cursor/rules/project-context.mdc new file mode 100644 index 0000000..6932af5 --- /dev/null +++ b/.cursor/rules/project-context.mdc @@ -0,0 +1,21 @@ +--- +description: Core Mixmaker product context +alwaysApply: true +--- + +# Mixmaker Context + +- Mixmaker is a web app for organizing Overwatch scrims for communities of 20+ players. +- Read the relevant files in `memory_bank/` before meaningful product or architecture changes. +- The core flows are Discord auth, player profiles, event calendar and RSVP, role-based team balancing, coin toss, map and hero bans, Bo3 results, and tournament brackets. +- Players sign in through Discord and may edit only their own Tank, Damage, and Support ratings. +- Scheduled events support Going, Maybe, and NotGoing participation statuses. +- Admins may manage events and change RSVP for another player; store the acting account for every administrative override. +- The balancer creates full 5v5 teams with 1 Tank, 2 Damage, and 2 Support; unmatched players remain in reserve. +- An Admin assigns one captain from each team's current roster; captain permission is scoped to that team. +- Keep the UI polished, responsive, mobile-first, and styled as a dark esports control panel. +- Business rules and draft state are enforced by the backend; the frontend must not be the source of truth. +- Preserve draft, result corrections, and match history as auditable actions instead of silently rewriting completed steps. +- Production deploys to Coolify as one Docker Compose stack with PostgreSQL; do not declare custom Compose networks unless explicitly required. +- Do not commit production secrets, publish PostgreSQL ports, or omit persistent storage, healthchecks, and backup documentation. +- After meaningful product, architecture, API, data-model, deployment, or workflow changes, update the relevant files in `memory_bank/` in the same task. diff --git a/.cursor/rules/testing-and-quality.mdc b/.cursor/rules/testing-and-quality.mdc new file mode 100644 index 0000000..1bacb11 --- /dev/null +++ b/.cursor/rules/testing-and-quality.mdc @@ -0,0 +1,16 @@ +--- +description: Testing and quality expectations for Mixmaker +alwaysApply: true +--- + +# Testing And Quality + +- Keep changes scoped and aligned with `memory_bank/`. +- After substantive edits, run the narrowest useful checks available. +- Backend domain rules and use cases must be unit-testable without PostgreSQL. +- Add focused tests for balancing constraints, draft transitions, role limits, and repeated-ban rules. +- Repository and migration behavior should use integration tests once the database layer exists. +- Critical frontend flows should receive component or end-to-end coverage as the UI stabilizes. +- Test concurrent or repeated draft commands for idempotency and version conflicts. +- Do not add broad abstractions until repeated behavior proves they are needed. +- Prefer explicit domain invariants over compatibility with unfinished code. diff --git a/memory_bank/active_context.md b/memory_bank/active_context.md new file mode 100644 index 0000000..f92768e --- /dev/null +++ b/memory_bank/active_context.md @@ -0,0 +1,68 @@ +# Активный контекст + +## Текущее состояние + +Проект начинается с нуля. Сформированы исходный контекст, предметная модель, архитектурное направление и предварительная дорожная карта. + +## Подтверждённые требования + +- сообщество из 20+ игроков; +- backend на Go с Clean Architecture; +- современный frontend на фреймворке; +- Discord OAuth и самостоятельное заполнение игроком рейтингов Tank, Damage и Support; +- календарь запланированных миксов со статусами Going / Maybe / NotGoing; +- административная панель управления событиями, игроками и регистрациями; +- возможность Admin отметить участие за другого игрока; +- автоматическая балансировка полных команд 1 Tank / 2 Damage / 2 Support; +- резерв для участников, не вошедших в полные команды; +- назначение Admin капитана каждой сформированной команды; +- жеребьёвка на сайте; +- последовательные баны карт и героев; +- серии Bo3; +- фиксация исхода каждой карты, счёта серии и итогового победителя; +- турнирная сетка; +- production-развёртывание единым Docker Compose resource в Coolify; +- PostgreSQL в том же Compose-стеке с persistent volume; +- мобильный и десктопный интерфейс. + +## Исходный регламент + +- основной Bo3: Control → Hybrid/Escort → Control; +- альтернативный Bo3: Control → Push → Escort; +- первый бан карт определяется жеребьёвкой; +- карты банятся по очереди до одной оставшейся; +- тайбрейкер Control не повторяет уже сыгранную Control-карту; +- перед каждой картой команды делают по два бана героев в порядке A → B → A → B; +- два бана одной команды должны относиться к разным ролям; +- команда не повторяет собственный бан героя в пределах серии; +- повторить героя, которого ранее банил соперник, разрешено; +- первой героев банит команда, проигравшая начальный жребий. + +## Предлагаемый стек + +- backend: Go, PostgreSQL, REST, WebSocket/SSE; +- frontend: React, TypeScript, Vite, TanStack Query/Router, Tailwind CSS, shadcn/ui; +- контракт: OpenAPI; +- локальная инфраструктура: Docker Compose; +- production: Coolify + Docker Compose без пользовательских сетей. + +## Принятые решения для MVP + +- игрок входит через Discord; +- игрок самостоятельно указывает рейтинг 1–100 для каждой роли; +- балансировщик автоматически назначает роли и собирает команды 1/2/2; +- участники сверх полного состава остаются в резерве; +- первая турнирная сетка — single elimination; +- игрок отмечается на микс через календарь; +- Admin может изменить RSVP за игрока, а действие сохраняет автора; +- капитан назначается отдельно для каждой команды и должен входить в её состав; +- исход карты задаётся как победа одной из команд или ничья; +- сервер автоматически пересчитывает счёт Bo3 и победителя серии; +- frontend, API и PostgreSQL разворачиваются одним Compose-стеком; +- Coolify управляет сетью и публичным маршрутом, PostgreSQL хранит данные в named volume. + +## Ближайший следующий шаг + +Создать full-stack каркас и первый вертикальный сценарий: Discord-вход → профиль с рейтингами → календарь → отметка участия → админка регистраций → список участников события. + +Открытое продуктовое решение, которое не блокирует каркас: как выбирается Hybrid/Escort для второй карты — заранее организатором, случайно или отдельным действием команд. diff --git a/memory_bank/architecture.md b/memory_bank/architecture.md new file mode 100644 index 0000000..b9c74e3 --- /dev/null +++ b/memory_bank/architecture.md @@ -0,0 +1,126 @@ +# Архитектура + +## Общий подход + +Backend строится на Go по принципам Clean Architecture. Зависимости направлены внутрь: инфраструктура и доставка зависят от сценариев приложения, сценарии — от доменной модели. + +## Backend + +Предлагаемая структура: + +```text +backend/ + cmd/api/ точка входа HTTP-сервера + internal/ + domain/ сущности, value objects, правила, доменные ошибки + application/ + usecase/ сценарии приложения + port/ интерфейсы репозиториев, часов, генераторов, событий + adapter/ + in/http/ handlers, middleware, DTO + out/postgres/ реализации репозиториев + out/realtime/ доставка событий клиентам + platform/ конфигурация, логирование, подключение инфраструктуры + migrations/ +``` + +Технологии первой версии: + +- Go; +- PostgreSQL; +- REST API для команд и запросов; +- WebSocket или Server-Sent Events для синхронизации драфта и сетки; +- Discord OAuth 2.0 для входа; +- серверная cookie-сессия с HttpOnly, Secure и SameSite; +- структурированное логирование; +- OpenAPI как контракт frontend/backend. + +## Frontend + +Предлагаемый стек: + +- React + TypeScript; +- Vite; +- TanStack Router и TanStack Query; +- Tailwind CSS; +- shadcn/ui как основа компонентов; +- Framer Motion для умеренных анимаций; +- React Hook Form + Zod; +- dnd-kit для ручной корректировки составов; +- библиотека турнирной сетки только после проверки мобильного UX; при необходимости — собственный SVG-компонент. + +Структура frontend группируется по продуктовым возможностям: + +```text +frontend/src/ + app/ + pages/ + widgets/ + features/ + entities/ + shared/ +``` + +## Границы модулей + +- Players: профили, рейтинги и предпочтения ролей; +- Auth: Discord OAuth, сессии и роли доступа; +- Admin: управление игроками, регистрациями, событиями и капитанами; +- Events: календарь, регистрации участников и состояние игрового вечера; +- Balancing: генерация и оценка составов; +- Draft: жеребьёвка, карты и герои; +- Matches: карты, счёт и завершение серии; +- Tournaments: сетка и продвижение команд; +- Realtime: подписка клиентов на изменения. + +## Ключевые решения + +### Балансировщик + +В MVP — детерминированный оптимизатор с весовой функцией качества и ограниченным поиском вариантов. Алгоритм располагается в доменном слое и не зависит от БД. Позже его можно заменить на constraint solver без изменения API сценария. + +### Драфт как конечный автомат + +Жеребьёвка и баны моделируются состояниями и допустимыми командами. Сервер является источником истины и отклоняет действие, если оно нарушает порядок или регламент. + +### История действий + +Все действия драфта сохраняются как неизменяемые записи аудита. Текущее состояние можно хранить в обычных таблицах; полноценный Event Sourcing для MVP не требуется. + +### Авторизация + +Вход выполняется через Discord OAuth 2.0. После callback backend создаёт собственную серверную сессию и безопасную HttpOnly-cookie; OAuth-токен Discord не передаётся frontend. Discord ID является внешним идентификатором аккаунта. + +Глобальные роли MVP — Admin и Player; Captain назначается Admin для конкретной команды, а read-only spectator-доступ доступен авторизованным игрокам. Игрок редактирует только собственный профиль, рейтинги и RSVP. Admin управляет событиями, может изменить RSVP за игрока, подтверждает участников, назначает капитанов и фиксирует результаты. Начальные Admin задаются через `ADMIN_DISCORD_IDS`, чтобы роль нельзя было получить через публичный интерфейс. + +### Календарь и участие + +События хранятся в UTC и отображаются в локальном часовом поясе пользователя. REST API отдаёт будущие события и статусы Going/Maybe/NotGoing. Изменения регистрации публикуются через realtime-канал, чтобы Admin сразу видел актуальный список. При изменении статуса за другого игрока API сохраняет actor ID и источник `admin`, а UI показывает, кем сделана отметка. + +### Капитаны + +Капитан — назначение внутри конкретной команды, а не глобальная роль аккаунта. Admin может назначить или заменить капитана только участником этой команды. Только текущий капитан выполняет командные действия драфта; Admin имеет аварийное право выполнить действие с обязательной записью в аудит. + +### Результаты матчей + +Исход каждой карты фиксируется отдельной командой use case. Домен серии пересчитывает счёт и победителя, а турнир продвигает победившую команду только после завершения серии. Исправление результата не удаляет историю первоначального действия. + +### Развёртывание в Coolify + +Production разворачивается из репозитория как один Docker Compose resource: frontend/reverse proxy, Go API, миграции и PostgreSQL с named volume. Coolify сам создаёт сеть стека и подключает свой proxy, поэтому в Compose не объявляются `networks`, `container_name` и вручную заданные Traefik labels. + +Frontend-контейнер обслуживает SPA и проксирует `/api` и SSE к сервису `api`, поэтому приложению достаточно одного публичного домена. PostgreSQL и API не публикуют host-порты; сервисы обращаются друг к другу по Compose-именам. Секреты и production-переменные задаются в Coolify UI, а в репозитории хранится только `.env.example`. + +Для всех долгоживущих сервисов задаются healthcheck и корректный graceful shutdown. Данные PostgreSQL сохраняются в named volume; для production обязательно настраивается регулярный backup тома/БД вне сервера. + +## Нефункциональные требования + +- идемпотентность команд, которые могут повториться из-за сети; +- optimistic UI только там, где возможен безопасный откат; +- серверная валидация всех правил; +- миграции схемы БД; +- unit-тесты доменных правил и балансировки; +- интеграционные тесты репозиториев и API; +- production Docker Compose совместим с Coolify без пользовательских сетей; +- PostgreSQL имеет persistent volume, healthcheck и внешние резервные копии; +- адаптивность от мобильного экрана до большого дисплея. diff --git a/memory_bank/domain_model.md b/memory_bank/domain_model.md new file mode 100644 index 0000000..b47ce2a --- /dev/null +++ b/memory_bank/domain_model.md @@ -0,0 +1,109 @@ +# Предметная модель + +## Основные сущности + +### Player + +Игрок связан с Discord-аккаунтом и имеет отображаемое имя и собственный рейтинг для каждой роли: Tank, Damage, Support. Игрок редактирует свои рейтинги самостоятельно; организатор может видеть время последнего изменения. Дополнительно можно хранить предпочитаемые роли, BattleTag и историю участия. + +### Account + +Учётная запись Discord с глобальной ролью Player или Admin. Admin назначается только другим Admin либо через начальный список Discord ID в конфигурации развёртывания. Изменение роли записывается в аудит. + +### Event + +Запланированный игровой вечер: название, дата и время, часовой пояс, описание, дедлайн регистрации, формат команд, регламент, турнир и текущее состояние. + +### EventRegistration + +Отметка игрока в календаре со статусом Going, Maybe или NotGoing. Игрок меняет собственный статус, а Admin может изменить его за игрока. Регистрация хранит автора и время последнего изменения, чтобы интерфейс явно показывал административное действие. В момент закрытия регистрации Admin подтверждает список участников; только Going-игроки по умолчанию попадают в балансировку. + +### Team + +Состав игроков, назначенный Admin капитан, цвет/название и рассчитанные показатели силы. Капитан должен входить в текущий состав команды; переназначение фиксируется в аудите. + +- общий средний рейтинг; +- средний рейтинг по каждой роли; +- распределение игроков по ролям; +- оценка доверия к балансу. + +### Ruleset + +Версионируемый набор правил серии: + +- формат Bo3; +- последовательность режимов; +- пулы карт по режимам; +- порядок банов карт и героев; +- лимиты банов по ролям; +- ограничения повторных банов в серии. + +### Series + +Матч двух команд в рамках события или турнирной сетки. Хранит жеребьёвку, порядок первого бана, карты, счёт, статус и итогового победителя. + +### MapResult + +Исход отдельной карты: победившая команда либо ничья, счёт/заметка при необходимости и автор фиксации. Результат карты обновляет счёт серии; завершённый Bo3 определяет победителя автоматически. Организатор может исправить ошибочный результат, при этом изменение попадает в аудит. + +### MapDraft + +Пошаговое исключение карт из пула выбранного режима до одной оставшейся карты. Для тайбрейкера ранее сыгранная Control-карта исключается. + +### HeroDraft + +Четыре бана перед картой в порядке A → B → A → B. Каждая команда выбирает двух героев разных ролей. Героя, которого команда уже банила в этой серии, она не может забанить снова; героя, ранее забаненного соперником, банить можно. + +### Tournament + +Формат и состояние турнирной сетки, участники, раунды, пары и продвижение победителей. + +## Правила текущего регламента + +### Карты + +Базовая последовательность Bo3: + +1. Control; +2. Hybrid или Escort; +3. Control-тайбрейкер, если счёт 1:1. + +Альтернативная последовательность: Control → Push → Escort. + +Первый бан определяется жеребьёвкой. Затем команды по очереди исключают карты внутри пула режима, пока не останется одна. + +### Герои + +- перед каждой картой банятся четыре героя; +- порядок: A → B → A → B; +- каждая команда банит двух героев разных ролей; +- один и тот же герой может быть забанен командой только один раз за серию; +- бан героя соперником не расходует собственную возможность забанить этого героя позже. + +## Балансировка + +Целевая функция должна учитывать не только близость общего среднего рейтинга команд, но и: + +- разницу средних рейтингов по ролям; +- корректность состава 1 Tank / 2 Damage / 2 Support; +- предпочтения игроков; +- запрет повторения составов при регулярных играх; +- заранее заданные пары или ограничения «вместе/раздельно». + +Алгоритм должен возвращать не только составы, но и понятную оценку качества и причины оставшегося дисбаланса. + +## Доменные события + +- EventCreated; +- PlayerJoinedEvent; +- EventRegistrationChanged; +- TeamsBalanced; +- TeamCaptainAssigned; +- CoinTossResolved; +- MapBanned; +- MapSelected; +- HeroBanned; +- MapResultRecorded; +- MapResultCorrected; +- SeriesCompleted; +- BracketAdvanced. diff --git a/memory_bank/project_context.md b/memory_bank/project_context.md new file mode 100644 index 0000000..f0b12b9 --- /dev/null +++ b/memory_bank/project_context.md @@ -0,0 +1,44 @@ +# Mixmaker — контекст проекта + +## Зачем нужен продукт + +Mixmaker — веб-приложение для организации любительских Overwatch-миксов на 20+ участников. Оно должно сокращать время на ручную подготовку матчей, делать команды сопоставимыми по силе и хранить весь ход игровой встречи в одном месте. + +## Основные задачи + +- регистрация участников и оценка их силы по ролям; +- вход через Discord и самостоятельное редактирование игроком своих рейтингов; +- календарь запланированных миксов и отметки об участии; +- административная панель для управления событиями, участниками и их отметками; +- автоматическая балансировка нескольких команд; +- назначение капитанов сформированных команд; +- проведение жеребьёвки; +- пошаговые баны карт и героев с автоматической проверкой правил; +- ведение серии Bo3, фиксация исходов карт и итогового победителя; +- отображение турнирной сетки и итогов игрового вечера; +- управление процессом в реальном времени с телефонов и компьютеров. + +## Целевая аудитория + +- организатор игрового вечера; +- капитаны команд; +- игроки; +- зрители. + +## Первая версия + +Первая версия ориентирована на закрытое сообщество друзей. Игрок входит через Discord, заполняет рейтинги по ролям и отмечает участие в запланированном миксе. Admin при необходимости отмечает участие за игрока, подтверждает состав, формирует сбалансированные команды, назначает капитанов, запускает турнир, проводит серии по заданному регламенту и фиксирует результаты. + +## Ограничения и принципы + +- бизнес-правила не должны зависеть от UI, базы данных или конкретного транспорта; +- регламент карт и банов должен быть настраиваемым, а не зашитым во фронтенде; +- критичные действия матча должны быть воспроизводимыми и иметь историю; +- интерфейс должен хорошо работать на мобильных устройствах; +- production должен разворачиваться через Coolify из Docker Compose без пользовательских сетей; +- PostgreSQL входит в Compose-стек и использует постоянный том и внешние резервные копии; +- интеграция с Battle.net не обязательна для MVP. + +## Визуальное направление + +Современный тёмный интерфейс в стиле киберспортивной контрольной панели: глубокий графитовый фон, яркие оранжевые и голубые акценты команд, крупные счётчики, компактные карточки и заметная визуализация текущего шага драфта. diff --git a/memory_bank/roadmap.md b/memory_bank/roadmap.md new file mode 100644 index 0000000..750dacb --- /dev/null +++ b/memory_bank/roadmap.md @@ -0,0 +1,76 @@ +# Дорожная карта + +## Этап 0 — уточнение продукта + +- согласовать способ оценки игроков и рейтинг по ролям; +- определить размеры команд и число одновременно создаваемых команд; +- выбрать первый формат турнирной сетки; +- подтвердить редактируемые части регламента; +- подготовить wireframes ключевых экранов. + +## Этап 1 — фундамент + +- создать Go backend и React frontend; +- подготовить отдельный Compose для локальной разработки; +- подготовить production Compose для Coolify без пользовательских сетей; +- добавить multi-stage Dockerfile для frontend и backend; +- настроить PostgreSQL в составе production-стека, persistent volume и миграции; +- добавить healthcheck и graceful shutdown сервисов; +- описать переменные Coolify и настройку внешних резервных копий БД; +- реализовать Discord OAuth и серверные сессии; +- добавить роли Admin/Player и безопасное начальное назначение Admin по Discord ID; +- зафиксировать OpenAPI-контракт; +- реализовать базовую навигацию и дизайн-систему; +- добавить автоматические проверки и тесты. + +## Этап 2 — игроки и балансировка + +- самостоятельное заполнение профиля и рейтингов по ролям; +- календарь будущих миксов; +- статусы участия Going / Maybe / NotGoing; +- админку для событий, игроков и регистраций; +- изменение Admin статуса участия за другого игрока с аудитом; +- подтверждение списка участников Admin; +- назначение доступных ролей; +- генерация нескольких вариантов команд; +- оценка качества баланса; +- ручная перестановка игроков с пересчётом показателей. +- назначение и переназначение капитана каждой команды. + +## Этап 3 — проведение серии + +- создание пары команд; +- серверная жеребьёвка с прозрачным результатом; +- драфт карт по выбранному ruleset; +- бан героев с проверкой ролей и истории серии; +- фиксация победителя или ничьей каждой карты; +- автоматический счёт серии и определение победителя; +- исправление ошибочного результата с аудитом; +- синхронизация клиентов в реальном времени. + +## Этап 4 — турнир + +- single-elimination сетка; +- автоматическое создание следующих пар; +- экран трансляции/зрителя; +- история результатов игрового вечера. + +## Этап 5 — удобство сообщества + +- пресеты регламентов; +- статистика игроков и команд; +- повторная жеребьёвка с защитой от одинаковых составов; +- Discord-уведомления; +- импорт данных и резервное копирование. + +## Идеи после MVP + +- режим «капитанский драфт» игроков; +- ограничения «хочу вместе» и «не ставить вместе»; +- сезонный рейтинг сообщества; +- прогноз вероятности победы и подсветка причин дисбаланса; +- голосование зрителей за карту или MVP; +- публичный overlay для стрима; +- PWA с push-уведомлением о начале матча; +- синхронизация событий с внешним календарём через iCalendar; +- библиотека версионируемых регламентов под разные патчи.