b81d865832
Add Discord adapter for the platform-neutral wizard moved to Shared in the previous commit. Six new files in src/GmRelay.DiscordBot/Features/ Sessions/Wizard/: - DiscordWizardContextStore: IWizardContextStore abstraction + thread-safe in-memory impl keyed by draft id. Holds the (guild, channel, message) coordinates the messenger needs to re-send the draft after a 15-minute interaction token expires. - DiscordWizardStep: renderer for all 15 wizard steps. Returns an embed plus an IReadOnlyList<IMessageComponentProperties> that mixes ActionRow buttons with StringMenu select menus. Also exposes BuildModal for the 8 modal-collecting steps. - DiscordWizardMessenger: IWizardMessenger impl backed by NetCord's RestClient + NpgsqlDataSource. Edit falls back to re-send on 401/403/404. Toast replies are stashed in the existing DiscordInteractionReplyCache. - DiscordWizardSubmitter: 3-retry finalize loop. Builds the shared CreateSessionCommand and calls CreateSessionHandler; on success edits the message to "ok Created: N sessions", on failure shows retry/cancel buttons. - DiscordWizardCommand: /newsession-wizard slash command with an optional mode param (single|pool). Owner/co-GM check via the shared group_managers table. - DiscordPermissionLookup: small helper that loads DB manager ids for a guild. Program.cs gets 5 new singleton registrations (IWizardDraftRepository, IWizardContextStore, IWizardMessenger, GameCreationWizard, DiscordWizardSubmitter). The slash command is auto-discovered by AddApplicationCommands<SlashCommandInteraction, SlashCommandContext>() + AddModules(typeof(Program).Assembly). Build green. All 85 wizard tests + 95 Discord tests pass. dotnet format clean. Open: DiscordWizardInteractionModule (button/modal handlers) is not yet implemented; the bot starts and /newsession-wizard works to the point of posting the first embed, but subsequent button clicks won't be handled. A follow-up commit will add the component-interaction module.