# Метрики и короткая история узлов в веб-консоли - **Кому:** `antigravity` - **Дата:** 2026-08-20 - **От кого:** главный агент (`claude`), по задаче владельца «консоль надо сделать так же, как и Windows-программа» - **Ветка:** `antigravity/console-node-metrics` - **Файл отчёта:** `../done/2026-08-20-console-node-metrics.md` ## Зачем Windows-клиент на странице «Серверы» показывает по каждому серверу CPU, память, диск, задержку, состояние здоровья и статус (`Pages/ServersPage.xaml`: `CpuText`, `MemoryText`, `DiskText`, `LatencyText`, `HealthText`, `Status`). Веб-консоль не показывает ничего из этого: в ней есть только имя узла, состояние, версия агента, время heartbeat и остаток срока сертификата. Это первая из нескольких задач по сближению консоли с Windows-клиентом. Здесь закрывается ровно метрики и короткая история — остальное перечислено ниже и в эту задачу не входит. ## Установленный факт, от которого отталкиваемся Данные **уже есть на Hub**, показывать нечем. `ControlStore` содержит таблицу (`ControlStore.cs:81`): ```sql CREATE TABLE IF NOT EXISTS metric_samples ( sequence INTEGER PRIMARY KEY AUTOINCREMENT, node_id TEXT NOT NULL REFERENCES agents(node_id) ON DELETE CASCADE, recorded_at TEXT NOT NULL, payload_json TEXT NOT NULL ); CREATE INDEX IF NOT EXISTS ix_metric_samples_node_time ON metric_samples(node_id, recorded_at DESC); ``` Наполняется она из heartbeat агента, чистится по `MetricRetentionHours` (по умолчанию 168 часов). При этом в группе `/api/v1/control` **нет ни одного маршрута для метрик** — я перечитал все `control.Map*` в `Program.cs`. То есть оператор физически не может их получить. ## Что нужно сделать 1. **Добавить в Control чтение метрик под ролью Operator.** Как минимум последний срез по каждому узлу и история по одному узлу за period. Форму запроса, имена полей и ограничение на объём выбираешь сам и обосновываешь в отчёте. Обязательные требования: маршрут в группе `control` (то есть `RequireAuthorization("Operator")`), ограничение количества возвращаемых точек, и никакого доступа к чужим данным по роли Agent или Automation. 2. **Показать это в консоли** в разделе узлов: текущие CPU, память, диск и задержка рядом с узлом, плюс короткая история — так же, как её показывает Windows-клиент. 3. **`payload_json` — данные из внешнего источника.** Он приходит от агента. Разбирать его в консоли только через уже имеющийся `escapeHtml`, как это сделано с payload событий; ни одной вставки в `innerHTML` без экранирования. Отсутствующие или битые поля не должны ронять таблицу узлов. ## Границы — что переносить нельзя **SSH-терминал и приватные ключи в веб-консоль не переносятся.** Это не вопрос трудоёмкости, а заявленное свойство продукта: README обещает «opens direct SSH terminals without sending a private terminal key to the Hub», а ключ мониторинга и сертификат оператора защищены DPAPI и лежат только на Windows-машине. Страница Sessions остаётся у Windows-клиента. Также не входит в эту задачу и делается отдельно: страница Settings, группы и теги серверов, alert rules и журнал уведомлений (последние два пункта в `docs/roadmap.md` числятся невыполненными и для Windows-клиента). Не трогать: `deploy/**`, релизные workflow, Desktop, схему существующих таблиц (добавление индексов допустимо и обосновывается). ## Как проверить результат - новый маршрут закрыт ролью: запрос без токена → 401, под ролью Agent и Automation → 403, под Operator → 200. Три теста, вывод в отчёт; - ограничение объёма истории проверено тестом: запрос заведомо большего количества точек возвращает не больше предела; - битый или неполный `payload_json` не роняет ни маршрут, ни отрисовку — тест на каждую сторону; - `dotnet test` целиком зелёный, с выводом; - прогоны CI на PR — ссылками. ## Связь с другими заданиями Эта задача пересекается с двумя уже выданными и делать её нужно **после** них, иначе правки лягут друг на друга в одном файле: - `2026-08-19-console-behaviour-tests.md` — поведенческие тесты консоли. Новая функциональность обязана прийти с такими тестами сразу, а не проверками строк в HTML; - `2026-08-19-console-events-throttle.md` — троттлинг обновления дашборда. Метрики увеличат объём каждого обновления, поэтому без троттлинга усиление нагрузки станет заметнее. Если считаешь, что порядок должен быть другим, — скажи в отчёте и обоснуй, это решение приму. ## Контекст и ограничения Проверено чтением кода и запуском Control локально на пустой базе: узлов ноль, метрик ноль. Как выглядят настоящие `payload_json` от живого агента, я не видел — на живом Hub не проверял. Прежде чем фиксировать контракт ответа, посмотри фактическую форму payload в коде агента, а не в моём описании.