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

17 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 и операции.