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 a7a1ecb..3fe9667 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,16 +1,17 @@ # База данных -GM-Relay использует PostgreSQL. Изменения схемы управляются DbUp-миграциями, встроенными в `GmRelay.Bot`. +GM-Relay **v1.2.0** использует PostgreSQL. Изменения схемы управляются DbUp-миграциями, встроенными в `GmRelay.Bot` как embedded resources. ## Миграции Текущие миграции: -- `V001__initial_schema.sql` — базовые таблицы для игроков, групп, сессий и участников. +- `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. ## Основные таблицы @@ -21,7 +22,7 @@ GM-Relay использует PostgreSQL. Изменения схемы упра Важные поля: - `telegram_id` — уникальный Telegram ID пользователя. -- `display_name` — актуальное отображаемое имя, полученное из Telegram. +- `display_name` — актуальное отображаемое имя из Telegram. - `telegram_username` — username пользователя, если он есть. ### game_groups @@ -32,11 +33,11 @@ Telegram-группы, где организуются игры. - `telegram_chat_id` — уникальный Telegram chat ID. - `name` — актуальное название Telegram-чата. -- `gm_telegram_id` — Telegram ID ГМа для этой группы. +- `gm_telegram_id` — Telegram ID GM для этой группы. ### game_group_members -Таблица связи групп и игроков. Текущая функциональность в основном работает через участие в конкретных сессиях и `gm_telegram_id`; таблица остаётся частью базовой схемы для группового membership. +Таблица связи группы и игроков. Сейчас основная проверка роли GM идёт через `game_groups.gm_telegram_id`; таблица остаётся базовой схемой для группового membership. ### sessions @@ -47,11 +48,12 @@ Telegram-группы, где организуются игры. - `batch_id` — объединяет несколько сессий, созданных одной командой `/newsession`. - `group_id` — Telegram-группа, которой принадлежит сессия. - `title` — название игры. -- `join_link` — ссылка для подключения, отправляемая перед началом игры. +- `join_link` — ссылка для подключения. - `scheduled_at` — дата и время в UTC. - `status` — `Planned`, `ConfirmationSent`, `Confirmed` или `Cancelled`. -- `confirmation_message_id` — ID Telegram-сообщения с RSVP-подтверждением. -- `link_message_id` — ID Telegram-сообщения с pre-game ссылкой. +- `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-сообщения с расписанием пачки. @@ -59,43 +61,38 @@ Telegram-группы, где организуются игры. ### session_participants -Участники конкретных сессий и их RSVP-состояние. +Участники сессий, их RSVP-состояние и положение в основном составе или очереди. Важные поля: - `session_id` и `player_id` — уникальная пара сессии и игрока. -- `is_gm` — признак, что участник является ГМом. +- `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 -Отслеживает один активный сценарий переноса для сессии. +Активные предложения переноса. -Важные поля: +Статусы: -- `session_id` — целевая сессия. -- `proposed_at` — новое предложенное время в UTC; `NULL`, пока бот ждёт ввод времени от ГМа. -- `proposed_by` — Telegram ID ГМа. -- `status` — `AwaitingTime`, `Voting`, `Approved`, `Rejected`. -- `vote_message_id` и `vote_chat_id` — где находится Telegram-сообщение голосования. - -Partial unique index разрешает только одно активное предложение переноса на сессию, пока статус `AwaitingTime` или `Voting`. +- `AwaitingTime` — GM нажал перенос, бот ждёт новое время. +- `Voting` — идёт голосование активных участников. +- `Approved` — перенос принят. +- `Rejected` — перенос отклонён. ### reschedule_votes -Хранит голоса участников по предложению переноса. - -Важные поля: - -- `proposal_id` — предложение переноса. -- `player_id` — игрок, который голосует. -- `vote` — `yes` или `no`. -- `voted_at` — время голосования. - -У каждого участника один голос на предложение. Повторное голосование обновляет сохранённый голос. +Голоса активных участников по предложению переноса. Уникальная пара `proposal_id + player_id` не даёт одному участнику проголосовать несколько раз; повторный голос обновляет значение. ## Модель статусов @@ -105,15 +102,14 @@ Partial unique index разрешает только одно активное Planned -> ConfirmationSent -> Confirmed Planned -> Cancelled ConfirmationSent -> Cancelled -Confirmed -> ConfirmationSent, если подтвердивший участник позже отказался +Confirmed -> ConfirmationSent, если активный участник отказался после подтверждения ``` -Статусы переноса: +Статусы участия в составе: ```text -AwaitingTime -> Voting -> Approved -AwaitingTime -> Voting -> Rejected -AwaitingTime -> Approved, если участников нет +Active +Waitlisted -> Active, когда GM повышает игрока из листа ожидания ``` RSVP-статусы: @@ -127,6 +123,4 @@ Declined -> Confirmed ## Работа со временем -Пользовательский ввод и вывод работают в московском времени (`UTC+3`). `MoscowTime.TryParseMoscow` преобразует поддерживаемые локальные форматы в UTC перед сохранением в `scheduled_at`. - -Web-форма редактирования показывает московское время, а перед обновлением БД преобразует его обратно в UTC. \ No newline at end of file +Пользовательский ввод и вывод работают в московском времени `UTC+3`. В базе `scheduled_at` хранится в UTC. `MoscowTime.TryParseMoscow` преобразует поддерживаемые локальные форматы в UTC перед сохранением. \ No newline at end of file