Files
cloud-ip-validator/docs/changes/2026-10-04_09-55_analytics-verdict-indicators-plan.md
T

76 lines
9.4 KiB
Markdown
Raw Normal View History

# План: кликабельные индикаторы PASS, PARTIAL, FAIL в разделе «Аналитика»
Статус: реализовано, см. [итог](2026-10-04_09-55_analytics-verdict-indicators-summary.md).
## 1. Что нужно
Вверху страницы `/analytics` есть ряд индикаторов. Сейчас кликабельны только четыре «прикладных»: «Egress https: есть провалы / все провалены» и «Ingress ssh: есть провалы / все провалены» (открывают окно со списком адресов, есть «Скачать CSV» и «Копировать»). Нужно сделать кликабельными ещё три: **pass**, **partial**, **fail**. По клику открывается тот же диалог со списком адресов с этим вердиктом.
Остальные индикаторы («Адресов», «Egress OK», «Ingress OK», «Длительность», «Поздние результаты») остаются как есть: в задаче их нет.
## 2. Решение
Новые виды списков строятся по тому же механизму, что и существующие: control-api отдаёт таблицу (JSON или CSV), дашборд проксирует, JS открывает диалог. Новых маршрутов, миграций и новых данных не нужно: вердикт, число проверок и причина `partial` уже вычисляются в `analytics.Compute`.
### 2.1. control-api (`internal/analytics/lists.go`)
Три новых вида списка (`kind`): `verdict_pass`, `verdict_partial`, `verdict_fail`. В список входят адреса запуска с этим вердиктом; отменённые (`cancelled`) не входят, как и в остальных списках и в числах `summary`. Порядок — по числовому адресу (`an.sorted()`).
Столбцы:
| Вид | Столбцы |
|---|---|
| `verdict_pass` | Адрес, Подсеть, Валидатор, Egress, Ingress, Проверок в цикле |
| `verdict_partial` | Адрес, Подсеть, Валидатор, Egress, Ingress, Проверок в цикле, **Причина** |
| `verdict_fail` | Адрес, Подсеть, Валидатор, Egress, Ingress, Проверок в цикле |
- «Валидатор» — тот же, что в списках https (`ShortValidator`); пусто → «—».
- «Egress» и «Ingress» — «успешно из всех» по уровню (`8 из 10`); у уровня без проверок — «—».
- «Проверок в цикле» — сохранённых из ожидаемых (`stored из ExpectedChecks`; если ожидаемое неизвестно, только сохранённое). Позволяет сразу увидеть «неполный набор».
- «Причина» у `partial` — та же формулировка, что в блоке «Почему partial» (`reasonName`), поэтому строки списка совпадают со столбиками блока.
Название CSV: `verdict_pass_run<N>.csv` и т. д. (по общему правилу). Для остальных видов ничего не меняется. Неизвестный `kind` по-прежнему даёт `404`.
Инвариант: число строк списка равно числу на карточке (`summary.pass / partial / fail`).
### 2.2. Дашборд (`internal/dashboard/static/analytics.js`, `analytics.css`)
- В `renderKpis` у плиток `pass`, `partial`, `fail` в поле списка ставится соответствующий `kind`, плитка становится `<button class="an-kpi" data-list=…>` и получает «список →», как у прикладных. У `fail` при значении 0 плитка остаётся некликабельной (список пуст, сейчас там надпись «ни одной полностью проваленной»).
- В `LISTS` добавляются три записи: заголовок («Адреса с вердиктом pass» и т. д.), пояснение («Вердикт адреса за последний цикл запуска, выставленный системой при агрегации…»), подсказки к столбцам (что значит Egress/Ingress, «Проверок в цикле», «Причина»).
- Обработчик клика и диалог менять не нужно: `[data-list]` уже подхватывает любую плитку. Стили есть (`button.an-kpi`); `an-go` для плитки без тега «успех/частично/провал» ставится рядом с существующим тегом.
- Серверной части дашборда (`handlers_analytics.go`, прокси списка и CSV) менять не нужно: `kind` в пути произвольный.
### 2.3. Объём списка pass
В запуске на ~6400 адресов `pass` может быть несколько тысяч строк. Диалог сейчас показывает все строки. Оставляем так (таблица на несколько тысяч строк в браузере открывается нормально) и проверяем на реальном объёме при выкладке; если окно тормозит — отдельным шагом добавим показ первых N строк с пометкой «полный список — в CSV». Выгрузка в CSV и копирование всегда полные.
## 3. Файлы
- `internal/analytics/lists.go` — константы, столбцы и строки новых видов.
- `internal/analytics/analytics.go` — только если нужна вспомогательная функция для строки «Egress/Ingress» (иначе без изменений).
- `internal/httpapi/handlers_analytics.go` — только комментарий с перечнем видов.
- `internal/dashboard/static/analytics.js` — плитки и `LISTS`.
- Документы: `docs/API.md` (перечень `kind`), `docs/USAGE.md` («Что можно открыть»), `docs/DASHBOARD.md` (строка `/analytics`), `README.md` (веха), итог `docs/changes/…-summary.md`.
## 4. Тесты
- `analytics`: для набора с pass, partial, fail и cancelled — число строк каждого списка равно `summary`; отменённые не входят; порядок по адресу; столбцы и значения «Egress/Ingress/Проверок в цикле»; «Причина» совпадает с `reasons`; у неполного набора в «Проверок в цикле» меньше ожидаемого.
- `httpapi`: `GET …/lists/verdict_partial` отдаёт JSON, `?format=csv` — файл с именем `verdict_partial_run<N>.csv`; неизвестный вид — `404` (уже есть, расширить).
- `dashboard`: прокси списка пропускает новые виды; в отданных данных страницы плитки pass/partial/fail имеют ссылки (если страница это проверяет без JS — иначе проверка вручную, п. 5).
- Полный `gofmt -l`, `go build ./... && go vet ./... && go test ./...`.
## 5. Выкладка и проверка
Меняются `control-api` (список) и `admin-dashboard` (статика встроена в бинарник); агенты и prober без изменений, миграций нет. Порядок: проверка пустой очереди, тег отката образов, пересборка, перезапуск. Проверка на стенде: на последнем запуске открыть плитки pass, partial, fail, сверить число в заголовке диалога с числом на плитке, скачать CSV, проверить фильтрацию и подсказки; оценить скорость окна на списке pass.
## 6. Риски
- Большой список pass: см. 2.3.
- Вердикт — оценка системы при агрегации, а не по фактическим проверкам (см. «Качество данных»): у адреса pass могут быть поздние провалы. В пояснении диалога это указывается; столбцы Egress/Ingress показывают фактические проверки.
- Числа на плитках и в списках берутся из одного вычисления отчёта, поэтому расходиться не должны (инвариант в тесте).
## 7. Не входит в доработку
Кликабельность «Egress OK», «Ingress OK», «Адресов», «Поздних результатов»; фильтры и сортировка внутри диалога; ссылка из строки диалога в «Реестр».
Открытых вопросов нет. Жду команды начать реализацию.