Add player profiles and community settings
Some checks failed
CI / backend (push) Has been cancelled
CI / frontend (push) Has been cancelled
CI / compose (push) Has been cancelled

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-19 21:43:48 +03:00
parent 5e0825f43f
commit fa4edc0df5
23 changed files with 1280 additions and 57 deletions

View File

@@ -4,9 +4,11 @@
### Player
Игрок связан с Discord-аккаунтом и имеет отображаемое имя и собственный Overwatch-ранг для каждой роли: Tank, Damage, Support. Лестница содержит 40 значений от Bronze 5 до Champion 1: Bronze, Silver, Gold, Platinum, Diamond, Master, Grandmaster, Champion, каждый с дивизионами 5 → 1. Для вычислений значения преобразуются в ordinal 140.
Игрок связан с Discord-аккаунтом либо создан как guest и имеет уникальный без учёта регистра nickname длиной 232 символа. Discord username используется только для учётной записи и не является публичным игровым именем. Связанный игрок может дополнительно указать публичный BattleTag в формате `Name#1234`.
Игрок редактирует ранги самостоятельно; Admin может видеть время последнего изменения. Игрок выбирает любое число предпочитаемых ролей, до трёх желаемых союзников и до трёх игроков для avoid. Предпочтения и avoid являются мягкими пожеланиями, а не гарантией состава; один игрок не может одновременно находиться в обоих списках.
Игрок редактирует nickname, BattleTag и собственный Overwatch-ранг для каждой роли: Tank, Damage, Support. Лестница содержит 40 значений от Bronze 5 → Champion 1 и внутри представляется ordinal 140. Игрок выбирает любое число предпочитаемых ролей, до трёх желаемых союзников и до трёх игроков для avoid. Предпочтения и avoid являются мягкими пожеланиями, а не гарантией состава; один игрок не может одновременно находиться в обоих списках.
Авторизованные пользователи могут открыть read-only профиль любого Player, включая guest: текущие ранги, число завершённых Bo3, победы, win rate, карты W/L/D и последние матчи. Статистика вычисляется из завершённых Event/Series и эффективных результатов после corrections. Для существующей модели участие определяется финальным сохранённым составом Event; reserve не получает матч, а emergency substitution относит историю к финальному roster.
### Account
@@ -24,6 +26,10 @@
Созданный микс проецируется во внешний Discord-канал как информационный анонс со ссылкой на страницу Event. Параметр команды создания определяет, сопровождается ли анонс уведомлением `@everyone`; он не является сохраняемым состоянием Event. Анонс не является источником состояния регистрации: RSVP, доступность события и все переходы workflow по-прежнему определяет backend Mixmaker. Недоступность Discord не отменяет валидное создание Event.
### CommunitySettings
Singleton-настройки сообщества содержат ссылку-приглашение на Discord, которую FAQ показывает авторизованным игрокам. Читать настройки может любой авторизованный пользователь, изменять ссылку — только Admin, не Moderator; изменение сохраняет автора в audit log. Пустая ссылка скрывает кнопку приглашения.
### Discord-роли состава
Подтверждённый Roster является источником desired state для внешних Discord-ролей. Каждый участник получает временную роль с `Team.Name`, роль своего slot-а Tank/Damage/Support, а капитан — отдельную `${Team.Name} Captain`. Discord role ID и выданные ботом назначения сохраняются отдельно от доменных Team и Account, чтобы повторная синхронизация была идемпотентной.