Skip to content

feat(account): роли, баны и репорты — модерация (итер. 39) - #43

Merged
Azazlokus merged 1 commit into
mainfrom
feat/roles-bans-reports
Aug 18, 2026
Merged

Azazlokus merged 1 commit into
mainfrom
feat/roles-bans-reports

Conversation

@Azazlokus

Copy link
Copy Markdown
Owner

Что

Итерация 39 — роли + баны + репорты (модерация). Первая осмысленная связка
бэкенд→game-join: забаненному аккаунту шлюз отказывает во входе. Роль на аккаунте,
модераторские действия под ролью, жалобы игроков.

Зачем

Базовая модерация: наказывать нарушителей (бан), разграничивать права (роли),
собирать сигналы (репорты). Бан завязан на отзыв сессий из итер. 36.

Как

  • store — миграция 0004 (sqlite+postgres): accounts.role; таблицы bans
    (история; активный бан — lifted_at=0 и не истёк, считает ActiveBan) и reports.
    Методы SetRole/BanAccount/LiftBans/ActiveBan/CreateReport/ListReports;
    AccountByID/CredentialsByUsername читают role.
  • account — иерархия ролей user<moderator<admin (roles.go: RoleRank/ValidRole);
    IsBanned — обёртка над ActiveBan для шлюза и /api/me.
  • api — POST /api/report (любой залогиненный, не self, target существует);
    /api/mod/ban/unban/reports (moderator+), /api/mod/role (admin) под
    requireRole. Ключевое: роль тянется из БД (не из токена — могла смениться), бан
    актора тоже блокирует mod-действия
    (access живёт до TTL). Бан отзывает все
    refresh-сессии; модератор не банит равного/старшего; смена своей роли запрещена.
    /me несёт role + статус бана.
  • cmd/server — шлюз после resolveIdentity зовёт IsBanned и закрывает соединение
    забаненному ДО входа в комнату (игровое ядро про баны не знает; fail-open при ошибке
    БД — availability). Env ARENA_ADMIN_USERNAME повышает аккаунт до admin при старте.
  • web — баннер бана + блокировка connect, роль в панели, кнопка report в профиле.
  • docs — README RU/EN + docs/architecture.md.

Границы

internal/game/провод/симуляция НЕ тронуты (стражи determinism/protocol не нужны);
шлюз-проверка — синхронный store-вызов, новых горутин нет. Бэкенд-фича безопасности →
security-review: HIGH/MEDIUM нет (авторизация из БД, ранговые проверки, бан
блокирует и mod-действия, SQL параметризован, reason без unsafe-рендера).

Тестирование

  • make check + make integration — зелёные.
  • Покрытие: store (роли/баны с истечением и снятием/репорты; Postgres-сьют дополнен
    bans/reports), account (IsBanned), api (рол-гейтинг, бан→/me→refresh-revoke,
    репорт self/unknown/guest, забаненный модератор→403), e2e TestE2EBannedAccountRefused
    (забаненный аккаунт получает отказ на WS-join, гость заходит).
  • Live-smoke на свежей БД (миграция 0004): бутстрап admin через ARENA_ADMIN_USERNAME,
    бан→/me banned, non-mod→403, unban→/me clean.
  • node --check web/game.js.

BENCHMARKS.md не трогался — горячего пути нет.

Первая связка бэкенд→game-join: забаненному шлюз отказывает во входе. Роль на
аккаунте, модераторские действия под ролью, репорты игроков.

- store: миграция 0004 (sqlite+postgres) — accounts.role; таблицы bans (история,
  активный = не снят и не истёк) и reports. Методы SetRole/BanAccount/LiftBans/
  ActiveBan/CreateReport/ListReports; AccountByID/CredentialsByUsername читают role.
- account: роли user<moderator<admin (roles.go: RoleRank/ValidRole); IsBanned —
  обёртка над ActiveBan для шлюза и /api/me.
- api: POST /api/report (любой залогиненный), /api/mod/ban|unban|reports (moderator+),
  /api/mod/role (admin) под requireRole (актуальная роль из БД, не из токена; бан
  актора тоже блокирует). Бан отзывает все refresh-сессии. /me несёт role + ban.
  ErrEmailTaken→409, forbidden→403.
- cmd/server: шлюз зовёт IsBanned после resolveIdentity и закрывает соединение
  забаненному до комнаты (fail-open при ошибке БД); env ARENA_ADMIN_USERNAME
  повышает аккаунт до admin при старте (бутстрап). Игровое ядро не тронуто.
- web: баннер бана + блокировка connect, роль в панели, кнопка report в профиле.
- docs: README RU/EN + architecture.

Игровое ядро/провод/симуляция не тронуты (стражи determ/protocol не нужны); шлюз-
проверка — синхронный store-вызов без новых горутин. security-review — findings нет.
Покрытие: store (роли/баны/репорты), account (IsBanned), api (рол-гейтинг/бан/репорт
end-to-end), e2e (забаненный не заходит, гость заходит). make check + integration +
live-smoke зелёные.
@Azazlokus
Azazlokus merged commit ba1818a into main Aug 18, 2026
10 checks passed
@Azazlokus
Azazlokus deleted the feat/roles-bans-reports branch August 18, 2026 13:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant