Issue #150 follow-up: clicking the session title only expands participants, so click the explicit 'Изменить' edit link. Cleanup now only deletes the player row when the test was the sole owner, avoiding accidental removal of the real Toutsu account from production.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Add DeleteSessionAsync to ISessionStore/SessionService (unpublish portfolio card,
remove bot-created empty forum topic, update batch message).
- Add DeleteSessionForCurrentUserAsync to AuthorizedSessionService with audit log.
- Add delete button + confirmation dialog to GroupDetails.razor.
- Extend dashboard Playwright tests with edit persistence and delete verification.
- Update AuthorizedSessionServiceTests with delete authorization coverage.
- Mark issue #150 as done in tests/e2e/README.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Add NewSessionScenario that walks the Telegram wizard:
single game, title, skip description/cover, D&D 5e, 4h, datetime,
capacity, online format, join link, public visibility, publish, confirm
- Add ClickInlineButtonAsync / ClickInlineButtonByTextAsync to TelegramUserClient
- Add local WizardCallback/Step constants mirroring GmRelay.Shared wizard wire format
- Program.cs now runs full flow: group setup + /newsession + cleanup
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Add GroupSetupScenario: create supergroup, invite GmRelay bot, send /start,
wait for reply, then delete the group
- Extend TelegramUserClient with DeleteGroupAsync and channel cache
- Update Program.cs to run the scenario with cleanup in finally
- Update README status table and runner documentation
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Add standalone C# console runner tests/e2e/runner/ using WTelegramClient
- Provide TelegramUserClient wrapper: login, create supergroup, invite bot,
send messages/commands, read recent messages, wait for bot reply
- Add .env.example and runner .gitignore to keep secrets/session files out of git
- Update E2E README with runner instructions and status table
- Runner project intentionally excluded from GM-Relay.slnx to avoid CI/AOT impact
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Add Playwright-based E2E tests in tests/e2e/dashboard/
- Authenticate via /auth/telegram-webapp using helpers/telegram_init_data.py
- Cover dashboard load and session edit flow
- Add requirements.txt and package dashboard folder
- Update README with setup and test descriptions
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Add TelegramAuthPayloadBuilder in GmRelay.Shared for C# tests.
- Refactor TelegramAuthServiceTests to use the shared builder.
- Add Python equivalent (telegram_init_data.py) for E2E runner.
- Add self-contained Python tests and E2E README.
Closes#144
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Remove legacy DiscordNewSessionCommand/Handler and their tests.
- Rename /newsession-wizard to /newsession.
- Add shared pool capacity step before Format/Location.
- Render Format and Location in Discord wizard; Location uses a modal.
- Propagate Format, JoinLink and LocationAddress in BuildCommand.
- Publish created sessions through existing IPlatformMessenger pipeline.
- Update README, version bump to 3.11.1, sync compose/deploy/NavMenu.
For non-managers /listsessions now shows player-friendly actions:
- ✅ Записаться <date> when not registered
- ✖️ Выйти <date> when already active
- ✖️ Выйти из ожидания <date> when waitlisted
Extend SessionListItemDto and the shared SQL query with IsUserActive
and IsUserWaitlisted flags so the renderer can choose the right button.
Update tests to cover all three player states.
Set /start, /newsession, /listsessions, /exportcalendar and /help
via setMyCommands for both private chats and group chats so users
see the command list when typing '/'.
Also update /help text to list all commands first and then show the
example.
The /listsessions buttons for owners/co-GMs only showed emoji + date,
so it was unclear what each button did. Add explicit verb labels:
- ❌ Отменить <date>
- ⏰ Перенести <date>
- ⬆️ С ожидания <date>
- 🗑 Удалить <date>
Update the renderer test to assert the new labels.
The /listsessions buttons for owners/co-GMs only showed emoji + date,
so it was unclear what each button did. Add explicit verb labels:
- ❌ Отменить <date>
- ⏰ Перенести <date>
- ⬆️ С ожидания <date>
- 🗑 Удалить <date>
Update the renderer test to assert the new labels.
The /listsessions buttons for owners/co-GMs only showed emoji + date,
so it was unclear what each button did. Add explicit verb labels:
- ❌ Отменить <date>
- ⏰ Перенести <date>
- ⬆️ С ожидания <date>
- 🗑 Удалить <date>
Update the renderer test to assert the new labels.
Slow ARM64 runners hit the default timeout while initializing the
container image scan after pulling. Extend the timeout so image scans
can complete reliably.
The scan-images job runs on a fresh runner that does not have the images
built by the build-and-push job. Login to the registry and pull the
images before scanning, otherwise Trivy cannot find them.
Merge pull request #139: feat(rendering): display description, system, duration, format, type and location in Telegram game card
Bump version to 3.11.0.
The ARM64 runner cannot reliably start PostgreSQL containers and apply
migrations within the test timeouts. Exclude the three Testcontainers
collections from pr-checks.yml while keeping all unit tests and SAST
builds. Integration tests remain runnable locally and via dotnet test.
Slow ARM64 runners hit the default timeout while downloading the Trivy
checks bundle and analyzing workflow YAML files. Extend the timeout so
PR checks can complete reliably.
Prevent offline sessions with empty join links from entering the 5-minute join-link notification flow, omit blank link lines from direct reminders, and add offline persistence/reminder regression coverage.
Add format and location steps to the Telegram /newsession wizard, persist offline addresses in sessions.location_address, and render online links/offline addresses in schedule messages.
Bump version to 3.10.0.
After the shared create handler persists sessions, create a Telegram topic when needed, send the schedule/signup message, and store thread_id/batch_message_id/topic_created_by_bot for the batch. Add a Testcontainers regression test for the wizard SubmitDraftAsync happy path. Bump version to 3.9.9.
Add a PostgreSQL integration regression test for new-platform-group session creation. The production failure was a missing Platform parameter in the group_managers insert, leaving @Platform in SQL and causing PostgreSQL 42883. Bump version to 3.9.8.
The previous comment claimed a 0 MaxPlayers would also be blocked, but
the code never actually enforced that. The wizard's text-input path
already guarantees cap >= MinCapacity, so 0 is unreachable. Drop the
inaccurate half-sentence to keep the comment faithful to the code.
After 3.9.6 fixed long-polling, the bot finally reaches the final
'✅ Создать' step. Users pressing '♾ Без лимита' on the Capacity step
get a valid payload where Single.MaxPlayers = null (the legitimate
no-limit choice from GameCreationWizard.ApplyCapacityChoice 'no_limit'),
but CreateSessionHandler.IsComplete then reports 'лимит мест' as
missing, blocking session creation.
This regression existed since 3.9.3 (when 'no_limit' was added) but
stayed invisible because 3.9.4 and 3.9.5 never reached SubmitDraft
(libgssapi-krb5 missing → long-polling hung). Once 3.9.6 restored
polling, the bug surfaced immediately.
Fix: drop the null-MaxPlayers check from IsComplete for Single type.
Null is a valid 'no limit' state and must pass through to BuildCommands
→ shared handler, which already accepts null MaxPlayers correctly.
Closes#131.
Bump version 3.9.6 -> 3.9.7
Telegram bot's long-polling hangs after the first GetUpdates request
because libgssapi-krb5.so.2 is missing from the runtime-deps:10.0-noble
final image. .NET runtime attempts dlopen() of libgssapi during the
HTTPS handshake; without the library the HttpClient connection pool
enters an unrecoverable state and TelegramBotService never receives
new updates, even though SessionSchedulerService keeps sending
outgoing messages successfully.
Symptom (Loki, container gmrelaybot-bot-1):
Telegram bot polling started
Polling error, retrying in 5s
Telegram.Bot.Exceptions.RequestException: Bot API Service Failure
Cannot load library libgssapi_krb5.so.2
After the single Polling error, no Error handling update, no further
Polling error, and getUpdates from outside returns [] forever.
Fix: install libgssapi-krb5-2 alongside wget in the final stage of
src/GmRelay.Bot/Dockerfile. This also future-proofs Npgsql GSS/SSPI
Kerberos authentication for PostgreSQL.
Closes#129.
Bump version 3.9.5 -> 3.9.6
Fix two wizard FSM bugs reported after v3.9.4:
1. Capacity waitlist buttons could still advance the draft without a
numeric MaxPlayers value. The final submit validation then rejected
the draft with 'Не заполнены поля: лимит мест'. Now waitlist:on/off
stay on Capacity until MaxPlayers is set; users must either enter a
numeric limit or explicitly choose '♾ Без лимита'.
2. PickClub computed NextAfterVisibility before SetClubId, so the first
club click left the wizard on PickClub and the second click advanced.
Now ClubId is saved first and NextAfterVisibility is evaluated after
that mutation, so a valid club click advances on the first try.
TDD:
- WaitlistChoiceWithoutCapacity_StaysOnCapacityStep covers waitlist:on/off.
- PickClub_ValidGuid_AdvancesToPublishOnFirstClick covers the single-click club path.
- Stale Capacity waitlist callback test updated to the safer no-advance contract.
Closes#127
Test-only patch release. Sync the four canonical version sources:
- Directory.Build.props
- compose.yaml (bot, discord, web image tags)
- .gitea/workflows/deploy.yml (VERSION env)
- src/GmRelay.Web/Components/Layout/NavMenu.razor (visible nav-version)
The new NavMenu_ShouldExposeCurrentProjectVersion test reads the
version from Directory.Build.props, so this bump does NOT need a
hand-edited test literal — verified locally that the test passes
on 3.9.4 with no manual changes.
Two non-blocking suggestions from the PR #124 code review:
1. Symmetric coverage for the Discord PoolSlotCapacity no-limit button.
The Capacity step already had a customId-shape assertion for the
'♾ Без лимита' button; PoolSlotCapacity only had a label-presence
assertion. If ChoiceButtonCustomId's wire format ever diverged between
the two steps, only Capacity would catch it. Convert the single Fact
to a Theory with two InlineData rows so a regression in either step
produces a targeted test failure.
2. Brittle hard-coded version literal in NavMenu_ShouldExposeCurrent
ProjectVersion. The test had to be hand-edited on every version bump
(we hit this in PR #124 — bumping 3.9.2 -> 3.9.3 broke CI). Read the
version from Directory.Build.props via XDocument instead so the test
only fails when the rendered NavMenu actually disagrees with the
canonical version, not when someone forgot to update a literal.
Tolerant of whitespace, comments and attribute order; the <Version>
element is a plain string body in the MSBuild schema.
No production code changes; production version is bumped in a
follow-up commit.
Closes#125