diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index b8e43c9..c9db68f 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -6,7 +6,7 @@ on: - main env: - VERSION: 3.8.0 + VERSION: 3.9.0 jobs: # ЧАСТЬ 1: Собираем образы и кладем в Gitea (чтобы делиться с ребятами) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index fd6d309..ec59637 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,8 +1,47 @@ -## 🛠 Patch 2.4.0 — Discord /newsession и /listsessions +## 🎯 Minor 3.9.0 — Discord-визард создания игры/пула (issue #112) + +Пошаговый сценарий создания одиночной игры или пула игр в Discord-чате, по аналогии с Telegram-визардом из 3.8.0. Платформо-нейтральная стейт-машина `GameCreationWizard` и контракт `IWizardMessenger` перенесены в `GmRelay.Shared`, чтобы обе платформы (Telegram/Discord) использовали один и тот же движок визарда. + +### 🧩 Что вошло в релиз + +**Платформо-нейтральный рефакторинг (GmRelay.Shared)** +- `Features/Sessions/CreateSession/Wizard/GameCreationWizard.cs` — стейт-машина визарда (один источник правды для обеих платформ) +- `Features/Sessions/CreateSession/Wizard/IWizardMessenger.cs` — контракт мессенджера (edit/send/answer/getOwnerClubs) +- `Features/Sessions/CreateSession/Wizard/WizardInteraction.cs` — запись взаимодействия (OwnerId, Text, CallbackPayload, PhotoFileId, PhotoUrl, InteractionId) +- `Features/Sessions/CreateSession/Wizard/WizardAction.cs`, `WizardKeyboard.cs`, `WizardStepLimits.cs` — модель кнопок и лимитов +- `Features/Sessions/CreateSession/Wizard/WizardDraft.cs` — добавлено поле `Platform` +- `Migrations/V032__add_wizard_drafts_platform.sql` — `ALTER TABLE wizard_drafts ADD COLUMN platform TEXT NOT NULL DEFAULT 'Telegram'` + +**Discord-адаптер (GmRelay.DiscordBot)** +- `Features/Sessions/Wizard/DiscordWizardCommand.cs` — slash-команда `/newsession-wizard` с проверкой owner/co-GM через `DiscordPermissionLookup` +- `Features/Sessions/Wizard/DiscordWizardStep.cs` — рендер 15 шагов в NetCord embed + buttons/StringSelectMenu/modals +- `Features/Sessions/Wizard/DiscordWizardMessenger.cs` — реализация `IWizardMessenger` через NetCord REST (edit с fallback на re-send при 401/403/404) +- `Features/Sessions/Wizard/DiscordWizardSubmitter.cs` — финализация с 3-retry циклом +- `Features/Sessions/Wizard/DiscordWizardContextStore.cs` — in-memory кэш контекста (guild/channel/messageId) для 15-минутного interaction token +- `Features/Sessions/Wizard/DiscordWizardInteractionModule.cs` — inbound handlers: 3 NetCord `ComponentInteractionModule` (button/StringMenu/Modal) + `WizardInteractionDispatcher` +- `Features/Sessions/Wizard/DiscordPermissionLookup.cs` — DB-хелпер для `group_managers` +- `Program.cs` — DI-регистрации + 3 `AddComponentInteractions` + +**Тесты** +- `tests/GmRelay.Bot.Tests/Features/Sessions/CreateSession/Wizard/*` — обновлены под новый контракт +- `tests/GmRelay.Bot.Tests/Discord/DiscordWizardInteractionModuleSourceTests.cs` — 12 source-level smoke-тестов на структуру interaction module + +### 🗺 Что это даёт +- Мастера (GM) могут пошагово создавать игры и пулы слотов прямо в Discord через slash-команду, кнопки, выпадающие меню и модальные окна. +- UX адаптирован под Discord (нативные components), а не скопирован из Telegram. +- Общая стейт-машина и валидация: Telegram и Discord визарды развиваются синхронно, баги фиксятся в одном месте. +- PickClub-шаг использует реальный SQL-запрос к `club_memberships` с фильтром по роли Owner/CoGm. + +### 📦 Версия и деплой +- Версия обновлена до 3.9.0 (`NavMenu.razor`, `.gitea/workflows/deploy.yml`) +- Docker-образы будут тегированы `3.9.0` при пуше в `main` +- Миграция V032 применяется автоматически на старте Bot + +## 🛠 Patch 2.4.0 — Discord /newsession и /listsessions Реализованы slash-команды Discord для создания сессий и просмотра расписания без Web Dashboard. -## 🧩 Что вошло в релиз +### 🧩 Что вошло в релиз - src/GmRelay.DiscordBot/Features/Sessions/DiscordNewSessionCommand.cs — slash-команда /newsession с параметрами (title, time, seats, link) - src/GmRelay.DiscordBot/Features/Sessions/DiscordNewSessionHandler.cs — handler создания batch + session в БД - src/GmRelay.DiscordBot/Features/Sessions/DiscordListSessionsCommand.cs — slash-команда /listsessions @@ -13,11 +52,11 @@ - ests/GmRelay.Bot.Tests/Discord/ — 20+ TDD-тестов на парсинг, права, структуру, DI, рендеринг - Синхронизированы версии: Directory.Build.props, NavMenu.razor, compose.yaml, deploy.yml → 2.4.0 -## 🗺 Что это даёт +### 🗺 Что это даёт - Мастера (GM) могут создавать сессии прямо из Discord, не заходя в Web. - Участники сервера видят расписание через /listsessions. - Единая PostgreSQL модель для Telegram и Discord — никакого дублирования данных. -## 📦 Версия и деплой +### 📦 Версия и деплой - версия обновлена до 2.4.0 -- Docker-образы используют тег 2.4.0 \ No newline at end of file +- Docker-образы используют тег 2.4.0 diff --git a/docs/review-brief.md b/docs/review-brief.md new file mode 100644 index 0000000..042bdce --- /dev/null +++ b/docs/review-brief.md @@ -0,0 +1,54 @@ +"""Detailed code review plan for the Discord wizard feature branch. + +Read this file FIRST. It has the full review scope. The original prompt +in the spawn was truncated due to Windows CLI limits; this file is the +canonical spec. +""" + +# Branch to review +BRANCH = "feat/issue-112-wizard-refactor" +BASE = "origin/main" + +# Files of interest +SHARED = "src/GmRelay.Shared/Features/Sessions/CreateSession/Wizard/*" +BOT_WIZARD = "src/GmRelay.Bot/Features/Sessions/CreateSession/Wizard/*" +BOT_CREATE = "src/GmRelay.Bot/Features/Sessions/CreateSession/*" +MIGRATION = "src/GmRelay.Bot/Migrations/V032__add_wizard_drafts_platform.sql" +DISCORD = "src/GmRelay.DiscordBot/Features/Sessions/Wizard/*" +PROG_CS = "src/GmRelay.DiscordBot/Program.cs" +TESTS_WIZ = "tests/GmRelay.Bot.Tests/Features/Sessions/CreateSession/Wizard/*" +TESTS_SMOKE = "tests/GmRelay.Bot.Tests/Discord/DiscordWizardInteractionModuleSourceTests.cs" +DELIVERABLE = "deliverable.md" + +REVIEW_FOCUS = [ + "Architecture: Shared/Bot/DiscordBot separation; no Telegram.Bot in Shared; no NetCord in Shared; single state machine source.", + "Security: owner/co-GM checks everywhere; NRE on null Context.User; SQL injection; connection strings with passwords.", + "Correctness: AOT-safety (no reflection, no dynamic); off-by-one in customId parsers; CancellationToken/Services.", + "Style: naming consistent; Async/await by convention; logging at right levels.", + "Tests: smoke tests are string-matching — where would real tests be useful?", + "Migration safety: V032 DEFAULT value, will it fail on existing rows?", + "Documentation: deliverable.md updated, open questions listed?", +] + +OUTPUT_FORMAT = """\ +## VERDICT: APPROVE / REQUEST_CHANGES / COMMENT + +## Critical findings +(file:line — what's wrong — how to fix) + +## Important findings +(file:line — what's wrong) + +## Nits +(quick observations) + +## Summary +(1-2 sentences) +""" + +COMMANDS_HINT = """\ +git fetch origin +git diff origin/main..feat/issue-112-wizard-refactor --stat +git diff origin/main..feat/issue-112-wizard-refactor +dotnet build && dotnet test +""" diff --git a/src/GmRelay.Web/Components/Layout/NavMenu.razor b/src/GmRelay.Web/Components/Layout/NavMenu.razor index 4ec7bd2..10142ed 100644 --- a/src/GmRelay.Web/Components/Layout/NavMenu.razor +++ b/src/GmRelay.Web/Components/Layout/NavMenu.razor @@ -82,7 +82,7 @@ - + diff --git a/tests/GmRelay.Bot.Tests/Web/CampaignTemplatesNavigationTests.cs b/tests/GmRelay.Bot.Tests/Web/CampaignTemplatesNavigationTests.cs index cb97c5f..783012f 100644 --- a/tests/GmRelay.Bot.Tests/Web/CampaignTemplatesNavigationTests.cs +++ b/tests/GmRelay.Bot.Tests/Web/CampaignTemplatesNavigationTests.cs @@ -15,7 +15,7 @@ public sealed class CampaignTemplatesNavigationTests public async Task NavMenu_ShouldExposeCurrentProjectVersion() { var navMenu = await File.ReadAllTextAsync(FindRepositoryFile("src/GmRelay.Web/Components/Layout/NavMenu.razor")); - Assert.Contains("v3.7.1", navMenu, StringComparison.Ordinal); + Assert.Contains("v3.9.0", navMenu, StringComparison.Ordinal); } [Fact]