Files
cloud-ip-validator/docs/changes/2026-10-06_13-11_registry-subnet-select-and-breakdown-chart-plan.md
T
ayurishchevandClaude Sonnet 5.5 ded196ec8d Registry and Analytics: run, subnet, direction and protocol filters, successes-by-target chart
Registry (/registry):
- filters by run (slice by the address's cycle in that run), subnet
  (drop-down of configured subnets), direction (egress/ingress) and
  protocol (icmp, tcp, ssh, https, tls); status in scope is computed over
  the narrowed checks
- chart "successful checks per target (egress) / site (ingress)" when both
  direction and protocol are chosen; a row opens the list of addresses
  (dialog, CSV)
- API: direction/protocol parameters and run in GET /admin/registry,
  GET /admin/registry/breakdown and /breakdown/list
- subnet filter passes ids as one JSON parameter (SQLite variable limit)

Analytics (/analytics):
- subnet filter recomputes the whole page over the addresses of the run
  inside the subnet; only their checks are read; cache per run and subnet
- direction and protocol focus the page; with both set the registry chart
  is shown
- subnet parameter in GET /admin/analytics/runs/{id} and lists (JSON, CSV)

Docs: plans and summaries in docs/changes, README, API, USAGE.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-06 14:23:48 +03:00

13 KiB
Raw Blame History

План: выпадающий список подсетей и чарт «успешные проверки по целям / площадкам» в «Реестре»

Редакция 2 (решения по вопросам подтверждены пользователем).

Продолжение 2026-10-06_12-12_registry-subnet-direction-protocol-filters. Фильтры работают; улучшаем удобство и восприятие.

Задача

  1. Подсеть выбирается из выпадающего списка (сейчас — поле ввода с подсказками).
  2. Когда выбраны направление и протокол (например, Egress + https), над таблицей показывается чарт «количество успешных проверок» по каждой цели 1…N:
    • Egress — в разрезе целей;
    • Ingress — в разрезе площадок (та же логика).
  3. Строка чарта кликабельна и открывает список адресов с детализацией.
  4. Подход переиспользуем из «Аналитика → Egress по целям».

Что уже есть (граф + код)

  • Аналитика: блок «Egress по целям» — строки an-bar-row (название, полоса an-track/an-fill, число и процент), вкладки по типу проверки. Диалог со списком адресов (analytics-dialog.js, шаблон analytics_dialog, «Копировать», «Скачать CSV», подсказки при наведении) подключается страницей и уже обслуживает списки по запросу load(url) → fill(...). Стили — static/analytics.css.
  • Данные в БД: в checks для egress target — адрес цели (https://github.com), source='egress'. Для ingress source = inbound-site-N (площадка), а target — сам проверяемый адрес, поэтому ingress группируется по source, а не по target. Имена площадок берутся по индексу (как SiteNames в аналитике), без имени — site-N.
  • Срез данных (запуск / последний цикл, направление, протокол, статус, подсеть) уже реализован в internal/db/queries_registry.go (registrySlice, scopeFrom). Чарт строится по тому же срезу и тому же набору адресов, что и таблица.
  • Список настроенных подсетей уже грузится в форму (GetSubnets), 45 штук на стенде.
  • Таблица /registry обновляется через htmx (#registry-table-wrap).

Решения (подтверждены пользователем)

  1. Когда показывать чарт: выбраны и направление, и протокол. С одним направлением вместо чарта — короткая подсказка «Выберите протокол, чтобы увидеть распределение по целям/площадкам».
  2. Набор адресов — все под текущим фильтром (запуск, подсеть, статус, поиск), а не только текущая страница. Чарт совпадает с «Найдено адресов: N». Чарт строится в разрезе проверок выбранного типа в рамках проверочного цикла среза: цикл адреса в выбранном запуске или его последний цикл.
  3. Что считается: число записанных проверок выбранного типа в проверочном цикле среза: успешных из всего. Полоса — доля успешных; подпись: 1 234 из 1 250 · 98,7%. У tcp и tls на ingress у адреса может быть несколько проверок на площадку (порты 22 и 443), поэтому считаются именно проверки, а не адреса (пояснение в подписи под чартом).
  4. Порядок строк: от большего к меньшему по числу успешных проверок, при равенстве — по названию. Полоса масштабируется по наибольшему значению; доля успешных остаётся в подписи.
  5. Подпись цели: адрес цели без схемы и без завершающего / (repo.almalinux.org/almalinux), ключ — исходное значение target. Разные пути на одном хосте остаются разными строками.
  6. Клик по строке: диалог со списком всех адресов набора, у которых есть проверки этой цели/площадки, провалы сверху (порядок списка не связан с порядком чарта). Столбцы: Адрес, Результат (успешно/провал), Тип проверки (https, tcp-22…), Цель или Площадка, Валидатор (для egress), Задержка (мс), Детали (ошибка), Проверено. Сверху — счётчики «успешно N · провал M». Доступны «Копировать» и «Скачать CSV».
  7. Подсеть в списке (ручной ввод убирается, решение подтверждено): варианты — «Все подсети» + настроенные подсети (CIDR — метка). Ручной ввод убирается. Подсеть из URL (переход из аналитики), которой нет в списке, добавляется отдельным выбранным пунктом. Если подсети не настроены — список недоступен, рядом ссылка на /settings с их настройкой.
  8. Egress + ssh/tcp/tls (таких проверок нет): чарт показывает «Для этого сочетания проверок нет», как и пустая таблица.

Изменения

1. БД (internal/db)

  • Выделить сборку условий FROM/WHERE из ListRegistryPage в функцию, которую используют и список, и новая выборка (поведение списка не меняется; существующие тесты — страховка).
  • Новый файл queries_registry_breakdown.go:
    • RegistryBreakdown(ctx, filter) (*Breakdown, error): требует Level и Family (иначе ErrValidation); один запрос GROUP BY по target (egress) или source (ingress) поверх проверок среза: COUNT(*), SUM(success). Возвращает группу (target|site), число адресов, строки {key, total, ok}.
    • RegistryBreakdownList(ctx, filter, key): строки проверок выбранного ключа с адресом, типом, валидатором, задержкой, деталью, временем; провалы сверху.
  • Индексы idx_checks_run и idx_checks_registry_cycle уже подходят; проверить EXPLAIN QUERY PLAN.

2. HTTP API (internal/httpapi)

  • GET /api/v1/admin/registry/breakdown — те же параметры, что у реестра (q, last_result, run, subnet, direction, protocol); без direction или protocol — 400. Ответ: {group, direction, protocol, run, addresses, rows:[{key,label,total,ok}]}; имена площадок подставляются здесь.
  • GET /api/v1/admin/registry/breakdown/list?…&key= — таблица {columns, rows}; format=csv — файл. Неизвестный ключ — 404.
  • Маршруты — в таблицу маршрутов (TestRouteTableIsClassified: admin-доступ). docs/API.md — описание и примеры.

3. Дашборд (internal/dashboard)

  • client.go: GetRegistryBreakdown, GetRegistryBreakdownList, …CSV.
  • handlers_registry.go: при выбранных направлении и протоколе запросить чарт и передать в шаблон; ошибка чарта показывается в самом блоке, страница не ломается. Прокси-маршруты GET /registry/breakdown/list и GET /registry/breakdown/csv (как analytics/lists).
  • templates/registry.html:
    • поле «Подсеть» → <select> (htmx-атрибуты те же, что у соседних полей);
    • блок registry_breakdown внутри registry_table (обновляется вместе с таблицей): заголовок «Успешные проверки по целям» / «…по площадкам», тип проверки, строки-кнопки an-bar-row с серверной отрисовкой полос (без JS-библиотек), подпись и подсказка про учёт проверок;
    • подключение analytics.css, analytics-dialog.js, шаблона analytics_dialog и нового static/registry.js.
  • static/registry.js (небольшой): делегированный клик по [data-bd-key] (переживает htmx-замену), запрос списка с текущей строкой фильтров из адресной строки, AnalyticsDialog.load/fill с подсказками столбцов и ссылкой на CSV.
  • Проверить, что analytics.css не конфликтует со стилями реестра (все классы с префиксом an-; токены темы общие). Если есть конфликт — вынести нужные правила в dashboard.css.
  • Доступность: строки — <button>, фокус с клавиатуры, aria-label с числами; светлая и тёмная темы; мобильная раскладка (строка переносится, полоса остаётся).

4. Тесты (минимум)

  • internal/db: один табличный тест выборок — egress по целям, ingress по площадкам, срез запуска, подсеть, статус в области, список по ключу (порядок, провалы сверху), ErrValidation без направления или протокола.
  • internal/httpapi: 400 без параметров, форма ответа, список и CSV, 404 на неизвестный ключ.
  • internal/dashboard: чарт есть при направлении + протоколе и отсутствует без них; подсеть — <select> с выбранным пунктом и пунктом из URL; прокси списка.
  • TestScaleSmoke6440: чарт и список на 6440 адресов в пределах лимита.
  • Правки существующих тестов, где проверялось поле ввода подсети.

Порядок работы

  1. Утвердить план и «Решения».
  2. Субагент (Sonnet 5.5, Medium effort) пишет код и тесты: п.1 → п.2 → п.3 → п.4.
  3. Ревью, gofmt, go build ./... && go vet ./... && go test -count=1 ./..., EXPLAIN QUERY PLAN.
  4. Проверка на тестовом стенде civ-test (порты 18081/18091): пересобрать образы тега filters, docker compose up -d в /opt/lvraid/claude/civ-teststand, снять замеры на копии боевой БД. Боевые контейнеры не трогаем.
  5. Summary в docs/changes/…-summary.md; обновить README.md, docs/API.md, docs/USAGE.md; обновить граф /graphify . --update.

Риски

  • Объём списка: до 6–7 тысяч адресов в диалоге, как в аналитике; для CSV — серверная выгрузка.
  • Время ответа чарта на 1 млн проверок: ожидается долей секунды (один GROUP BY по срезу); проверить замером на копии БД стенда. При деградации — не считать чарт, пока не выбраны оба фильтра (уже предусмотрено).
  • Названия площадок и целей берутся из текущей конфигурации: удалённая площадка отображается как site-N.
  • Незавершённый запуск даёт частичные данные — как и таблица.
  • Подсеть только из списка: чтобы отфильтровать произвольный CIDR, подсеть нужно добавить в настройки (ссылка рядом с полем).