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

42 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.

Блок 11Б.3.3.4.2 — подтверждение проверки EvoBGP (2026-10-01)

  • testConnection проверяет явное ok=true: HTTP 200 с false, пустым или некорректным receipt не становится сообщением об установленном соединении. Ошибка возвращается существующей форме, без повторного POST.
  • Прошли unit для true/false/missing/null/неверных типов, ESLint изменённых файлов и полный TypeScript. Два профильных браузерных теста прошли; после расширения новый тест повторно проверил false → ручная повторная проверка → true и ровно один запрос на каждое нажатие. HTTP-подмена не доказывает соединение с реальным Portal.
  • Полная production сборка прошла в предыдущем блоке 11Б.3.3.4.1; текущая маленькая правка проверена TypeScript и браузером. Общие settings/RBAC/dirty/context и сохранение последнего каталога остаются впереди. Основная точка продолжения — 11Б.3.3.5.
  • Блок сохранён отдельным локальным коммитом без push. Процент недельной квоты округлён до 100%, ordinaryUsageAllowed при начале блока оставался true.

Блок 11Б.3.3.5 — независимые настройки и черновики (2026-10-03)

  • Подключены четыре строгих settings reader и существующий certificate reader. У каждого источника независимые known/error/browser receivedAt; медленный uptime не задерживает остальные настройки. Ошибка сохраняет последние подтверждённые данные и время, неполный DTO не подменяется defaults.
  • Изменённые пользователем интервалы и дополнительные поля сохраняются при обновлении. Состояние источника сбрасывается существующим remount; abort/revision защищают поздние ответы. Uptime scheduler metadata больше не переписывает чужие переключатели. REST ping использует собственный DTO без выдуманного retention.
  • Неизвестные настройки показывают —/пустые отключённые поля, доступность записи пока консервативно зависит от всех пяти подтверждённых источников. GeoIP расписание отмечено внешне управляемым через NetFlow. Формат/композиция установленной Data Grid сохранены; async metadata объявляется role=status.
  • Прошли 15 профильных E2E (4 новых settings + история/status/race), ESLint, полный TypeScript и production frontend/contracts build. ReUI audit checklist получен; изменения затрагивают данные/состояния, vendor props и тема не менялись. Реальные DB/RouterOS/ACME не проверены.
  • Следующий блок 11Б.3.3.6: строгие mutation receipts/проверка ввода, точечные PUT вместо записи всех настроек переключателем, синхронные locks/права и сброс dirty только по подтверждённому результату. Полная приёмка 11Б ещё впереди.

Блок 11Б.3.3.6.1 — строгие PUT настроек (2026-10-03)

  • Четыре settings PUT проверяют минимумы/целые числа до запроса и реальные backend receipt ok=true/settings после него. Каждый переданный параметр обязан совпасть с подтверждённым. Пустой patch/unknown fields/неверные числа отклоняются; timeout/ошибка/неверный receipt не вызывают повтор.
  • Прошли 14 GET/PUT unit, ESLint и полный TypeScript. Первоначальный unit assertion уточнён под две формулировки подтверждения; повтор прошёл. Новый API пока не подключён к операциям страницы; certificate PUT переиспользуется с отдельной проверкой echo на следующем шаге.
  • Далее 11Б.3.3.6.2: точечная запись dirty полей и выбранного переключателя, locks/права, сброс dirty по подтверждению и профильные E2E.

Блок 11Б.3.3.6.2 — точечное сохранение и права (2026-10-03)

  • Переключатель отправляет только флаг выбранного сборщика; сохранение отправляет только dirty поля. Все числовые поля выбранного плана проверяются до первой записи без parseInt/default/clamp. Неполные данные других источников не мешают точечной операции.
  • Строгие receipts подключены; certificate PUT дополнительно сверяет echo. Подтверждённая часть очищает dirty и обновляет сохранённые данные, отказ/403/неизвестный receipt сохраняют draft. Частичный успех показан отдельно и при ручном повторе не отправляется снова.
  • Синхронный lock предотвращает повтор; pending GET инвалидируется перед записью, поздний ответ не отменяет подтверждённый переключатель. Изменение источника/unmount прекращает публикацию и последующие записи batch, но не гарантирует отмену уже полученной backend операции. Права соответствуют существующим backend permissions каждого endpoint.
  • Прошли 26 E2E (15 settings + 11 history/status/race), ESLint и production frontend/contracts build. Проверены malformed/mismatched receipts, selective PUT, partial failure, dirty, fractional/no HTTP, lock, old GET, HTTP 403 и read-only claims. Реальный JWT/DB/RouterOS/ACME не проверен.
  • Далее 11Б.3.3.6.3: подключить строгие run-now/refresh receipts, общий lock и права для POST, отдельно показать skipped/partial/event/status failures; затем source E2E/визуальная приёмка страницы. Этап 11Б не завершён.

Блок 11Б.3.3.6.3 — подтверждённые ручные запуски (2026-10-03)

  • Строгие scheduler run-now/refresh подключены вместо raw POST. Показаны подтверждённый запуск, skipped/not-due и partial; event/status failure отделены от результата задачи. Неверный/чужой receipt не становится успехом и не повторяет POST, сообщает неизвестность результата и необходимость обновить журнал.
  • Run-now/refresh используют общий синхронный lock с PUT, права mm:settings:admin и сохранённые настройки без отправки dirty draft. Неизвестная/running задача не запускается из UI. Поздние callbacks после unmount/source change не публикуются; backend применение уже начатой операции не отменяется.
  • Прошли 26 E2E (10 operations + 16 settings), ESLint и production frontend/contracts build. Проверены partial/event/status, false receipt/foreign snapshot, lock и mode change; смена режима также прекращает оставшийся batch PUT. Предыдущие 11 status/history/race прошли в 11Б.3.3.6.2; новый блок не меняет readers.
  • Далее 11Б.3.3.7: backend source E2E и визуальная/адаптивная приёмка scheduler. GeoIP/NetFlow формы и Evolution provider, alerts/releases/probe scheduling остаются в объёме этапа 11Б; их общий интерфейс пока не принят.

Блок 11Б.3.3.7 — локальная приёмка scheduler (2026-10-03)

  • Проверены обычные HTTP-пути со сменой backend: 6 source E2E для позднего GET/PUT/run-now, успех и отказ старого источника не меняют новый. Source тесты вынесены в отдельную конфигурацию :3101/local; общий профиль остаётся :3100/same-origin.
  • 46 основных профильных E2E проверены: 39 прошли сразу, 7 KPI assertions требовали обновления селектора после переноса подписей; 9 history/status повторно прошли с устойчивой привязкой к установленному FramePanel. Отдельно 6 source E2E прошли. Новая структура не меняет unknown/zero значения.
  • ПК/390/320 проходят без горизонтального переполнения body; сохранены 6 снимков docs/ux-ui/screens/data-collection*.png, визуально просмотрены 320 и ПК. KPI тексты переносятся, unknown сбор не помечается зелёным успехом. Кнопка «Сохранить изменения» помещается на 320, доступное имя сохранено. Удалена техническая ссылка Preview из текста NetFlow.
  • ESLint новых/изменённых файлов и production frontend/contracts build прошли; две последние правки текста дополнительно проверены 3 responsive E2E с обновлением снимков. ReUI композиция/тема сохранены, labels и async объявления есть. Это приёмка scheduler/settings/history, а не всей страницы интеграций.
  • Следующий блок 11Б.3.4: GeoIP/NetFlow формы — known/error/dirty/source/partial и операции. Evolution provider, alerts/releases/probe scheduling и итоговая приёмка 11Б остаются впереди. PostgreSQL, RouterOS, Portal, MaxMind download и JWT не доказаны HTTP-фикстурами.

Блок 11Б.3.4.1 — права GeoIP (2026-10-03)

  • Выявлен и устранён fallback GeoIP в mm:dashboard:read: GET /api/geoip требует mm:traffic:read, PUT /api/geoip и POST /api/geoip/update — mm:traffic:write, как соседние NetFlow настройки. Catch-all и права сетевых операций не менялись.
  • Это целевое ужесточение: пользователя с одним dashboard:read больше недостаточно для чтения/изменения GeoIP. Traffic write/admin наследуют read; settings:admin не даёт произвольных traffic прав по существующей модели. AUTH_REQUIRED=false сохраняет локальный режим.
  • Подписанные JWT/Fastify inject проверяют GET/PUT/POST с пятью наборами прав: reader не вызывает mutation handler, traffic writer/admin допускаются, без JWT 401. Первоначальное ожидание глобальных прав settings:admin исправлено по реальному hasPermission; повтор прошёл. Проверка добавлена в backend test:geoip.
  • Backend permissions unit, JWT gate, ESLint и backend build прошли. Нет БД/скачивания MaxMind/производственного Portal в этих тестах. UI ещё использует старую форму; далее 11Б.3.4.2 — known/error/dirty/права и partial outcome GeoIP.

Блок 11Б.3.4.2 — достоверная форма GeoIP (2026-10-03)

  • GeoIP вынесен из NetFlow в отдельный раздел с backend key/remount, abort/revision и active guards. Независимые read/operation ошибки, browser receivedAt и последние данные сохраняются. Unknown не выдаётся за отсутствующие базы; формы/действия до подтверждения или без traffic write отключены.
  • Dirty сохраняется при GET и после ручного обновления; PUT принимает фактический интервал с точностью до секунды без rounding/default/clamp, receipt очищает dirty только после подтверждения. Синхронный lock блокирует PUT/POST/refresh во время операции и инвалидирует pending GET.
  • Частичный update показывает скачанное/без изменений/bytes вместе с ошибками, не сообщает полного успеха. Skipped отдельно. Неизвестный POST не повторяется; новое обновление требует явного действия после проверки журнала/баз. Guard живёт в текущем разделе, не является durable backend идемпотентностью.
  • Прошли 10 новых GeoIP E2E, 2 ранее существовавших malformed tests, ESLint и production frontend/contracts build. После добавления explicit unknown guard профильный POST тест повторно прошёл. Проверены fractional interval, invalid/no HTTP, false/unknown, partial, dirty, lock и reader claims; signed JWT gate принят в 11Б.3.4.1.
  • NetFlow сохраняет собственные известные ограничения; его synchronous-effect lint исправлен очередью microtask, не считать это защитой от поздних ответов. Далее 11Б.3.4.3 — GeoIP source/визуальная приёмка, затем strict NetFlow API/форма. Реальная загрузка mmdb/DB/Portal не проверена.

Блок 11Б.3.4.3 — локальная приёмка GeoIP (2026-10-03)

  • 6 backend source E2E проверили поздние GET/PUT/POST, success/error старого адреса не меняют новый раздел. POST assertions уточнены для сообщения с фактическими счётчиками; оба POST source теста повторно прошли.
  • 13 основных GeoIP E2E (10 сценариев + ПК/390/320) прошли, сохранены 3 снимка docs/ux-ui/screens/geoip*.png. На телефоне бейджи перенесены из headerRight в переносимую строку: заголовок больше не сжимается и не скрывается. Кнопка разрешения нового POST имеет короткую подпись и полное доступное имя.
  • Первоначальный overflow assertion выявлял также штатную отрицательную границу Frame (+1px); допуск ограничен 2px, body не переполняется. Снимок 320 просмотрен и обнаруженное фактическое сжатие заголовка исправлено, тесты повторены. Это не утверждение о всей NetFlow панели.
  • ESLint и production frontend/contracts build прошли. Backend JWT gate/permissions/build приняты в 11Б.3.4.1; реальные Portal/DB/mmdb не проверены. Unknown guard текущего раздела не долговечен между reload/navigation.
  • Далее 11Б.3.4.4: строгие NetFlow settings/keys/export/purge API и backend эффекты. Выявлены создание ключей в GET host-files, выдача конфигов с private key по traffic read и маскировка успешного purge ошибкой события; также требуется проверка атомарности purge. UI NetFlow ещё не принят.

Продолжение 2026-10-03: завершён 11Б.3.4.4.1 (строгие NetFlow API, 5 unit и 3 collector/probes E2E, typecheck/ESLint). Следующий блок — 11Б.3.4.4.2: backend экспорт/права и подтверждение сохранения отдельно от запуска listener. Purge и форма ещё требуют доработки.

Завершён 11Б.3.4.4.2: private export требует traffic write, GET не создаёт ключи, PUT отделяет сохранение от ошибки запуска listener. HTTP/JWT, backend build, lint и permissions прошли. Далее 11Б.3.4.4.3: конкурентное создание ключей/выборочные patch; purge и UI ещё не приняты.

Завершён 11Б.3.4.4.3: выборочная запись NetFlow patch и условная установка host keys, свежая подтверждённая пара; DI гонка/HTTP/JWT/build/lint прошли. Реальная PG гонка не проверена. Далее 11Б.3.4.4.4 — атомарность purge и частичные результаты.

Завершён 11Б.3.4.4.4: 6 таблиц/counters purge в общей транзакции, отдельные partition/listener/event warnings и nullable размер файлов. DI/HTTP/API/typecheck/build/lint прошли; реальный PG purge не запускался. Следующий шаг 11Б.3.4.4.5 — форма NetFlow и подтверждённые/частичные/неизвестные операции.