8
База данных
Toutsu edited this page 2026-04-27 14:58:56 +03:00
This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

База данных

GM-Relay v1.7.0 использует 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 для голосования по нескольким слотам.

Основные таблицы

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 — уникальная пара группы и пользователя.
  • roleOwner или 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.
  • statusPlanned, 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_modeGroupAndDirect для групповых сообщений с 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.

session_participants

Участники сессий, их RSVP-состояние и положение в основном составе или очереди.

Важные поля:

  • session_id и player_id — уникальная пара сессии и игрока.
  • is_gm — признак, что участник является GM.
  • registration_statusActive для основного состава или Waitlisted для листа ожидания.
  • rsvp_statusPending, 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.

Модель статусов

Статусы сессии:

Planned -> ConfirmationSent -> Confirmed
Planned -> Cancelled
ConfirmationSent -> Cancelled
Confirmed -> ConfirmationSent, если активный участник отказался после подтверждения

Статусы участия в составе:

Active
Waitlisted -> Active, когда GM повышает игрока из листа ожидания
Active -> удаление строки, когда игрок самостоятельно снимает запись
Waitlisted -> удаление строки, когда игрок выходит из листа ожидания

RSVP-статусы:

Pending -> Confirmed
Pending -> Declined
Confirmed -> Declined
Declined -> Confirmed

Работа со временем

Пользовательский ввод и вывод работают в московском времени UTC+3. В базе scheduled_at хранится в UTC. MoscowTime.TryParseMoscow преобразует поддерживаемые локальные форматы в UTC перед сохранением.