Files
MikrotikManager/docs/ux-ui-stage-11b.md
T

24 KiB
Raw Blame History

Этап 11Б: сбор данных, оповещения и настройки

ReUI PRO/base-nova; существующие Frame, Data Grid v9, KpiStatGrid, Sheet. Последовательные блоки, локальные коммиты без push. Этап 11А принят локально в 11А.33.

Область Референс Схема и результат
Сбор данных / scheduler Settings 16, Data Grid Filtering 2 Источник → свежесть → настройки/журнал → подтверждённый запуск
Оповещения Stats 12, Sheet 8 Правило → фактическое состояние → адресат → подтверждённая отправка
Интеграции / настройки Settings 16 Секция → сохранённое состояние/черновик → проверка соединения → результат
Релизы List 9 Текущая сборка → доступные сведения → понятный переход
[Источник / права] → [Независимые подтверждённые данные]
                           ↓
[Черновик настроек] → [Действие] → [API receipt]
                           ↓             ↓
                   [Ошибка/unknown]   [Снимок результата]
                           └──────→ [Отдельное обновление]
Порядок Раздел / исходные файлы Выявленная проблема Точка завершения
1 backend scheduler.ts / routes/scheduler.ts Безусловный ok и повторная запись после journal failure Один collector/одна запись, partial/fatal явно сохранены (11Б.1)
2 lib/scheduler-run-snapshot.ts, data-collection/page.tsx PostgreSQL JSONB объект обрабатывается как строка Object и legacy JSON отображаются без падения
3 data-collection/page.tsx Общий Promise.allSettled задерживает быстрые зависимости; refresh сбрасывает drafts; числа нормализуются; run-now receipt игнорируется Strict API, независимые known/error/time, сохранённые формы, lock/права/контекст
4 alerts/page.tsx / routes/alerts.ts Зависимости/CRUD/отправка требуют профильного аудита Правило/получатель/частичный результат/без повторной отправки при неизвестности
5 settings/page.tsx, Evolution/NetFlow интеграции Секреты, сохранение, test/refresh и сообщения требуют аудита Проверка сохранённой конфигурации, черновик и подтверждённый результат раздельны
6 releases/page.tsx Проверить фактические сведения сборки/переходы Семантическая оболочка, пустой/unknown, ПК/390/320
7 probes расписание, общая приёмка Осталось после этапа 10 Настройки расписания/результат, профильная регрессия/снимки/build

Границы: данные наблюдения offline/down не заменять ошибкой сборщика; записанные samples и доставка Telegram — разные результаты. Не менять сетевые правила и права. Локальные DI/HTTP фикстуры не доказывают PostgreSQL транзакции, RouterOS, реальную доставку Telegram/Portal и долговечную идемпотентность.

Блок 11Б.1 — общий scheduler runner и карта оставшихся разделов (2026-10-01)

  • Collector вызывается один раз, результат записывается одной попыткой. Fatal/errors snapshot даёт status=error с сохранёнными счётчиками/снимком; partial отмечается текстом «Завершено с ограничениями». Наблюдаемое down/offline само по себе не является ошибкой выполнения коллектора. Skipped/not-due не порождают событие о выполненной работе.
  • Ошибки event/hook отделены от результата. Отказ run journal не создаёт вторую запись; выдаётся явная ошибка подтверждения журнала с предупреждением о повторных операциях. Ручной API возвращает ok=false/result для partial и отдельный statusError при отказе чтения статуса после подтверждённого запуска.
  • 9 runner + 4 HTTP теста, backend/contracts build и ESLint изменённых файлов прошли. Общий npm --prefix backend test завершился с кодом 0; DB-зависимые тесты пропущены из-за недоступного PostgreSQL, это не проверка транзакций с реальной DB.
  • Карта/референсы/схема оставшегося этапа сохранены в ux-ui-stage-11b.md. UI сбора данных пока не читает новый receipt строго; JSONB resultJson ошибочно ожидается строкой (raw.trim может выбросить ошибку). Следующий небольшой блок исправляет совместимость JSONB/legacy JSON; полные reader/state/операции — после него.
  • Следующий блок 11Б.2: отображение object/legacy snapshot в общем журнале без падения, затем 11Б.3 строгие API и независимые состояния/черновики сбора данных. Этап 11Б/12 не принят, реальные DB/RouterOS/Telegram/Portal остаются внешней приёмкой.

Блок 11Б.2 — JSONB и legacy snapshot общего журнала (2026-10-01)

  • resultJson читается как unknown: PostgreSQL JSONB объект и старый строковый JSON проходят общий decoder. Больше нет raw.trim на объекте. Проверены версия/известная задача/время/обязательные поля верхнего уровня; backup counts и новые diagnostics валидируются без подстановки нулей.
  • Снимок другого job не отображается в выбранной записи. Некорректный/неподдерживаемый снимок показывает Alert «Снимок недоступен», отсутствие снимка остаётся отдельным состоянием. Полная валидация вложенных строк остальных коллекций ещё относится к строгому API следующего блока.
  • 4 unit, 4 E2E object/legacy/invalid/foreign, TypeScript и production frontend/contracts build прошли. ESLint parser/DTO/tests прошёл. На общей странице остаются 2 исходные set-state-in-effect ошибки и 2 warnings: отдельный lint HEAD через stdin подтвердил ту же исходную базу; их исправление входит в reader/context блока 11Б.3.
  • Первый E2E прогон использовал неполную GeoIP фикстуру и падал в старом GeoipSettingsSection. Фикстура уточнена; NetFlow зависимость вынесена в явный HTTP 503 вместо неверного success DTO. Повторные 4 E2E прошли без pageerror. Строгий GeoIP reader/guard также необходим в 11Б, реальная интеграция не принята.
  • ReUI audit checklist получен; существующий Alert/вариант warning, текстовый рендер и структура сохранены. Весь раздел сбора данных ещё не прошёл визуальную/доступностную приёмку.
  • Следующий блок 11Б.3: строгие scheduler/collector API, независимые reader states, dirty drafts и контекст/права; новый run-now receipt пока не обрабатывается страницей строго.

Блок 11Б.3.1 — строгий API-клиент планировщика (2026-10-01)

  • Добавлен shared/api/scheduler.ts: status/runs/run-now/refresh проверяют DTO, известные ключи, дубли, обязательные false/zero/null, время PostgreSQL и согласованность receipt. Фильтр журнала отклоняет записи чужой задачи. Snapshot остаётся unknown в каталоге до отдельного декодирования.
  • Manual POST принимает только receipt выбранной задачи; успешный status с fatal/partial snapshot отклоняется. Partial files, eventError и statusError остаются отдельными подтверждёнными полями. Потерянный/неверный ответ не вызывает повторный POST. Caller cancellation и 30s срок сохранены; timeout POST не доказывает отмену backend.
  • 5 новых API unit + 4 snapshot unit, полный TypeScript и ESLint новых файлов прошли. Frontend build прошёл в 11Б.2; этот блок добавляет пока не подключённый API-модуль, UI/backend не менялись.
  • Клиент ещё не подключён к странице: её старые settings/receipts/locks/context/lint ограничения сохраняются. Это основа миграции, не приёмка операций сборщика. Вложенные коллекции остальных snapshot ещё требуют строгого decoder.
  • Следующий блок 11Б.3.2: GeoIP strict API/receipt против выявленного malformed crash; затем 11Б.3.3 подключение scheduler и независимые reader/context/dirty states.

Блок 11Б.3.2 — строгий GeoIP API против malformed crash (2026-10-01)

  • Существующие GeoIP schemas подключены к GET/PUT/update; неполный status не попадает в UI state. Ответ проверяет ready/loaded и время, PUT подтверждает отправленные поля, update сверяет ok с partial/fatal/errors и счётчиками. False/null/zero не заменяются defaults, partial download остаётся фактом.
  • Выходная ошибка понятна пользователю, без сырого Zod JSON. Запросы имеют caller cancellation/30s срок; неверный/потерянный POST не повторяется автоматически. Timeout не доказывает отмену backend.
  • 4 GeoIP API unit + 5 scheduler API unit, 6 E2E GeoIP/snapshot, профильный ESLint и production frontend/contracts build прошли. E2E fixture GeoIP приведена к полному существующему DTO. Первую проверку toast уточнили для двух dev StrictMode вызовов; повтор прошёл без pageerror.
  • UI GeoIP/NetFlow пока сохраняет прежние defaults/dirty/context/mutation ограничения и требует отдельной приёмки; strict reader исправляет конкретное падение, не доказывает реальные загрузки mmdb или готовность интеграции.
  • Следующий блок 11Б.3.3.1: изоляция контекста страницы сбора и исходные lint ошибки; затем подключение strict scheduler/settings readers, независимые состояния и черновики.

Блок 11Б.3.3.1 — контекст и гонки чтения общего журнала (2026-10-01)

  • Страница ждёт hydration источника; mode/backend задают ключ нового содержимого. При размонтировании читатель становится inactive, старые запросы отменяются и их callbacks не обновляют UI/не запускают последующее чтение.
  • Каждая загрузка отменяет предыдущую и имеет revision/30s deadline; все шесть GET используют общий AbortSignal. Поздний success/error после смены фильтра не заменяет актуальные строки/ошибки/busy. Promise.allSettled пока сохраняется: независимое появление быстрых зависимостей и dirty drafts ещё не реализованы.
  • Сброс раскрытых строк перенесён в обработчик фильтра; эффектные synchronous setState и ненужный stats useMemo устранены. ESLint страницы и нового теста прошёл без прежних 2 errors/2 warnings.
  • 2 новых filter-race + 6 GeoIP/snapshot E2E, production frontend/contracts build со встроенным TypeScript прошли. Отдельные E2E смены backend/mode и поздних мутаций ещё нужны в следующем блоке. Старые mutations не получили новой идемпотентности/lock; их приёмка не заявлена.
  • Следующий блок 11Б.3.3.2: подключение strict scheduler runs и known/error/time журнала; затем независимые settings/status readers, dirty drafts, действия/права и source E2E. GeoIP/NetFlow формы и вся 11Б ещё не приняты.

Блок 11Б.3.3.2 — подтверждённая история и свежесть журнала (2026-10-01)

  • Strict listSchedulerRuns подключён к странице. Missing/duplicate/foreign/invalid DTO не становится пустой историей; первоначальная ошибка даёт unknown/KPI —, подтверждённое empty даёт 0. Ответные ошибки API теперь понятные, без сырого Zod JSON.
  • Фоновый сбой сохраняет строки и прежнее время получения; Alert объясняет необходимость обновления. Смена job filter сбрасывает только историю/раскрытие/свежесть предыдущего среза: старые строки не выдаются за новый фильтр. Browser receivedAt явно подписан временем получения истории, не временем выполнения job.
  • Добавлены 5 history E2E: initial API/malformed, background error, known empty, смена среза. Общие 13 data-collection E2E, 5 scheduler API unit, ESLint страницы/API/теста и production frontend/contracts build прошли. Первые проверки KPI уточнены по реальной вложенности установленного KpiStatGrid; повтор прошёл.
  • Remaining: быстрый журнал пока ждёт остальных пяти зависимостей; status KPI ещё использует uptime/default drafts. Их независимость/known состояния — следующий блок. Forms/mutations/права/весь 11Б не приняты.
  • Следующий блок 11Б.3.3.3: независимое получение scheduler status/runs и достоверные status KPI; затем strict settings readers, dirty drafts и операции.

Блок 11Б.3.3.3 — независимые scheduler status/runs и достоверные KPI (2026-10-01)

  • Strict getSchedulerStatus подключён как отдельный источник. Status/runs публикуются сразу по своим ответам, до завершения пяти settings зависимостей; медленный/ошибочный uptime не задерживает подтверждённую сводку и историю.
  • KPI enabled/running считает подтверждённые jobs, не переключатели/default drafts. Unknown показывает —; backend zero/false сохраняется. Фоновая ошибка оставляет последний статус и прежнее browser receivedAt с Alert обновления. Таблица получает metadata из отдельного status; это не атомарный снимок всех настроек.
  • 13 общих data-collection E2E и 4 status E2E (повтор после уточнения fixture), ESLint страницы/теста и production frontend/contracts build со встроенным TypeScript прошли. Проверен быстрый status/history при задержанном uptime, initial API/malformed, background failure.
  • Первый status fixture по ошибке включал все интеграции generic enabled=true, выявив старый malformed Evolution snapshot crash в sidebar. Fixture ограничена выключенной интеграцией; этот отдельный дефект Evolution reader включён в оставшийся scope 11Б, исправление не заявлено.
  • Остальные settings всё ещё обрабатываются общим Promise.allSettled и могут сбрасывать drafts; strict settings readers/dirty state и операции впереди. GeoIP/NetFlow/общий UI ещё не принят, реальные DB/RouterOS/Portal остаются внешней приёмкой.
  • Следующий блок 11Б.3.3.4: strict collector settings API с реальными различиями DTO; затем подключение независимых settings readers и dirty drafts, mutation/RBAC/source проверки.

Блок 11Б.3.3.4 — строгие readers настроек сборщиков (2026-10-01)

  • Добавлен shared/api/collector-settings.ts: traffic/REST ping/uptime/internet path читаются по своим реальным GET DTO. False/zero/null сохраняются, missing/invalid не нормализуется defaults; PostgreSQL время приводится к тому же ISO instant.
  • REST ping не получает выдуманный retentionDays. Traffic/internet path требуют фактический retention; uptime требует отдельные resources/ping/speed и интервалы. Вложенная scheduler metadata uptime не используется: status уже получает отдельный строгий reader. Сертификаты имеют существующий strict getCertificateRenewSettings, его следует переиспользовать.
  • 10 новых API unit, полный TypeScript и ESLint новых файлов прошли. Production frontend прошёл в 11Б.3.3.3; этот блок добавляет пока не подключённый модуль, UI/backend не менялись.
  • Current UI всё ещё использует старые settings calls. Нельзя считать формы подтверждёнными или защищёнными от default submit по этим unit: подключение readers/known/error/time/dirty states, synchronous locks, RBAC и unknown mutation receipt ещё впереди. Generic CollectorSettingsDto на странице ошибочно требует retention у REST ping; при подключении исправить типы по отдельным DTO.
  • Следующий блок 11Б.3.3.5: подключить четыре strict settings reader и существующий certificate reader, независимые состояния/свежесть и dirty drafts; затем операции/права/source E2E. Evolution malformed snapshot crash и GeoIP/NetFlow формы остаются в scope 11Б.
  • На контрольной точке недельный лимит использован на 99%, пятичасовой на 36%. Проверенные блоки сохранены; для продолжения читать текущую квоту и этот журнал.

Блок 11Б.3.3.4.1 — проверка каталога Evolution (2026-10-01)

  • Каталог Evolution проверяется до записи в состояние: обязательные коллекции, поля строк, дата снимка, числовые счётчики и уникальность идентификаторов. Неполный HTTP 200 больше не обрушает боковую навигацию; в настройках EvoBGP отображается понятная ошибка.
  • Подтверждённые пустые коллекции, false и zero сохраняются. Decoder совместим с DTO backend; неизвестные значения backend не переосмыслены. Последний снимок при ошибке пока не сохраняется: независимые состояния, свежесть и защита от гонок Evolution остаются в объёме этапа.
  • Прошли 3 unit, 1 браузерный тест через обычные API-пути с подменой HTTP, ESLint изменённых файлов и production frontend/contracts build со встроенным TypeScript. В браузере проверены доступность журнала, переход в настройки EvoBGP и отсутствие pageerror при malformed каталоге. Реальный Evolution Portal не проверен.
  • Следующий основной блок остаётся 11Б.3.3.5: подключение strict settings readers, независимые known/error/time и dirty drafts. Также выявлено: Evolution testConnection пока принимает любой успешный HTTP вместо подтверждения ok=true; исправление и профильная проверка ещё впереди.
  • На завершении пятичасовой лимит использован на 42%, недельный показывает 100%. Новый блок не начат; изменения сохранены локально без push.