From 5e33e3bbae2525d558a3b815d0bc3ddc2e9db75c Mon Sep 17 00:00:00 2001 From: Toutsu Date: Mon, 27 Apr 2026 14:58:56 +0300 Subject: [PATCH] docs: update wiki for 1.7.0 reschedule voting --- ...%82%D0%B5%D0%BA%D1%82%D1%83%D1%80%D0%B0.md | 8 ++++--- ...B0-%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85.md | 18 ++++++++++++++-- ...8B%D0%B9-%D1%81%D1%82%D0%B0%D1%80%D1%82.md | 7 ++++--- ...%82%D1%8B%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5.md | 8 +++---- ...%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B0.md | 4 ++-- ...81%D1%82%D0%B2%D0%BE-%D0%93%D0%9C%D0%B0.md | 21 +++++++++++++------ Home.md | 6 +++--- 7 files changed, 49 insertions(+), 23 deletions(-) diff --git a/%D0%90%D1%80%D1%85%D0%B8%D1%82%D0%B5%D0%BA%D1%82%D1%83%D1%80%D0%B0.md b/%D0%90%D1%80%D1%85%D0%B8%D1%82%D0%B5%D0%BA%D1%82%D1%83%D1%80%D0%B0.md index c45e1d7..469f136 100644 --- a/%D0%90%D1%80%D1%85%D0%B8%D1%82%D0%B5%D0%BA%D1%82%D1%83%D1%80%D0%B0.md +++ b/%D0%90%D1%80%D1%85%D0%B8%D1%82%D0%B5%D0%BA%D1%82%D1%83%D1%80%D0%B0.md @@ -19,7 +19,7 @@ GM-Relay состоит из нескольких .NET-проектов и об - сценариев немного, отдельный Clean Architecture слой был бы лишним; - зависимости Npgsql и Telegram.Bot стабильны; - Native AOT требует явной регистрации зависимостей и аккуратного SQL-маппинга; -- BackgroundService + PeriodicTimer проще и надёжнее Quartz.NET для двух периодических проверок. +- BackgroundService + PeriodicTimer проще и надёжнее Quartz.NET для периодических проверок расписания и дедлайнов голосования. ## Поток Telegram updates @@ -33,9 +33,9 @@ GM-Relay состоит из нескольких .NET-проектов и об - callback `cancel_session:`; - callback `delete_session:`; - callback `reschedule_session:`; -- callback `reschedule_vote::`; +- callback `reschedule_vote:`; - callback `rsvp::`; -- обычные текстовые сообщения ГМа как ввод нового времени для активного переноса. +- обычные текстовые сообщения ГМа как ввод 2-3 вариантов времени и дедлайна для активного переноса. Маршрутизация не использует reflection или assembly scanning. @@ -52,6 +52,8 @@ GM-Relay состоит из нескольких .NET-проектов и об Состояние хранится в PostgreSQL, поэтому после рестарта сервис продолжает работу без in-memory очередей. +`RescheduleVotingDeadlineService` — отдельный stateless background service. Он раз в минуту ищет `reschedule_proposals` в статусе `Voting`, у которых `voting_deadline_at <= now()`, выбирает вариант с наибольшим числом голосов, применяет перенос или отклоняет голосование при ничьей/нуле голосов, обновляет Telegram-сообщения и сбрасывает RSVP при успешном переносе. + ## Web UI Blazor Server-приложение использует cookie auth и Telegram Login Widget. diff --git a/%D0%91%D0%B0%D0%B7%D0%B0-%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85.md b/%D0%91%D0%B0%D0%B7%D0%B0-%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85.md index 6b88439..52b7182 100644 --- a/%D0%91%D0%B0%D0%B7%D0%B0-%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85.md +++ b/%D0%91%D0%B0%D0%B7%D0%B0-%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85.md @@ -1,6 +1,6 @@ # База данных -GM-Relay **v1.6.0** использует PostgreSQL. Изменения схемы управляются DbUp-миграциями, встроенными в `GmRelay.Bot` как embedded resources. +GM-Relay **v1.7.0** использует PostgreSQL. Изменения схемы управляются DbUp-миграциями, встроенными в `GmRelay.Bot` как embedded resources. ## Миграции @@ -14,6 +14,7 @@ GM-Relay **v1.6.0** использует PostgreSQL. Изменения схем - `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` и индекс для одночасовых напоминаний. - `V008__add_group_managers.sql` — таблица `group_managers` для ролей `Owner` и `CoGm`; миграция переносит текущих GM из `game_groups.gm_telegram_id` в owner-записи. +- `V009__add_multi_option_reschedule_votes.sql` — дедлайн и выбранный вариант в `reschedule_proposals`, таблицы `reschedule_options` и `reschedule_option_votes` для голосования по нескольким слотам. ## Основные таблицы @@ -113,9 +114,22 @@ Bulk-операции Web не требуют новых таблиц: общи - `Approved` — перенос принят. - `Rejected` — перенос отклонён. +Важные поля: + +- `voting_deadline_at` — дедлайн голосования по вариантам. +- `selected_option_id` — победивший вариант после финализации, если перенос принят. + +### reschedule_options + +Варианты нового времени для активного предложения переноса. Для одного предложения хранится 2-3 строки с `display_order` и `proposed_at`. + +### reschedule_option_votes + +Голоса активных участников по вариантам переноса. Уникальная пара `proposal_id + player_id` не даёт одному участнику проголосовать несколько раз; повторный голос обновляет `option_id` и время `voted_at`. + ### reschedule_votes -Голоса активных участников по предложению переноса. Уникальная пара `proposal_id + player_id` не даёт одному участнику проголосовать несколько раз; повторный голос обновляет значение. +Старая таблица голосов `yes/no` из версии одиночного переноса. Новые голосования используют `reschedule_option_votes`. ## Модель статусов diff --git a/%D0%91%D1%8B%D1%81%D1%82%D1%80%D1%8B%D0%B9-%D1%81%D1%82%D0%B0%D1%80%D1%82.md b/%D0%91%D1%8B%D1%81%D1%82%D1%80%D1%8B%D0%B9-%D1%81%D1%82%D0%B0%D1%80%D1%82.md index c926ee9..7a0ef09 100644 --- a/%D0%91%D1%8B%D1%81%D1%82%D1%80%D1%8B%D0%B9-%D1%81%D1%82%D0%B0%D1%80%D1%82.md +++ b/%D0%91%D1%8B%D1%81%D1%82%D1%80%D1%8B%D0%B9-%D1%81%D1%82%D0%B0%D1%80%D1%82.md @@ -1,6 +1,6 @@ # Быстрый старт -Эта страница описывает минимальный запуск текущей версии GM-Relay **v1.6.0**. +Эта страница описывает минимальный запуск текущей версии GM-Relay **v1.7.0**. ## Требования @@ -41,8 +41,8 @@ docker compose up -d Compose поднимает: - `db`: PostgreSQL 17 Alpine, БД `gmrelay_db`, пользователь `gmrelay`. -- `bot`: образ `git.codeanddice.ru/toutsu/gmrelay-bot:1.6.0`. -- `web`: образ `git.codeanddice.ru/toutsu/gmrelay-web:1.6.0`. +- `bot`: образ `git.codeanddice.ru/toutsu/gmrelay-bot:1.7.0`. +- `web`: образ `git.codeanddice.ru/toutsu/gmrelay-web:1.7.0`. Web UI будет доступен на `http://localhost:8080`, если `GMRELAY_WEB_PORT` не переопределён. @@ -72,6 +72,7 @@ dotnet run --project src/GmRelay.AppHost - `/start` должен ответить `GM-Relay Bot ready. Use /help for commands.` - `/help` должен показать формат `/newsession`, включая необязательную строку `Мест:`. - В сообщении расписания у активной сессии должны быть кнопки записи и `Выйти`. +- Owner/co-GM может нажать `⏰ Перенести`, отправить 2-3 варианта времени и дедлайн; бот создаст голосование и применит победивший вариант по дедлайну. - Web-панель должна перенаправлять неавторизованного пользователя на `/login`. - После входа через Telegram пользователь видит группы, где он назначен owner или co-GM. - На странице группы owner видит блок управления co-GM, а owner/co-GM видят batch-операции: общий title/link, режим уведомлений, перенос всей пачки и клонирование batch. diff --git a/%D0%A0%D0%B0%D0%B7%D0%B2%D1%91%D1%80%D1%82%D1%8B%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5.md b/%D0%A0%D0%B0%D0%B7%D0%B2%D1%91%D1%80%D1%82%D1%8B%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5.md index 5313c90..3b37ecd 100644 --- a/%D0%A0%D0%B0%D0%B7%D0%B2%D1%91%D1%80%D1%82%D1%8B%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5.md +++ b/%D0%A0%D0%B0%D0%B7%D0%B2%D1%91%D1%80%D1%82%D1%8B%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5.md @@ -1,6 +1,6 @@ # Развёртывание -Текущий production-like способ запуска GM-Relay **v1.6.0** — Docker Compose из `compose.yaml`. +Текущий production-like способ запуска GM-Relay **v1.7.0** — Docker Compose из `compose.yaml`. ## Сервисы Docker Compose @@ -15,13 +15,13 @@ `bot`: -- образ: `git.codeanddice.ru/toutsu/gmrelay-bot:1.6.0`; +- образ: `git.codeanddice.ru/toutsu/gmrelay-bot:1.7.0`; - запускается после успешного healthcheck сервиса `db`; - переменные окружения: `ConnectionStrings__gmrelaydb`, `Telegram__BotToken`. `web`: -- образ: `git.codeanddice.ru/toutsu/gmrelay-web:1.6.0`; +- образ: `git.codeanddice.ru/toutsu/gmrelay-web:1.7.0`; - запускается после успешного healthcheck сервиса `db`; - переменные окружения: `ConnectionStrings__gmrelaydb`, `Telegram__BotToken`, `Telegram__BotUsername`; - порт: `${GMRELAY_WEB_PORT:-8080}:8080`; @@ -92,7 +92,7 @@ docker compose down -v ## Поведение миграций -Бот применяет DbUp-миграции при старте до обработки Telegram updates. В версии `1.6.0` добавлена миграция `V008__add_group_managers.sql`: она создаёт `group_managers` и переносит текущих GM в роль `Owner`. После обновления стоит проверить логи `bot`, чтобы убедиться, что миграции применились без ошибок. +Бот применяет DbUp-миграции при старте до обработки Telegram updates. В версии `1.7.0` добавлена миграция `V009__add_multi_option_reschedule_votes.sql`: она создаёт таблицы вариантов и голосов для переноса сессии, а также дедлайн и выбранный вариант в `reschedule_proposals`. После обновления стоит проверить логи `bot`, чтобы убедиться, что миграции применились без ошибок. ## Безопасность diff --git a/%D0%A0%D0%B0%D0%B7%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B0.md b/%D0%A0%D0%B0%D0%B7%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B0.md index 6f44086..dd6bf2d 100644 --- a/%D0%A0%D0%B0%D0%B7%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B0.md +++ b/%D0%A0%D0%B0%D0%B7%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B0.md @@ -26,7 +26,7 @@ dotnet run --project src/GmRelay.AppHost `Directory.Build.props` задаёт: -- `Version`: `1.6.0`. +- `Version`: `1.7.0`. - `TargetFramework`: `net10.0`. - `LangVersion`: `preview`. - `Nullable`: `enable`. @@ -72,7 +72,7 @@ V006__add_example_column.sql - domain/status helpers; - parser `/newsession`; - RSVP flow rules; -- reschedule time input и vote rules; +- reschedule voting input, multi-option vote rendering и deadline winner rules; - rendering batch-сообщений; - Telegram polling service behavior; - secret redaction; diff --git a/%D0%A0%D1%83%D0%BA%D0%BE%D0%B2%D0%BE%D0%B4%D1%81%D1%82%D0%B2%D0%BE-%D0%93%D0%9C%D0%B0.md b/%D0%A0%D1%83%D0%BA%D0%BE%D0%B2%D0%BE%D0%B4%D1%81%D1%82%D0%B2%D0%BE-%D0%93%D0%9C%D0%B0.md index f314f95..d10068e 100644 --- a/%D0%A0%D1%83%D0%BA%D0%BE%D0%B2%D0%BE%D0%B4%D1%81%D1%82%D0%B2%D0%BE-%D0%93%D0%9C%D0%B0.md +++ b/%D0%A0%D1%83%D0%BA%D0%BE%D0%B2%D0%BE%D0%B4%D1%81%D1%82%D0%B2%D0%BE-%D0%93%D0%9C%D0%B0.md @@ -1,6 +1,6 @@ # Руководство ГМа -Руководство описывает пользовательские сценарии бота и Web-панели для GM-Relay **v1.6.0**. +Руководство описывает пользовательские сценарии бота и Web-панели для GM-Relay **v1.7.0**. ## Кто управляет группой @@ -95,11 +95,20 @@ Owner или co-GM может поднять первого игрока из о 1. Бот проверяет, что кнопку нажал owner или co-GM. 2. Создаётся `reschedule_proposals` со статусом `AwaitingTime`. -3. Инициатор переноса пишет новое время обычным сообщением в чат. -4. Если активных участников нет, бот переносит сессию сразу. -5. Если активные участники есть, бот создаёт голосование. -6. Любой голос `Против` отклоняет перенос. -7. Если все активные участники согласились, бот переносит сессию, сбрасывает RSVP активных участников в `Pending`, очищает `confirmation_message_id` и `link_message_id`. +3. Инициатор переноса пишет 2-3 варианта нового времени и дедлайн обычным сообщением в чат. +4. Если активных участников нет, бот переносит сессию сразу на первый предложенный вариант. +5. Если активные участники есть, бот создаёт голосование с кнопкой для каждого варианта. +6. Участники видят текущие результаты в Telegram-сообщении и могут менять голос до дедлайна. +7. По дедлайну побеждает вариант с наибольшим числом голосов. Если голосов нет или есть ничья, перенос отклоняется. +8. При успешном переносе бот сбрасывает RSVP активных участников в `Pending`, очищает `confirmation_message_id` и `link_message_id`, обновляет batch-сообщение и отправляет результат в ЛС при включённом DM-режиме. + +Формат ввода: + +```text +25.04.2026 19:30 +26.04.2026 18:00 +Дедлайн: 25.04.2026 12:00 +``` ## RSVP и ссылка на игру diff --git a/Home.md b/Home.md index c762de1..0553a9a 100644 --- a/Home.md +++ b/Home.md @@ -1,10 +1,10 @@ # Главная -GM-Relay — Telegram-бот и Blazor-панель для организации TTRPG-сессий. Текущее состояние документации соответствует репозиторию `Toutsu/GmRelayBot` и релизу **v1.6.0**. +GM-Relay — Telegram-бот и Blazor-панель для организации TTRPG-сессий. Текущее состояние документации соответствует репозиторию `Toutsu/GmRelayBot` и релизу **v1.7.0**. ## Текущий стек -- Версия проекта: `1.6.0`. +- Версия проекта: `1.7.0`. - Платформа: `.NET 10`, C# preview, nullable reference types, warnings as errors. - Оркестрация разработки: `.NET Aspire 13` через `src/GmRelay.AppHost`. - Runtime бота: `Worker Service`, Telegram long polling, Native AOT. @@ -25,7 +25,7 @@ GM-Relay — Telegram-бот и Blazor-панель для организаци - Автоматическое создание Telegram forum topic для пачки игр, если группа является форумом. - Отмена отдельной сессии owner/co-GM из основного сообщения расписания. - Управление сессиями через `/listsessions` с отображением мест и очереди ожидания. -- Перенос сессии через кнопку owner/co-GM и голосование активных участников. +- Перенос сессии через кнопку owner/co-GM: GM предлагает 2-3 времени и дедлайн, участники голосуют за варианты, бот показывает текущие результаты и применяет победителя по дедлайну. - RSVP-подтверждение за 24 часа до игры только для основного состава. - Персональные DM-уведомления игрокам о RSVP за 24 часа, напоминание за 1 час, ссылке перед стартом, отмене и переносе. - Отправка ссылки на подключение за 5 минут до подтверждённой игры.