chore: remove AI working directories (docs/superpowers, docs/plans) from repo
Add docs/superpowers/, docs/plans/, *.diff to .gitignore. These directories contain implementation plans and design specs used during agentic development; they are not needed in source control. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,44 +0,0 @@
|
||||
# Telegram Mini App Dashboard Design
|
||||
|
||||
## Goal
|
||||
|
||||
Issue #17 adds a Telegram Mini App dashboard as the mobile entry point for the existing Web Dashboard. Owner and co-GM users must be able to open the dashboard from Telegram, pass server-side Telegram WebApp `initData` validation, and manage only their own groups.
|
||||
|
||||
## Scope
|
||||
|
||||
- Add Mini App authentication using Telegram WebApp `initData`.
|
||||
- Add a `/miniapp` entry page that signs the user into the existing cookie auth flow, then opens the regular dashboard UI in mobile-first mode.
|
||||
- Reuse `AuthorizedSessionService`, `SessionService`, and existing Blazor pages for groups, sessions, templates, waitlist promotion, edit forms, and bulk batch operations.
|
||||
- Add bot entry points: a Mini App button in `/start` and a configurable default menu button when `Telegram:MiniAppUrl` is set.
|
||||
- Update README, wiki, deployment config, and visible version strings to `1.9.0`.
|
||||
|
||||
## Architecture
|
||||
|
||||
The Mini App is not a second dashboard implementation. It is a Telegram-authenticated entrance into the existing Blazor dashboard. This keeps authorization, domain operations, Telegram message synchronization, and Web Dashboard behavior in one place.
|
||||
|
||||
`TelegramAuthService` gains a second verification method for WebApp `initData`. The server accepts the raw URL-encoded init payload at `/auth/telegram-webapp`, verifies the Telegram HMAC with the bot token, extracts the user id/name from the embedded `user` JSON, and issues the same auth cookie as the login widget endpoint.
|
||||
|
||||
`/miniapp` loads `telegram-web-app.js`, posts `window.Telegram.WebApp.initData` to the server endpoint, expands the WebApp viewport, and redirects to `/`. If a user opens `/miniapp` outside Telegram, the page shows the regular login fallback.
|
||||
|
||||
## Data Flow
|
||||
|
||||
1. User opens the Mini App from the bot menu button or `/start` inline button.
|
||||
2. Telegram injects `initData` into the WebApp JavaScript API.
|
||||
3. `/miniapp` posts `{ initData }` to `/auth/telegram-webapp`.
|
||||
4. The server verifies the WebApp signature and expiry.
|
||||
5. The server creates the same claims used by Telegram Login Widget.
|
||||
6. Existing Blazor pages load groups through `AuthorizedSessionService`.
|
||||
7. Any edit, waitlist, template, or batch action still goes through existing services and keeps Telegram messages synchronized.
|
||||
|
||||
## Error Handling
|
||||
|
||||
- Missing or invalid init data returns `401` and leaves the user on the Mini App page.
|
||||
- Expired auth data is rejected with the same 24-hour window used by the Login Widget.
|
||||
- A verified Telegram user with no owner/co-GM groups sees the existing empty dashboard state.
|
||||
- Direct navigation to a foreign group/session still redirects to `/access-denied` through existing authorization checks.
|
||||
|
||||
## Testing
|
||||
|
||||
- Unit tests cover valid and invalid WebApp `initData`.
|
||||
- File-level regression tests ensure `/miniapp`, `/auth/telegram-webapp`, Telegram WebApp script loading, bot Mini App button, menu button setup, and mobile Mini App CSS hooks remain present.
|
||||
- Existing `AuthorizedSessionServiceTests` continue covering owner/co-GM access behavior.
|
||||
-140
@@ -1,140 +0,0 @@
|
||||
# Platform Messenger Scheduler Notifications Design
|
||||
|
||||
## Goal
|
||||
|
||||
Issue #31 moves scheduler-driven notifications and reschedule deadline message updates behind `IPlatformMessenger`, preserving Telegram behavior and adding full Discord support instead of no-op placeholders.
|
||||
|
||||
## Scope
|
||||
|
||||
- `SessionSchedulerService` remains the trigger orchestrator, but scheduler handlers stop depending on Telegram API types for outbound notification work.
|
||||
- Confirmation requests, one-hour reminders, join-link notifications, RSVP follow-up messages, and reschedule deadline updates use platform-neutral contracts.
|
||||
- Telegram keeps the current user-visible behavior: same message content, RSVP buttons, direct messages, topic/thread targeting, and stored legacy message ids.
|
||||
- Discord receives full channel and direct notifications:
|
||||
- confirmation requests are sent to the Discord channel with RSVP buttons;
|
||||
- Discord RSVP button clicks update participant RSVP state, refresh the confirmation message, and send the same group/GM outcome notifications where applicable;
|
||||
- one-hour reminders and join-link notifications are sent as Discord DMs when direct notifications are enabled;
|
||||
- join-link notifications also post the channel message with participant mentions;
|
||||
- reschedule deadline processing updates Discord vote and schedule messages through the same messenger boundary.
|
||||
- Discord DM failures are non-fatal: log a warning and continue without posting a public fallback message.
|
||||
|
||||
## Architecture
|
||||
|
||||
The platform boundary should be semantic, not Telegram-shaped. `GmRelay.Shared.Platform` already owns `PlatformKind`, `PlatformUser`, `PlatformGroup`, `PlatformMessageRef`, and `IPlatformMessenger`; issue #31 extends that layer with notification-specific DTOs and messenger methods.
|
||||
|
||||
The scheduler handlers own database queries and notification eligibility. They load platform-neutral groups, users, message refs, and session data, then ask the platform messenger to send or update the platform message. Platform implementations own rendering details: Telegram renders HTML and inline keyboards; Discord renders embeds, components, channel messages, mentions, and DMs.
|
||||
|
||||
RSVP handling should become platform-neutral enough for both Telegram and Discord. The current `HandleRsvpHandler` logic is not duplicated. Its command changes from Telegram ids to `PlatformUser`, `PlatformGroup`, `PlatformMessageRef`, and `InteractionId`. Telegram update routing maps callback queries into that command; Discord component routing maps RSVP button interactions into the same command.
|
||||
|
||||
Reschedule finalization already has shared database logic in `RescheduleVotingFinalizer`. The remaining platform-specific deadline services should stop editing messages through `ITelegramBotClient` or Discord `RestClient` directly. They should load message refs and call `IPlatformMessenger` to update vote messages, schedule messages, and direct result notifications.
|
||||
|
||||
## Platform Contracts
|
||||
|
||||
Add semantic notification records in `GmRelay.Shared.Platform`, with names finalized during implementation planning:
|
||||
|
||||
- `PlatformSessionParticipant`: a `PlatformUser` plus RSVP, registration, and display metadata needed by notification renderers.
|
||||
- `PlatformSessionNotification`: common session title, time, join link, notification mode, group, optional existing message, and participants.
|
||||
- `PlatformConfirmationRequest`: confirmation-specific session notification with RSVP actions.
|
||||
- `PlatformJoinLinkNotification`: join-link group/direct notification data.
|
||||
- `PlatformOneHourReminder`: one-hour direct reminder data.
|
||||
- `PlatformRsvpMessageUpdate`: refreshed confirmation message state after a participant responds.
|
||||
- `PlatformRescheduleVoteUpdate`: finalized reschedule vote message state, including selected option or rejection reason.
|
||||
|
||||
Extend `IPlatformMessenger` with methods for these semantic operations while keeping existing schedule, group, private, interaction, and calendar methods intact for current flows:
|
||||
|
||||
- send and update confirmation request messages;
|
||||
- send one-hour reminder direct notifications;
|
||||
- send join-link channel and direct notifications;
|
||||
- update finalized reschedule vote messages;
|
||||
- send RSVP outcome messages to the group and GM recipients.
|
||||
|
||||
The exact method names should be chosen in the implementation plan after tests define the desired API, but each method should accept platform-neutral DTOs and return `PlatformMessageRef` when the caller must persist a sent message id.
|
||||
|
||||
## Telegram Behavior
|
||||
|
||||
Telegram implementation lives in `GmRelay.Bot.Infrastructure.Telegram.TelegramPlatformMessenger`.
|
||||
|
||||
It must preserve:
|
||||
|
||||
- `messageThreadId` handling for forum topics;
|
||||
- HTML parse mode where the existing flow uses HTML;
|
||||
- current confirmation and RSVP button callback payloads;
|
||||
- `confirmation_message_id` and `link_message_id` storage in `sessions`;
|
||||
- direct notification behavior controlled by `SessionNotificationMode`;
|
||||
- warning-and-continue behavior for failed direct messages;
|
||||
- existing schedule rendering through `TelegramSessionBatchRenderer` and `BatchMessageEditor`.
|
||||
|
||||
Telegram-specific inbound parsing remains at the Telegram boundary. `UpdateRouter` can still use `Telegram.Bot.Types`, but the command it passes into the RSVP handler should be platform-neutral.
|
||||
|
||||
## Discord Behavior
|
||||
|
||||
Discord implementation lives in `GmRelay.DiscordBot.Infrastructure.Discord.DiscordPlatformMessenger`.
|
||||
|
||||
It must support:
|
||||
|
||||
- channel messages through the configured channel id in `PlatformGroup.ExternalChannelId`;
|
||||
- interactive RSVP buttons routed by `DiscordSessionInteractionModule`;
|
||||
- ephemeral interaction replies via the existing `DiscordInteractionReplyCache` pattern;
|
||||
- DMs through Discord user ids in `PlatformUser.ExternalUserId`;
|
||||
- non-fatal DM failures with warning logs;
|
||||
- Discord-friendly rendering, not raw Telegram HTML;
|
||||
- persistence of Discord schedule and notification message refs in `platform_messages` where later updates need them.
|
||||
|
||||
The current Discord reschedule deadline service directly uses `RestClient` for vote and schedule message edits. This should be folded into `DiscordPlatformMessenger` so deadline services and future platform handlers do not need to know Discord API details.
|
||||
|
||||
## Data Flow
|
||||
|
||||
1. `SessionSchedulerService.TickAsync` asks `ISessionTriggerStore` for due confirmation, one-hour reminder, and join-link session ids.
|
||||
2. Each handler loads the session, group platform identity, message refs, participants, RSVP state, and notification mode.
|
||||
3. The handler builds a semantic platform notification DTO and calls `IPlatformMessenger`.
|
||||
4. The messenger renders and sends/updates platform messages.
|
||||
5. The handler persists sent message ids where required, using legacy `sessions.confirmation_message_id` and `sessions.link_message_id` for Telegram and `platform_messages` for Discord refs that need later updates.
|
||||
6. Telegram callback queries and Discord component interactions both call the same platform-neutral RSVP handler.
|
||||
7. Reschedule deadline services use `RescheduleVotingFinalizer`, then call `IPlatformMessenger` for vote message updates, schedule updates, and direct result notifications.
|
||||
|
||||
## Error Handling
|
||||
|
||||
- A failed trigger query still logs and lets the scheduler continue to the next trigger category.
|
||||
- A failed send/update for one session logs and does not stop other sessions in the same tick.
|
||||
- DM failures are warning-level and non-fatal for Telegram and Discord.
|
||||
- A missing platform message ref logs a warning and skips only the update that needs the ref.
|
||||
- Unsupported platform values throw at the messenger boundary, not inside scheduler orchestration.
|
||||
- If Discord cannot parse a stored channel, message, or user id, it logs the bad external id and skips that platform send/update.
|
||||
|
||||
## Testing
|
||||
|
||||
Use TDD for implementation.
|
||||
|
||||
Focused tests should cover:
|
||||
|
||||
- `IPlatformMessenger` exposes semantic notification methods without referencing Telegram or Discord assemblies from `GmRelay.Shared`.
|
||||
- `SendConfirmationHandler`, `SendOneHourReminderHandler`, `SendJoinLinkHandler`, `HandleRsvpHandler`, and reschedule deadline services do not call `ITelegramBotClient`, `BatchMessageEditor`, or Discord `RestClient` directly for notification output.
|
||||
- Telegram source/regression tests preserve thread ids, callback payloads, message id persistence, and direct notification mode behavior.
|
||||
- Discord source tests verify registration of scheduler handlers, RSVP component routes, and messenger methods.
|
||||
- RSVP flow tests run through platform-neutral `PlatformUser` identity, including Discord users without Telegram ids.
|
||||
- Discord messenger tests verify DMs are attempted, DM failures are swallowed after logging, channel notifications include buttons or mentions as appropriate, and message refs are returned.
|
||||
- Full regression: `dotnet test tests/GmRelay.Bot.Tests/GmRelay.Bot.Tests.csproj`, `dotnet build`, and `dotnet format --verify-no-changes --verbosity diagnostic`.
|
||||
|
||||
## Versioning
|
||||
|
||||
Current repository version is `2.6.0`. Although the Gitea issue is labeled `type:refactor`, the approved scope adds full Discord notification behavior. Proposed bump: `2.6.0` to `2.7.0`.
|
||||
|
||||
Synchronize:
|
||||
|
||||
- `Directory.Build.props`
|
||||
- `compose.yaml` image tags for bot, discord, and web
|
||||
- `.gitea/workflows/deploy.yml` `VERSION`
|
||||
- `src/GmRelay.Web/Components/Layout/NavMenu.razor`
|
||||
|
||||
## Out Of Scope
|
||||
|
||||
- Moving the entire scheduler hosted service into `GmRelay.Shared`.
|
||||
- Removing legacy Telegram columns such as `telegram_chat_id`, `confirmation_message_id`, or `link_message_id`.
|
||||
- Reworking Web dashboard Telegram behavior.
|
||||
- Public fallback messages when a Discord DM is blocked.
|
||||
|
||||
## Self-Review
|
||||
|
||||
- Spec coverage: every issue acceptance criterion is represented by scheduler handler boundaries, messenger contracts, Telegram behavior preservation, and Discord implementation requirements.
|
||||
- Placeholder scan: no TBD/TODO/fill-in-later sections remain.
|
||||
- Internal consistency: the design uses semantic platform DTOs consistently and keeps SDK-specific rendering in platform implementations.
|
||||
- Scope check: the work is large but still one coherent platform-notification refactor; moving the whole scheduler to shared remains explicitly out of scope.
|
||||
@@ -1,166 +0,0 @@
|
||||
# Дизайн: Синхронизация документации после MVP2 (Discord + кросс-платформенность)
|
||||
|
||||
**Дата:** 2026-05-21
|
||||
**Версия проекта:** v2.7.2
|
||||
**Статус:** Approved
|
||||
|
||||
---
|
||||
|
||||
## 1. Цель
|
||||
|
||||
Привести всю проектную документацию в актуальное состояние после завершения MVP2:
|
||||
- Discord-интеграция (slash-команды, кнопки, RSVP, reschedule voting, DM-уведомления).
|
||||
- Кросс-платформенная архитектура (`IPlatformMessenger`, `SessionBatchViewBuilder`, platform-specific renderers).
|
||||
- Новые env-переменные (`DISCORD_BOT_TOKEN`), healthcheck на 8082, Docker Compose сервис `discord`.
|
||||
- Регрессионные тесты, обновлённый CI/CD.
|
||||
|
||||
---
|
||||
|
||||
## 2. Аудитории и каналы
|
||||
|
||||
| Аудитория | Канал | Фокус |
|
||||
|---|---|---|
|
||||
| ГМы и игроки | Gitea Wiki | Как пользоваться ботом: команды, кнопки, уведомления, FAQ |
|
||||
| Разработчики и хостеры | `README.md` + `docs/` | Архитектура, сборка, деплой, env-переменные, ADR |
|
||||
|
||||
**Принцип:** Wiki — только пользовательская документация. Технические детали (архитектура, БД, разработка) удаляются из Wiki и консолидируются в репозитории.
|
||||
|
||||
---
|
||||
|
||||
## 3. Wiki (пользовательская документация)
|
||||
|
||||
### Новая структура страниц
|
||||
|
||||
1. **Home**
|
||||
- Общее описание GM-Relay (Telegram + Discord).
|
||||
- Текущая версия v2.7.2.
|
||||
- Ссылки: Быстрый старт, Руководство ГМа, Руководство игрока.
|
||||
- Убираем: технический стек, ссылки на Архитектуру/БД/Разработка.
|
||||
|
||||
2. **Быстрый старт**
|
||||
- Шаг 1: Добавление Telegram-бота в группу.
|
||||
- Шаг 2: Приглашение Discord-приложения на сервер (scopes: bot, applications.commands).
|
||||
- Шаг 3: Создание первой группы (`/newgroup` в Telegram или через Web).
|
||||
- Шаг 4: Создание первого batch (`/newsession`).
|
||||
- Шаг 5: Публикация расписания (`/listsessions`).
|
||||
|
||||
3. **Руководство ГМа**
|
||||
- Telegram-команды: `/newgroup`, `/newsession`, `/listsessions`, `/exportcalendar`.
|
||||
- Discord slash-команды: `/newsession`, `/listsessions`.
|
||||
- Создание и управление batch: картинки, повторы, bulk-операции (Web).
|
||||
- Co-GM и делегирование.
|
||||
- Переносы (reschedule): как инициировать голосование, как работает дедлайн.
|
||||
- Шаблоны кампаний.
|
||||
- Статистика посещаемости (Web).
|
||||
- Управление очередью (waitlist, promote).
|
||||
|
||||
4. **Руководство игрока**
|
||||
- Telegram: запись через inline-кнопки, отмена.
|
||||
- Discord: кнопки Join/Leave в schedule message, RSVP (Confirm/Decline).
|
||||
- Уведомления: за 24ч, за 1ч, ссылка перед игрой, DM vs группа.
|
||||
- Лист ожидания: как попасть, как автоматически продвинуться.
|
||||
|
||||
5. **FAQ / Устранение неполадок**
|
||||
- Бот не отвечает: проверить права, перезапустить.
|
||||
- Кнопки не работают: проверить права Manage Messages / Embed Links.
|
||||
- Mini App не открывается: HTTPS, domain в BotFather.
|
||||
- Discord DM не приходят: privacy settings, бот не может писать first.
|
||||
- Reschedule голосование не завершилось: дедлайн, минимум голосов.
|
||||
|
||||
### Удаляемые Wiki-страницы (контент переходит в README/docs)
|
||||
|
||||
- `Архитектура` → `docs/c4-system-context.md` + `docs/adr/`
|
||||
- `База данных` → `docs/adr/` (описание схемы)
|
||||
- `Разработка` → `README.md` (раздел для контрибьюторов)
|
||||
- `Развёртывание` → `README.md` (Docker Compose quick start)
|
||||
|
||||
---
|
||||
|
||||
## 4. README.md (разработчики и хостеры)
|
||||
|
||||
### Что обновить
|
||||
|
||||
- **Версия:** с `v2.7.0` → `v2.7.2`.
|
||||
- **Key Features — Discord:**
|
||||
- Slash-команды `/newsession`, `/listsessions`.
|
||||
- Кнопки Join/Leave/RSVP с ephemeral-ответами.
|
||||
- DM-напоминания и ссылки (с fallback-логированием).
|
||||
- Reschedule voting с дедлайном.
|
||||
- Waitlist и auto-promote.
|
||||
- **Технологический стек:**
|
||||
- Добавить NetCord Gateway для Discord.
|
||||
- Уточнить: `GmRelay.DiscordBot` — это NetCord Gateway worker (не отдельный проект в solution, а runtime-роль внутри Bot/Web).
|
||||
- Добавить `IPlatformMessenger` в архитектурное описание.
|
||||
- **Структура репозитория:**
|
||||
- Убрать `GmRelay.DiscordBot` как отдельный проект (согласно CLAUDE.md, его нет; Discord-логика внутри `GmRelay.Bot`).
|
||||
- Добавить `GmRelay.ServiceDefaults`.
|
||||
- **Переменные окружения:**
|
||||
- Добавить `DISCORD_BOT_TOKEN`.
|
||||
- Добавить `DISCORD_BOT_CLIENT_ID` (для регистрации slash-команд).
|
||||
- **Docker Compose:**
|
||||
- Добавить сервис `discord` с healthcheck на `:8082`.
|
||||
- Уточнить multi-arch (AMD64/ARM64 для Raspberry Pi).
|
||||
- **Quick Start:**
|
||||
- Добавить шаг приглашения Discord-бота.
|
||||
- Добавить настройку домена для Mini App.
|
||||
|
||||
### Новый раздел (опционально)
|
||||
|
||||
- **Для разработчиков:**
|
||||
- Краткое описание Vertical Slice + Native AOT.
|
||||
- Ссылка на `docs/adr/0001-...` и `docs/adr/002-...`.
|
||||
- Как добавить handler и зарегистрировать в Program.cs.
|
||||
- Как написать миграцию (DbUp).
|
||||
|
||||
---
|
||||
|
||||
## 5. `docs/` (архитектурная и техническая документация)
|
||||
|
||||
### `docs/c4-system-context.md`
|
||||
|
||||
- **Level 1 (System Context):** Добавить Discord Gateway and REST API как external system. Добавить игрокам Discord-взаимодействие.
|
||||
- **Level 2 (Container):** Уточнить, что `GmRelay.Bot` содержит **оба** runtime-роли: Telegram long polling **и** Discord Gateway worker (или уточнить, что Discord worker — отдельный контейнер внутри той же сборки). Проверить текущую C4-диаграмму — она уже содержит `discordBot`, так что нужно только убедиться, что он соответствует `GmRelay.Bot` (а не `GmRelay.DiscordBot`).
|
||||
- **Level 3 (Component):** Уже содержит Discord-компоненты. Проверить актуальность: `DiscordSessionInteractionModule`, `DiscordPlatformMessenger`. Добавить `RescheduleVotingFinalizer` (shared). Добавить `DiscordHealthCheckHostedService`.
|
||||
|
||||
### `docs/adr/0001-use-vertical-slice-native-aot-and-aspire.md`
|
||||
|
||||
- Добавить Discord-аспект: NetCord Gateway worker, slash-команды.
|
||||
- Уточнить, что Aspire оркестрирует **три** сервиса: Bot (Telegram + Discord), Web, PostgreSQL.
|
||||
|
||||
### `docs/adr/002-platform-neutral-batch-rendering.md`
|
||||
|
||||
- Уже содержит Discord renderer. Дополнить:
|
||||
- Issue #30 (reschedule voting) использует `IPlatformMessenger`.
|
||||
- Issue #31 (scheduler notifications) тоже использует `IPlatformMessenger`.
|
||||
- Issue #32 (compose wiring) добавил Discord healthcheck.
|
||||
- Issue #33 (регрессионные тесты) покрывает оба renderer'а.
|
||||
|
||||
### Новый ADR (опционально, если есть время)
|
||||
|
||||
- **ADR-003: Discord Integration Architecture** — почему NetCord (а не DSharpPlus), как Gateway events маршрутизируются в vertical slice handlers, как ephemeral-ответы работают.
|
||||
- Это необязательно, но полезно для будущих разработчиков.
|
||||
|
||||
---
|
||||
|
||||
## 6. Порядок выполнения
|
||||
|
||||
1. **Wiki Home** — обновить описание, версию, ссылки.
|
||||
2. **Wiki Быстрый старт** — переписать с учётом Discord.
|
||||
3. **Wiki Руководство ГМа** — добавить Discord-команды, reschedule voting, статистику.
|
||||
4. **Wiki Руководство игрока** — новая страница (или раздел в Руководстве ГМа).
|
||||
5. **Wiki FAQ** — новая страница.
|
||||
6. **README.md** — версия, features, env, Docker, quick start.
|
||||
7. **`docs/c4-system-context.md`** — Discord-компоненты, healthcheck.
|
||||
8. **`docs/adr/0001-...`** — Discord-аспекты.
|
||||
9. **Удалить устаревшие Wiki-страницы** (Архитектура, База данных, Разработка, Развёртывание) или заменить их редиректами на README.
|
||||
|
||||
---
|
||||
|
||||
## 7. Критерии готовности
|
||||
|
||||
- [ ] Все wiki-страницы отражают текущую версию v2.7.2.
|
||||
- [ ] Все Discord-фичи задокументированы для пользователей.
|
||||
- [ ] README содержит актуальную версию, env-переменные, структуру репозитория.
|
||||
- [ ] C4-диаграмма и ADR'ы отражают Discord-архитектуру и `IPlatformMessenger`.
|
||||
- [ ] Нет противоречий между Wiki и README (например, версия, команды).
|
||||
- [ ] Устаревшие wiki-страницы удалены или содержат редирект.
|
||||
Reference in New Issue
Block a user