feat: log bot command invocations to the event stream
Bot commands were the only user-initiated path that didn't surface in the dashboard. They now produce ``command_handled`` / ``command_rate_limited`` / ``command_failed`` rows in ``EventLog`` alongside tracker and action events. Backend - ``EventLog`` gains nullable ``command_tracker_id`` / ``telegram_bot_id`` FKs plus deletion-snapshot name columns (idempotent migration). - New ``_log_command_event`` helper emits one row per invocation at the three branches in ``handle_command``. Logging failures are swallowed so they cannot block the user-visible reply. - Telegram ``from`` is captured in poller and webhook, whitelisted to identity fields by ``_normalize_issuer`` (drops ``language_code`` and any future PII), persisted under ``details.issuer``. - ``/api/status`` resolves live ``CommandTracker`` / ``TelegramBot`` names (mirroring the action pattern) and exposes ``tracker_id``, ``command_tracker_id``, ``telegram_bot_id`` so the frontend can deep-link. Frontend - Event rows are now clickable and open a detail modal with full provenance (bot → chat → issuer → provider), raw ``details`` JSON, and per-entity action buttons. - Buttons use the existing ``requestHighlight`` + ``goto`` crosslink pattern, so clicking lands on the entity's list page with that specific card scrolled into view and pulsing. - Auto-refresh dropdown (Off / 10s / 30s / 1m / 5m) persisted in ``localStorage``; ticker pauses while the tab is hidden. - Event-type filter, dashboard verb labels, and gradients extended for the three new ``command_*`` types. - Filled in pre-existing missing i18n keys (``common.hide`` / ``common.show`` / ``commandConfig.noCommandsForProvider``). Tests - New ``test_command_event_logging.py`` covers subject formatting, issuer normalization, the three event branches, and graceful failure when the DB is unreachable. ``pytest packages/server/tests/`` → 96/96.
This commit is contained in:
@@ -87,6 +87,15 @@
|
||||
"actionSuccess": "действие выполнено",
|
||||
"actionPartial": "действие частично",
|
||||
"actionFailed": "действие провалено",
|
||||
"commandHandled": "команда обработана",
|
||||
"commandRateLimited": "ограничение частоты",
|
||||
"commandFailed": "команда упала",
|
||||
"autoRefreshTitle": "Интервал авто-обновления списка событий",
|
||||
"refreshOff": "Выкл",
|
||||
"refresh10s": "10с",
|
||||
"refresh30s": "30с",
|
||||
"refresh60s": "1м",
|
||||
"refresh5m": "5м",
|
||||
"searchEvents": "Поиск событий...",
|
||||
"allEvents": "Все события",
|
||||
"filterAssetsAdded": "Добавление файлов",
|
||||
@@ -97,6 +106,9 @@
|
||||
"filterActionSuccess": "Действие выполнено",
|
||||
"filterActionPartial": "Действие частично",
|
||||
"filterActionFailed": "Действие провалено",
|
||||
"filterCommandHandled": "Команда обработана",
|
||||
"filterCommandRateLimited": "Ограничение частоты",
|
||||
"filterCommandFailed": "Команда упала",
|
||||
"allProviders": "Все провайдеры",
|
||||
"newestFirst": "Сначала новые",
|
||||
"oldestFirst": "Сначала старые",
|
||||
@@ -141,6 +153,23 @@
|
||||
"newTracker": "Новый трекер",
|
||||
"eventsTotal": "Событий"
|
||||
},
|
||||
"events": {
|
||||
"detailTitle": "Детали события",
|
||||
"bot": "Бот",
|
||||
"chat": "Чат",
|
||||
"issuer": "Отправитель",
|
||||
"commandTracker": "Командный трекер",
|
||||
"tracker": "Трекер",
|
||||
"action": "Действие",
|
||||
"provider": "Провайдер",
|
||||
"assetsCount": "Файлов",
|
||||
"openProvider": "Открыть провайдера",
|
||||
"openBot": "Открыть бота",
|
||||
"openCommandTracker": "Открыть командный трекер",
|
||||
"openAction": "Открыть действие",
|
||||
"openTracker": "Открыть трекер",
|
||||
"rawDetails": "Сырые данные"
|
||||
},
|
||||
"providers": {
|
||||
"title": "Сервисные",
|
||||
"titleEmphasis": "провайдеры",
|
||||
@@ -889,6 +918,7 @@
|
||||
"titleEmphasis": "конфигурации",
|
||||
"countLabel": "конфигураций",
|
||||
"title": "Конфигурации команд",
|
||||
"noCommandsForProvider": "Для этого типа провайдера нет доступных команд.",
|
||||
"description": "Настройки команд для взаимодействия с Telegram-ботами",
|
||||
"newConfig": "Новая конфигурация",
|
||||
"name": "Название",
|
||||
@@ -1025,6 +1055,8 @@
|
||||
"edit": "Редактировать",
|
||||
"description": "Описание",
|
||||
"close": "Закрыть",
|
||||
"hide": "Скрыть",
|
||||
"show": "Показать",
|
||||
"confirm": "Подтвердить",
|
||||
"cannotDelete": "Невозможно удалить",
|
||||
"blockedByIntro": "На объект ссылаются:",
|
||||
@@ -1149,6 +1181,14 @@
|
||||
"actionSuccess": "Запланированное действие выполнено",
|
||||
"actionPartial": "Запланированное действие выполнено частично",
|
||||
"actionFailed": "Запланированное действие провалено",
|
||||
"commandHandled": "Команда бота обработана",
|
||||
"commandRateLimited": "Команда бота ограничена по частоте",
|
||||
"commandFailed": "Команда бота вызвала ошибку",
|
||||
"refreshOff": "Автообновление выключено",
|
||||
"refresh10s": "Обновлять каждые 10 секунд",
|
||||
"refresh30s": "Обновлять каждые 30 секунд",
|
||||
"refresh60s": "Обновлять каждую минуту",
|
||||
"refresh5m": "Обновлять каждые 5 минут",
|
||||
"newestFirst": "Сначала новые события",
|
||||
"oldestFirst": "Сначала старые события",
|
||||
"chatActionNone": "Индикатор не показывается",
|
||||
|
||||
Reference in New Issue
Block a user