# GM-Relay — C4 Model ## Level 1: System Context ```mermaid C4Context title GM-Relay System Context Person(gm, "Game Master", "Создаёт сессии, управляет расписанием игр") Person(player, "Player", "Подтверждает участие через inline-кнопки") System(gmrelay, "GM-Relay Bot", "Telegram Worker Service на Raspberry Pi. Управляет подтверждениями, рассылает напоминания и ссылки.") System_Ext(telegram, "Telegram Bot API", "Long Polling. Сообщения, inline keyboards, callback queries.") SystemDb_Ext(postgres, "PostgreSQL", "Сессии, игроки, RSVP-статусы") Rel(gm, telegram, "Команды бота (/newsession)") Rel(player, telegram, "Нажимает кнопки (✅ Буду / ❌ Не смогу)") Rel(telegram, gmrelay, "Updates (Long Polling)") Rel(gmrelay, telegram, "SendMessage, EditMessage, AnswerCallbackQuery") Rel(gmrelay, postgres, "SQL (Npgsql + Dapper)") ``` ## Level 2: Container ```mermaid C4Container title GM-Relay Containers Person(gm, "Game Master") Person(player, "Player") System_Boundary(pi, "Raspberry Pi 5") { Container(bot, "GmRelay.Bot", "Worker Service, .NET 10 AOT", "Long polling, обработка команд и callback queries, планировщик") ContainerDb(db, "PostgreSQL 16", "Database", "sessions, players, session_participants, game_groups") } System_Ext(telegram, "Telegram Bot API") Rel(gm, telegram, "Commands") Rel(player, telegram, "Callback Queries") Rel(telegram, bot, "GetUpdates (Long Polling)") Rel(bot, telegram, "Bot API calls") Rel(bot, db, "Npgsql + Dapper.AOT") ``` ## Level 3: Component (GmRelay.Bot) ```mermaid C4Component title GmRelay.Bot Components Container_Boundary(bot, "GmRelay.Bot") { Component(polling, "TelegramBotService", "BackgroundService", "Long polling loop, получает Updates") Component(router, "UpdateRouter", "C#", "Маршрутизирует Update → Handler по типу") Component(scheduler, "SessionSchedulerService", "BackgroundService", "PeriodicTimer(60s): T-24ч и T-5мин триггеры") Component(migrator, "DbMigrator", "DbUp", "SQL миграции при старте") Component(confirm, "SendConfirmationHandler", "Feature", "Отправляет inline keyboard за 24ч") Component(rsvp, "HandleRsvpHandler", "Feature", "Обрабатывает ✅/❌, проверяет all-confirmed") Component(link, "SendJoinLinkHandler", "Feature", "Отправляет join link за 5 мин") } System_Ext(telegram, "Telegram Bot API") ContainerDb(db, "PostgreSQL") Rel(polling, router, "Update") Rel(router, rsvp, "CallbackQuery rsvp:*") Rel(scheduler, confirm, "T-24h trigger") Rel(scheduler, link, "T-5min trigger") Rel(confirm, telegram, "SendMessage + InlineKeyboard") Rel(rsvp, telegram, "EditMessage + AnswerCallback") Rel(link, telegram, "SendMessage + user mentions") Rel(confirm, db, "SELECT/UPDATE sessions") Rel(rsvp, db, "UPDATE participants, SELECT counts") Rel(link, db, "SELECT confirmed players") Rel(migrator, db, "DDL migrations") ```