Delete page "%D0%91%D0%B0%D0%B7%D0%B0-%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85"
@@ -1,184 +0,0 @@
|
||||
# База данных
|
||||
|
||||
GM-Relay **v1.9.9** использует PostgreSQL. Изменения схемы управляются DbUp-миграциями, встроенными в `GmRelay.Bot` как embedded resources.
|
||||
|
||||
## Миграции
|
||||
|
||||
Текущие миграции:
|
||||
|
||||
- `V001__initial_schema.sql` — базовые таблицы игроков, групп, сессий и участников.
|
||||
- `V002__add_session_batch.sql` — поле `sessions.batch_id` для пачек сессий.
|
||||
- `V003__add_thread_id.sql` — поле `sessions.thread_id` для Telegram forum topics.
|
||||
- `V004__add_reschedule_proposals.sql` — таблицы предложений переноса и голосов.
|
||||
- `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.
|
||||
- `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` для голосования по нескольким слотам.
|
||||
- `V010__add_campaign_templates.sql` — таблица `campaign_templates` для сохранённых шаблонов кампаний и быстрого создания повторяющихся batch-расписаний из Web.
|
||||
|
||||
Версия `1.9.9` не добавляет новую миграцию: релиз добавляет функциональный smoke-тест Telegram-сценария и использует существующие `batch_message_id`, `sessions`, `group_managers` и `session_participants` без изменения схемы БД.
|
||||
|
||||
## Основные таблицы
|
||||
|
||||
### players
|
||||
|
||||
Известные Telegram-пользователи, которые взаимодействовали с ботом.
|
||||
|
||||
Важные поля:
|
||||
|
||||
- `telegram_id` — уникальный Telegram ID пользователя.
|
||||
- `display_name` — актуальное отображаемое имя из Telegram.
|
||||
- `telegram_username` — username пользователя, если он есть.
|
||||
|
||||
### game_groups
|
||||
|
||||
Telegram-группы, где организуются игры.
|
||||
|
||||
Важные поля:
|
||||
|
||||
- `telegram_chat_id` — уникальный Telegram chat ID.
|
||||
- `name` — актуальное название Telegram-чата.
|
||||
- `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
|
||||
|
||||
Таблица связи группы и игроков. Она остаётся базовой схемой для группового membership; права управления вынесены в `group_managers`.
|
||||
|
||||
### sessions
|
||||
|
||||
Отдельные игровые сессии.
|
||||
|
||||
Важные поля:
|
||||
|
||||
- `batch_id` — объединяет несколько сессий, созданных одной командой `/newsession`.
|
||||
- `group_id` — Telegram-группа, которой принадлежит сессия.
|
||||
- `title` — название игры.
|
||||
- `join_link` — ссылка для подключения.
|
||||
- `scheduled_at` — дата и время в UTC.
|
||||
- `status` — `Planned`, `ConfirmationSent`, `Confirmed` или `Cancelled`.
|
||||
- `max_players` — необязательный лимит основного состава; `NULL` означает запись без лимита.
|
||||
- `confirmation_message_id` — ID Telegram-сообщения RSVP-подтверждения.
|
||||
- `link_message_id` — ID Telegram-сообщения со ссылкой перед игрой.
|
||||
- `thread_id` — ID Telegram forum topic, если тема была создана.
|
||||
- `batch_message_id` — ID исходного Telegram-сообщения с расписанием пачки.
|
||||
- `notification_mode` — `GroupAndDirect` для групповых сообщений с DM-дублированием или `GroupOnly` только для группы.
|
||||
- `one_hour_reminder_processed_at` — когда бот обработал персональное напоминание примерно за 1 час до игры.
|
||||
|
||||
Bulk-операции Web не требуют новых таблиц: общий title/link обновляется по `batch_id`, перенос пересчитывает `scheduled_at` существующих строк, а clone создаёт новый `batch_id` и новые строки `sessions` без копирования `session_participants`.
|
||||
|
||||
Для активных статусов есть partial index `ix_sessions_pending` по `scheduled_at`.
|
||||
Для T-1h напоминаний есть partial index `ix_sessions_one_hour_reminders` по `scheduled_at`.
|
||||
|
||||
### campaign_templates
|
||||
|
||||
Сохранённые шаблоны кампаний для Web Dashboard. Шаблон принадлежит группе и описывает параметры будущей пачки игр, но не создаёт `sessions`, пока GM не выберет первую дату.
|
||||
|
||||
Важные поля:
|
||||
|
||||
- `group_id` — группа, которой доступен шаблон.
|
||||
- `name` — человекочитаемое название шаблона; уникально внутри группы.
|
||||
- `title` и `join_link` — общие значения для создаваемого batch.
|
||||
- `session_count` — количество игр в повторяющемся расписании, от 1 до 52.
|
||||
- `interval_days` — фиксированный шаг между играми, от 1 до 365 дней.
|
||||
- `max_players` — необязательный лимит мест для каждой создаваемой сессии.
|
||||
- `notification_mode` — режим уведомлений, который будет записан в новые `sessions`.
|
||||
|
||||
При создании batch из шаблона Web генерирует новый `batch_id`, создаёт строки `sessions` со статусом `Planned`, публикует новое Telegram-сообщение расписания и сохраняет его `batch_message_id`.
|
||||
|
||||
### session_participants
|
||||
|
||||
Участники сессий, их RSVP-состояние и положение в основном составе или очереди.
|
||||
|
||||
Важные поля:
|
||||
|
||||
- `session_id` и `player_id` — уникальная пара сессии и игрока.
|
||||
- `is_gm` — признак, что участник является GM.
|
||||
- `registration_status` — `Active` для основного состава или `Waitlisted` для листа ожидания.
|
||||
- `rsvp_status` — `Pending`, `Confirmed` или `Declined`.
|
||||
- `responded_at` — время RSVP-ответа.
|
||||
- `created_at` — время записи; используется для порядка листа ожидания.
|
||||
|
||||
Индексы:
|
||||
|
||||
- `ix_session_participants_session_registration_status` ускоряет подсчёт основного состава и waitlist.
|
||||
- `ix_session_participants_waitlist_order` ускоряет выбор первого игрока из очереди.
|
||||
|
||||
## Таблицы переноса сессий
|
||||
|
||||
### reschedule_proposals
|
||||
|
||||
Активные предложения переноса.
|
||||
|
||||
Статусы:
|
||||
|
||||
- `AwaitingTime` — GM нажал перенос, бот ждёт новое время.
|
||||
- `Voting` — идёт голосование активных участников.
|
||||
- `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
|
||||
|
||||
Старая таблица голосов `yes/no` из версии одиночного переноса. Новые голосования используют `reschedule_option_votes`.
|
||||
|
||||
## Модель статусов
|
||||
|
||||
Статусы сессии:
|
||||
|
||||
```text
|
||||
Planned -> ConfirmationSent -> Confirmed
|
||||
Planned -> Cancelled
|
||||
ConfirmationSent -> Cancelled
|
||||
Confirmed -> ConfirmationSent, если активный участник отказался после подтверждения
|
||||
```
|
||||
|
||||
Статусы участия в составе:
|
||||
|
||||
```text
|
||||
Active
|
||||
Waitlisted -> Active, когда GM повышает игрока из листа ожидания
|
||||
Active -> удаление строки, когда игрок самостоятельно снимает запись
|
||||
Waitlisted -> удаление строки, когда игрок выходит из листа ожидания
|
||||
```
|
||||
|
||||
RSVP-статусы:
|
||||
|
||||
```text
|
||||
Pending -> Confirmed
|
||||
Pending -> Declined
|
||||
Confirmed -> Declined
|
||||
Declined -> Confirmed
|
||||
```
|
||||
|
||||
## Работа со временем
|
||||
|
||||
Пользовательский ввод и вывод работают в московском времени `UTC+3`. В базе `scheduled_at` хранится в UTC. `MoscowTime.TryParseMoscow` преобразует поддерживаемые локальные форматы в UTC перед сохранением.
|
||||
Reference in New Issue
Block a user