docs: update wiki for 1.6.0 co-gm delegation

2026-04-27 14:25:42 +03:00
parent 449640e3c5
commit e668e4756b
7 changed files with 62 additions and 32 deletions
@@ -61,14 +61,15 @@ Blazor Server-приложение использует cookie auth и Telegram
- `TelegramAuthService` валидирует HMAC-SHA256 подпись Telegram Login Widget и `auth_date`. - `TelegramAuthService` валидирует HMAC-SHA256 подпись Telegram Login Widget и `auth_date`.
- `SessionService` читает и обновляет группы/сессии через Dapper, включая bulk-операции по `batch_id`. - `SessionService` читает и обновляет группы/сессии через Dapper, включая bulk-операции по `batch_id`.
- `SessionService` сохраняет режим уведомлений batch и дублирует Web-уведомления в ЛС, если включён `GroupAndDirect`. - `SessionService` сохраняет режим уведомлений batch и дублирует Web-уведомления в ЛС, если включён `GroupAndDirect`.
- `SessionService` читает `group_managers`, проверяет роли `Owner`/`CoGm` и сохраняет назначения co-GM.
- `BatchSchedulePlanner` задаёт детерминированные правила fixed-interval переноса и clone-смещения batch. - `BatchSchedulePlanner` задаёт детерминированные правила fixed-interval переноса и clone-смещения batch.
- `AuthorizedSessionService` проверяет, что текущий Telegram ID является ГМом группы. - `AuthorizedSessionService` проверяет, что текущий Telegram ID является owner или co-GM группы; owner-only операции делегирования проходят через отдельную проверку роли.
Основные страницы: Основные страницы:
- `/login` — вход через Telegram. - `/login` — вход через Telegram.
- `/` — список групп ГМа. - `/` — список групп, где пользователь owner или co-GM.
- `/group/{GroupId}` — будущие сессии группы и batch bulk-операции. - `/group/{GroupId}` управляющие группы, будущие сессии и batch bulk-операции.
- `/session/edit/{SessionId}` — редактирование названия, времени и ссылки. - `/session/edit/{SessionId}` — редактирование названия, времени и ссылки.
## Общий домен ## Общий домен
@@ -78,6 +79,7 @@ Blazor Server-приложение использует cookie auth и Telegram
- `SessionStatus`: `Planned`, `ConfirmationSent`, `Confirmed`, `Cancelled`. - `SessionStatus`: `Planned`, `ConfirmationSent`, `Confirmed`, `Cancelled`.
- `RsvpStatus`: `Pending`, `Confirmed`, `Declined`. - `RsvpStatus`: `Pending`, `Confirmed`, `Declined`.
- `SessionNotificationMode`: `GroupAndDirect`, `GroupOnly`. - `SessionNotificationMode`: `GroupAndDirect`, `GroupOnly`.
- `GroupManagerRole`: `Owner`, `CoGm`.
- `MoscowTime`: парсинг и форматирование МСК (`UTC+3`). - `MoscowTime`: парсинг и форматирование МСК (`UTC+3`).
- `SessionBatchRenderer`: единый renderer для Telegram-сообщения пачки сессий. - `SessionBatchRenderer`: единый renderer для Telegram-сообщения пачки сессий.
@@ -1,6 +1,6 @@
# База данных # База данных
GM-Relay **v1.5.0** использует PostgreSQL. Изменения схемы управляются DbUp-миграциями, встроенными в `GmRelay.Bot` как embedded resources. GM-Relay **v1.6.0** использует PostgreSQL. Изменения схемы управляются DbUp-миграциями, встроенными в `GmRelay.Bot` как embedded resources.
## Миграции ## Миграции
@@ -13,6 +13,7 @@ GM-Relay **v1.5.0** использует PostgreSQL. Изменения схем
- `V005__add_batch_message_id.sql` — поле `sessions.batch_message_id` для редактирования исходного сообщения расписания. - `V005__add_batch_message_id.sql` — поле `sessions.batch_message_id` для редактирования исходного сообщения расписания.
- `V006__add_session_capacity_waitlist.sql` — лимит мест `sessions.max_players`, статус участника `session_participants.registration_status`, время постановки в очередь `session_participants.created_at` и индексы для waitlist. - `V006__add_session_capacity_waitlist.sql` — лимит мест `sessions.max_players`, статус участника `session_participants.registration_status`, время постановки в очередь `session_participants.created_at` и индексы для waitlist.
- `V007__add_session_notification_mode.sql` — режим уведомлений `sessions.notification_mode`, отметка обработки T-1h reminder `sessions.one_hour_reminder_processed_at` и индекс для одночасовых напоминаний. - `V007__add_session_notification_mode.sql` — режим уведомлений `sessions.notification_mode`, отметка обработки T-1h reminder `sessions.one_hour_reminder_processed_at` и индекс для одночасовых напоминаний.
- `V008__add_group_managers.sql` — таблица `group_managers` для ролей `Owner` и `CoGm`; миграция переносит текущих GM из `game_groups.gm_telegram_id` в owner-записи.
## Основные таблицы ## Основные таблицы
@@ -34,11 +35,27 @@ Telegram-группы, где организуются игры.
- `telegram_chat_id` — уникальный Telegram chat ID. - `telegram_chat_id` — уникальный Telegram chat ID.
- `name` — актуальное название Telegram-чата. - `name` — актуальное название Telegram-чата.
- `gm_telegram_id` — Telegram ID GM для этой группы. - `gm_telegram_id` — Telegram ID первого owner для совместимости с ранними версиями и миграциями; новая проверка доступа идёт через `group_managers`.
### group_managers
Таблица управляющих группой. Она поддерживает несколько пользователей с правами управления одной Telegram-группой.
Важные поля:
- `group_id` и `player_id` — уникальная пара группы и пользователя.
- `role``Owner` или `CoGm`.
- `added_by_player_id` — кто назначил co-GM; для owner-записей из миграции может быть `NULL`.
- `created_at` — время назначения роли.
Индексы:
- `ix_group_managers_group_role` ускоряет выбор управляющих группы и проверку owner.
- `ix_group_managers_player` ускоряет список групп, доступных пользователю в Web Dashboard.
### game_group_members ### game_group_members
Таблица связи группы и игроков. Сейчас основная проверка роли GM идёт через `game_groups.gm_telegram_id`; таблица остаётся базовой схемой для группового membership. Таблица связи группы и игроков. Она остаётся базовой схемой для группового membership; права управления вынесены в `group_managers`.
### sessions ### sessions
@@ -1,6 +1,6 @@
# Быстрый старт # Быстрый старт
Эта страница описывает минимальный запуск текущей версии GM-Relay **v1.5.0**. Эта страница описывает минимальный запуск текущей версии GM-Relay **v1.6.0**.
## Требования ## Требования
@@ -41,8 +41,8 @@ docker compose up -d
Compose поднимает: Compose поднимает:
- `db`: PostgreSQL 17 Alpine, БД `gmrelay_db`, пользователь `gmrelay`. - `db`: PostgreSQL 17 Alpine, БД `gmrelay_db`, пользователь `gmrelay`.
- `bot`: образ `git.codeanddice.ru/toutsu/gmrelay-bot:1.5.0`. - `bot`: образ `git.codeanddice.ru/toutsu/gmrelay-bot:1.6.0`.
- `web`: образ `git.codeanddice.ru/toutsu/gmrelay-web:1.5.0`. - `web`: образ `git.codeanddice.ru/toutsu/gmrelay-web:1.6.0`.
Web UI будет доступен на `http://localhost:8080`, если `GMRELAY_WEB_PORT` не переопределён. Web UI будет доступен на `http://localhost:8080`, если `GMRELAY_WEB_PORT` не переопределён.
@@ -73,5 +73,5 @@ dotnet run --project src/GmRelay.AppHost
- `/help` должен показать формат `/newsession`, включая необязательную строку `Мест:`. - `/help` должен показать формат `/newsession`, включая необязательную строку `Мест:`.
- В сообщении расписания у активной сессии должны быть кнопки записи и `Выйти`. - В сообщении расписания у активной сессии должны быть кнопки записи и `Выйти`.
- Web-панель должна перенаправлять неавторизованного пользователя на `/login`. - Web-панель должна перенаправлять неавторизованного пользователя на `/login`.
- После входа через Telegram GM видит только группы, где он записан как `gm_telegram_id`. - После входа через Telegram пользователь видит группы, где он назначен owner или co-GM.
- На странице группы GM видит блоки batch-операций: общий title/link, перенос всей пачки и клонирование batch. - На странице группы owner видит блок управления co-GM, а owner/co-GM видят batch-операции: общий title/link, режим уведомлений, перенос всей пачки и клонирование batch.
@@ -1,6 +1,6 @@
# Развёртывание # Развёртывание
Текущий production-like способ запуска GM-Relay **v1.5.0** — Docker Compose из `compose.yaml`. Текущий production-like способ запуска GM-Relay **v1.6.0** — Docker Compose из `compose.yaml`.
## Сервисы Docker Compose ## Сервисы Docker Compose
@@ -15,13 +15,13 @@
`bot`: `bot`:
- образ: `git.codeanddice.ru/toutsu/gmrelay-bot:1.5.0`; - образ: `git.codeanddice.ru/toutsu/gmrelay-bot:1.6.0`;
- запускается после успешного healthcheck сервиса `db`; - запускается после успешного healthcheck сервиса `db`;
- переменные окружения: `ConnectionStrings__gmrelaydb`, `Telegram__BotToken`. - переменные окружения: `ConnectionStrings__gmrelaydb`, `Telegram__BotToken`.
`web`: `web`:
- образ: `git.codeanddice.ru/toutsu/gmrelay-web:1.5.0`; - образ: `git.codeanddice.ru/toutsu/gmrelay-web:1.6.0`;
- запускается после успешного healthcheck сервиса `db`; - запускается после успешного healthcheck сервиса `db`;
- переменные окружения: `ConnectionStrings__gmrelaydb`, `Telegram__BotToken`, `Telegram__BotUsername`; - переменные окружения: `ConnectionStrings__gmrelaydb`, `Telegram__BotToken`, `Telegram__BotUsername`;
- порт: `${GMRELAY_WEB_PORT:-8080}:8080`; - порт: `${GMRELAY_WEB_PORT:-8080}:8080`;
@@ -92,14 +92,14 @@ docker compose down -v
## Поведение миграций ## Поведение миграций
Бот применяет DbUp-миграции при старте до обработки Telegram updates. В версии `1.5.0` добавлена миграция `V007__add_session_notification_mode.sql` для режима уведомлений batch и отметки T-1h reminder. После обновления стоит проверить логи `bot`, чтобы убедиться, что миграции применились без ошибок. Бот применяет DbUp-миграции при старте до обработки Telegram updates. В версии `1.6.0` добавлена миграция `V008__add_group_managers.sql`: она создаёт `group_managers` и переносит текущих GM в роль `Owner`. После обновления стоит проверить логи `bot`, чтобы убедиться, что миграции применились без ошибок.
## Безопасность ## Безопасность
- При старте бот логирует PostgreSQL connection string через `SecretRedactor`, чтобы не раскрывать пароль. - При старте бот логирует PostgreSQL connection string через `SecretRedactor`, чтобы не раскрывать пароль.
- Web-cookie настроены как `HttpOnly`, `SecurePolicy.Always`, `SameSite.Strict`, со sliding expiration на 7 дней. - Web-cookie настроены как `HttpOnly`, `SecurePolicy.Always`, `SameSite.Strict`, со sliding expiration на 7 дней.
- Web-ответы добавляют заголовки `X-Content-Type-Options`, `X-Frame-Options`, `Referrer-Policy` и `Permissions-Policy`. - Web-ответы добавляют заголовки `X-Content-Type-Options`, `X-Frame-Options`, `Referrer-Policy` и `Permissions-Policy`.
- Доступ к данным групп и сессий проверяется сравнением Telegram ID пользователя с `game_groups.gm_telegram_id`. - Доступ к данным групп и сессий проверяется через `group_managers`: owner и co-GM могут управлять расписанием, а назначать co-GM может только owner.
## Чеклист обновления ## Чеклист обновления
@@ -26,7 +26,7 @@ dotnet run --project src/GmRelay.AppHost
`Directory.Build.props` задаёт: `Directory.Build.props` задаёт:
- `Version`: `1.5.0`. - `Version`: `1.6.0`.
- `TargetFramework`: `net10.0`. - `TargetFramework`: `net10.0`.
- `LangVersion`: `preview`. - `LangVersion`: `preview`.
- `Nullable`: `enable`. - `Nullable`: `enable`.
@@ -1,10 +1,18 @@
# Руководство ГМа # Руководство ГМа
Руководство описывает пользовательские сценарии бота и Web-панели для GM-Relay **v1.5.0**. Руководство описывает пользовательские сценарии бота и Web-панели для GM-Relay **v1.6.0**.
## Кто считается ГМом ## Кто управляет группой
GM группы определяется полем `game_groups.gm_telegram_id`. При первом создании сессии в группе бот сохраняет Telegram ID автора как GM. Последующие операции управления проверяют этот ID. При первом создании сессии в группе бот сохраняет автора как owner группы. Owner хранится в таблице `group_managers` с ролью `Owner`; историческое поле `game_groups.gm_telegram_id` остаётся для совместимости и миграций.
Owner может назначать помощников с ролью `CoGm` в Web Dashboard. Owner и co-GM могут создавать, отменять, удалять и переносить сессии, редактировать batch и поднимать игроков из листа ожидания. Только owner может добавлять или убирать co-GM.
## Делегирование co-GM
На странице группы Web-панель показывает блок управления группой: owner, список co-GM и текущую роль пользователя. Чтобы добавить помощника, owner указывает Telegram ID, имя и при необходимости username. После сохранения co-GM видит эту группу на главной странице Web Dashboard и получает доступ к тем же операциям управления расписанием, что и owner.
Если co-GM больше не должен помогать с группой, owner удаляет его из того же блока. Снятие роли не удаляет игрока из таблицы `players` и не меняет его записи на игры.
## Создание расписания ## Создание расписания
@@ -53,7 +61,7 @@ GM группы определяется полем `game_groups.gm_telegram_id`
## Повышение из листа ожидания ## Повышение из листа ожидания
GM может поднять первого игрока из очереди: Owner или co-GM может поднять первого игрока из очереди:
- в Telegram — кнопкой `Из ожидания (ГМ)` в сообщении расписания; - в Telegram — кнопкой `Из ожидания (ГМ)` в сообщении расписания;
- в Web Dashboard — кнопкой `Из ожидания` в списке сессий. - в Web Dashboard — кнопкой `Из ожидания` в списке сессий.
@@ -62,7 +70,7 @@ GM может поднять первого игрока из очереди:
## Bulk-операции для batch в Web ## Bulk-операции для batch в Web
На странице группы Web-панель показывает отдельный блок для каждой видимой пачки игр. GM может: На странице группы Web-панель показывает отдельный блок для каждой видимой пачки игр. Owner и co-GM могут:
- обновить общий `title` и `link` сразу у всех сессий batch; - обновить общий `title` и `link` сразу у всех сессий batch;
- выбрать режим уведомлений для игроков: `В группе и в личку` или `Только в группе`; - выбрать режим уведомлений для игроков: `В группе и в личку` или `Только в группе`;
@@ -76,7 +84,7 @@ GM может поднять первого игрока из очереди:
## Отмена и удаление ## Отмена и удаление
- `Отменить <дата> (ГМ)` в сообщении расписания меняет статус сессии на `Cancelled` и оставляет её в истории пачки. - `Отменить <дата> (ГМ)` в сообщении расписания меняет статус сессии на `Cancelled` и оставляет её в истории пачки.
- `/listsessions` показывает будущие сессии; если команду вызывает GM, бот добавляет кнопки удаления. - `/listsessions` показывает будущие сессии; если команду вызывает owner или co-GM, бот добавляет кнопки удаления.
- Удаление физически удаляет сессию из БД. Если после удаления пачка пустая и была создана forum-тема, бот пытается удалить тему. - Удаление физически удаляет сессию из БД. Если после удаления пачка пустая и была создана forum-тема, бот пытается удалить тему.
## Перенос сессии ## Перенос сессии
@@ -85,9 +93,9 @@ GM может поднять первого игрока из очереди:
Поток: Поток:
1. Бот проверяет, что кнопку нажал GM. 1. Бот проверяет, что кнопку нажал owner или co-GM.
2. Создаётся `reschedule_proposals` со статусом `AwaitingTime`. 2. Создаётся `reschedule_proposals` со статусом `AwaitingTime`.
3. GM пишет новое время обычным сообщением в чат. 3. Инициатор переноса пишет новое время обычным сообщением в чат.
4. Если активных участников нет, бот переносит сессию сразу. 4. Если активных участников нет, бот переносит сессию сразу.
5. Если активные участники есть, бот создаёт голосование. 5. Если активные участники есть, бот создаёт голосование.
6. Любой голос `Против` отклоняет перенос. 6. Любой голос `Против` отклоняет перенос.
@@ -108,7 +116,7 @@ GM может поднять первого игрока из очереди:
## Web-панель ## Web-панель
Web UI доступен после входа через Telegram Login Widget. GM может: Web UI доступен после входа через Telegram Login Widget. Owner и co-GM могут:
- видеть свои Telegram-группы; - видеть свои Telegram-группы;
- открыть список предстоящих сессий группы; - открыть список предстоящих сессий группы;
@@ -118,4 +126,6 @@ Web UI доступен после входа через Telegram Login Widget.
- выполнять bulk-операции над batch: общий title/link, перенос пачки и клонирование на неделю или месяц. - выполнять bulk-операции над batch: общий title/link, перенос пачки и клонирование на неделю или месяц.
- выбирать режим уведомлений batch: групповые сообщения с личными DM или только групповые сообщения. - выбирать режим уведомлений batch: групповые сообщения с личными DM или только групповые сообщения.
Дополнительно owner может управлять списком co-GM на странице группы.
При сохранении отдельной сессии Web-панель обновляет запись в БД, отправляет уведомление в Telegram-группу и пытается перерисовать исходное сообщение расписания пачки. Bulk-операции обновляют исходное batch-сообщение, а clone публикует новое сообщение для новой пачки. При сохранении отдельной сессии Web-панель обновляет запись в БД, отправляет уведомление в Telegram-группу и пытается перерисовать исходное сообщение расписания пачки. Bulk-операции обновляют исходное batch-сообщение, а clone публикует новое сообщение для новой пачки.
+7 -6
@@ -1,10 +1,10 @@
# Главная # Главная
GM-Relay — Telegram-бот и Blazor-панель для организации TTRPG-сессий. Текущее состояние документации соответствует репозиторию `Toutsu/GmRelayBot` и релизу **v1.5.0**. GM-Relay — Telegram-бот и Blazor-панель для организации TTRPG-сессий. Текущее состояние документации соответствует репозиторию `Toutsu/GmRelayBot` и релизу **v1.6.0**.
## Текущий стек ## Текущий стек
- Версия проекта: `1.5.0`. - Версия проекта: `1.6.0`.
- Платформа: `.NET 10`, C# preview, nullable reference types, warnings as errors. - Платформа: `.NET 10`, C# preview, nullable reference types, warnings as errors.
- Оркестрация разработки: `.NET Aspire 13` через `src/GmRelay.AppHost`. - Оркестрация разработки: `.NET Aspire 13` через `src/GmRelay.AppHost`.
- Runtime бота: `Worker Service`, Telegram long polling, Native AOT. - Runtime бота: `Worker Service`, Telegram long polling, Native AOT.
@@ -20,16 +20,17 @@ GM-Relay — Telegram-бот и Blazor-панель для организаци
- Интерактивная запись игроков на конкретные даты и самостоятельный выход через inline-кнопки Telegram. - Интерактивная запись игроков на конкретные даты и самостоятельный выход через inline-кнопки Telegram.
- Лист ожидания: если основной состав заполнен, новые игроки не переполняют сессию, а попадают в очередь. - Лист ожидания: если основной состав заполнен, новые игроки не переполняют сессию, а попадают в очередь.
- Автоматическое освобождение места: когда активный игрок снимает запись, первый ожидающий переводится в основной состав. - Автоматическое освобождение места: когда активный игрок снимает запись, первый ожидающий переводится в основной состав.
- Повышение первого игрока из листа ожидания кнопкой GM в Telegram или Web Dashboard. - Делегирование управления группой: owner может назначать co-GM, а co-GM управляет расписанием в Telegram и Web Dashboard.
- Повышение первого игрока из листа ожидания кнопкой owner/co-GM в Telegram или Web Dashboard.
- Автоматическое создание Telegram forum topic для пачки игр, если группа является форумом. - Автоматическое создание Telegram forum topic для пачки игр, если группа является форумом.
- Отмена отдельной сессии GM из основного сообщения расписания. - Отмена отдельной сессии owner/co-GM из основного сообщения расписания.
- Управление сессиями через `/listsessions` с отображением мест и очереди ожидания. - Управление сессиями через `/listsessions` с отображением мест и очереди ожидания.
- Перенос сессии через кнопку GM и голосование активных участников. - Перенос сессии через кнопку owner/co-GM и голосование активных участников.
- RSVP-подтверждение за 24 часа до игры только для основного состава. - RSVP-подтверждение за 24 часа до игры только для основного состава.
- Персональные DM-уведомления игрокам о RSVP за 24 часа, напоминание за 1 час, ссылке перед стартом, отмене и переносе. - Персональные DM-уведомления игрокам о RSVP за 24 часа, напоминание за 1 час, ссылке перед стартом, отмене и переносе.
- Отправка ссылки на подключение за 5 минут до подтверждённой игры. - Отправка ссылки на подключение за 5 минут до подтверждённой игры.
- Экспорт будущих запланированных сессий в `.ics` через `/exportcalendar`. - Экспорт будущих запланированных сессий в `.ics` через `/exportcalendar`.
- Web-панель для GM: список групп, список сессий, редактирование названия, времени, ссылки и лимита мест. - Web-панель для owner/co-GM: список групп, список сессий, редактирование названия, времени, ссылки и лимита мест.
- Bulk-операции в Web Dashboard: общий `title/link` для batch, перенос всей пачки на фиксированный шаг и клонирование на следующую неделю или месяц с новым Telegram-сообщением. - Bulk-операции в Web Dashboard: общий `title/link` для batch, перенос всей пачки на фиксированный шаг и клонирование на следующую неделю или месяц с новым Telegram-сообщением.
- Настройка режима уведомлений для batch: `В группе и в личку` или `Только в группе`, при этом групповые сообщения сохраняются всегда. - Настройка режима уведомлений для batch: `В группе и в личку` или `Только в группе`, при этом групповые сообщения сохраняются всегда.
- CSS-fix Web Dashboard: раскрывающиеся списки используют контрастный фон и текст в native select dropdown. - CSS-fix Web Dashboard: раскрывающиеся списки используют контрастный фон и текст в native select dropdown.