fix(uptime): отличать ошибки опроса от измеренных потерь Ping

This commit is contained in:
Denozordec committed 2026-10-12 17:55:16 +07:00
1 parent ca23284486
commit 8fb46b1552
35 files changed
+1582 -78

No files matched your search

+27 -2
View File
@@ -1,6 +1,6 @@
# UX/UI: протокол внешней приёмки 12.5
Актуальное продолжение 2026-10-12: завершён12.5.172 — monitoring history использует общие confirmed collector facts внутри readonly transaction; disabled/stale/error/unknown не поднимают raw samples. Старый backend реально показывал disabled/hour-old sample; Date schema failure не воспроизведён. OwnSQL26+GRE8/stability/source437/compiled1020/build/4E2E/2live UI passed; own DB/roles removed. Backend ux-history172 healthy, frontend ux-targets171 прежний, оба CHR selected API200. Следующий173 — различить ошибку выполнения Ping и измеренные потери: producer catch пишет100%, guard пока принимает ok=false down;12.5 открыт.
Актуальное продолжение 2026-10-12: завершён12.5.173 — Ping execution error/empty payload не считается100% loss: measurement_known/error provenance, nullable unknown API/UI, scheduled/manual/after-BT, malformed/zero/inconsistent count guards.85 unique E2E initial83+delta3, ownSQL26+Ping8+GRE8/stability, source440+518/compiled1020/build passed. Migration0010 applied; оба ux-ping173 healthy/running; real CHR Ping4/4 both/0%/53ms, config/password unchanged. Own DB/role removed. Следующий174 — audit first-wave/invalid traffic rate confidence; legacy unclassified manual samples и source unconfirmed diagnostics остаются;12.5 открыт.
IPsec78: реальный PSK responder established, mode-config198.18.78.10 и online=true подтверждены API; точные собственные объекты удалены. Сертификатный/DN online, late failure и history restore остаются открытыми. [Отчёт](ux-ui/acceptance/ipsec-mode-config-2026-10-09.json), [журнал](ux-ui-progress.md).
@@ -696,7 +696,7 @@ flowchart LR
## 12.5.77 — основной блок IPsec (2026-10-09)
Актуальное продолжение 2026-10-12: завершён12.5.172 — monitoring history использует общие confirmed collector facts внутри readonly transaction; disabled/stale/error/unknown не поднимают raw samples. Старый backend реально показывал disabled/hour-old sample; Date schema failure не воспроизведён. OwnSQL26+GRE8/stability/source437/compiled1020/build/4E2E/2live UI passed; own DB/roles removed. Backend ux-history172 healthy, frontend ux-targets171 прежний, оба CHR selected API200. Следующий173 — различить ошибку выполнения Ping и измеренные потери: producer catch пишет100%, guard пока принимает ok=false down;12.5 открыт.
Актуальное продолжение 2026-10-12: завершён12.5.173 — Ping execution error/empty payload не считается100% loss: measurement_known/error provenance, nullable unknown API/UI, scheduled/manual/after-BT, malformed/zero/inconsistent count guards.85 unique E2E initial83+delta3, ownSQL26+Ping8+GRE8/stability, source440+518/compiled1020/build passed. Migration0010 applied; оба ux-ping173 healthy/running; real CHR Ping4/4 both/0%/53ms, config/password unchanged. Own DB/role removed. Следующий174 — audit first-wave/invalid traffic rate confidence; legacy unclassified manual samples и source unconfirmed diagnostics остаются;12.5 открыт.
Подробный объём, протоколы, схема и ограничения: [12.5.77 в журнале](ux-ui-progress.md).
@@ -1948,3 +1948,28 @@ Source/build/unit/ESLint прошли. Локальные alert-engine и12 ск
Протоколы: [first baseline hypothesis](ux-ui/acceptance/monitoring-history-baseline-attempt-2026-10-12.json), [real baseline](ux-ui/acceptance/monitoring-history-baseline-2026-10-12.json), [SQL26/cleanup](ux-ui/acceptance/monitoring-history-sql-2026-10-12.json), [source437](ux-ui/acceptance/monitoring-history-source-2026-10-12.json), [compiled1020](ux-ui/acceptance/monitoring-history-compiled-2026-10-12.json), [runtime](ux-ui/acceptance/monitoring-history-runtime-2026-10-12.json), [API/UI](ux-ui/acceptance/monitoring-history-deployed-2026-10-12.json).
Следующий173 — source finding: collectPingProbesOnce/pingProbesNow catch превращает ошибку REST-команды в lossPct100/down; decoder пока разрешает ok=false/down/null/100. Это не независимое доказательство потери пакетов. Проверить и исправить подтверждение измерений/empty payload; не объявлять legacy raw UI stats и manual provenance уже исправленными. Также остаются unconfirmed/missing target diagnostics, stable-ID migration, scale/multi-instance/physical WAN и внешние Telegram/Portal/client OS.12.5 открыт. Локальный коммит без push.
## 12.5.173 — ошибка Ping не подменяет измеренные потери (2026-10-12)
Завершён целый раздел producer→SQL→API→UI. parsePing теперь возвращает measured: empty/unsupported replies, zero sent и противоречивые/malformed counts не подтверждают процент потерь. Подтверждённые received0/sent4 остаются100%/down с RTTnull; успешный настоящий RTT0/loss0 сохранён. Scheduled и manual collectors различают успешное измерение и ошибку REST/недостаточный ответ; after-bandwidth Ping при неизвестном результате возвращает null metrics/error, а не выдуманный outage. Alert decoder принимает только ok=true и известное состояние; retained legacy ok=false/down/100 не срабатывает как измеренная потеря. Malformed due-probe rows без ID — barrier, не разрешение восстановить старое измерение.
Миграция0010 добавляет uptime_probe_samples.measurement_known boolean defaulttrue и observation_error text; CHECK/legacy storage status и integer loss не ломаются. Raw100/down в failed rows — прежние storage sentinel с явным measurement_known=false, не публичное измерение. Snapshot/public observations/API loss становятсяnull/statusunknown, есть причина ошибки. Новые flags пишутся при scheduled и manual error/empty response. Старые scheduled failure samples переклассифицируются readonly по точному probeId+sampledAt retained v1 JSON provenance; genuine100% без failure flag не меняется. Старые manual/retention-lost failures без provenance надёжно восстановить нельзя: они остаются legacy ambiguity, полного historical cleanup не заявляем. Migration additive, прошлые данные не удаляет; source JSON internal v1 теперь допускает nullable loss/unknown. Для rollback старый код не интерпретирует measurement_known, поэтому совместимость хранения не означает корректное чтение новых unknown attempts старой версией.
Overview выдаёт unknown/null без fallback100/down и без padded historical0. Observations timestamps канонизированы; parser проверяет согласованность unknown/null. /uptime использует тот же observed decoder, что dashboard: «Нет данных», — для RTT/loss, причина execution error, отдельный filter/URLstatus=unknown. Новая draft probe тоже не объявляется заранее up/0. Мини-Sparkline сохраняет gaps; expanded RTT chart больше не превращаетnull в0 и не дублирует одиночную точку для выдуманной линии. Dashboard status tooltip получает причину. Source/speed-interface read endpoints теперь409 до RouterOS при disabled server; ошибочная подпись «для ping всё равно можно выбрать выключенный» исправлена. Это соответствует прямому правилу пользователя не опрашивать выключенные устройства любых типов. UI/ReUI primitives/theme не заменены.
| Состояние | Эталон | Результат |
| --- | --- | --- |
| Ошибка REST/нет измерения | Существующие probe rows/StatusDot/Sparkline | [ПК1440](ux-ui/screens/ping-measurement-unknown-1440-2026-10-12.png), [телефон320](ux-ui/screens/ping-measurement-unknown-320-2026-10-12.png) — API-fixture, не production positive sample |
| Подтверждённые100% | Тот же public observed path | Down и100% сохранены отдельным positive control |
Unit parser/observations/frontend dashboard-probes/URL guards прошли; backend build, application-source TypeScript и ESLint прошли (в uptime-collector два прежних unused settings warnings, functional scope не расширен). Первый npm --prefix exec взял неверный cwd, повтор direct tsx корректен; новый тест сначала использовал неверное имя Zod package, исправлен на установленный @fastify/type-provider-zod. Local cancellation test получил sandbox EACCES, разрешённый сетевой профиль прошёл; local own SQL skipped без выделенной базы.85 unique E2E Uptime/Ping/Speed: initial83passed/2failed были новые ambiguous test selectors (имя есть в sidebar и строке); selector исправлен на конкретную причину ошибки, delta3passed9.5s. Existing83 scenarios повторно не запускались;2 screenshot captures passed8.5s отдельно. Это не85 clean single-run и не87 новых сценариев. Два перезаписанных тестами прежних speed images восстановлены SHA256;8 user dirty GRE/VXLAN images не тронуты. Новые снимки просмотрены, nullable состояние читаемо при320px.
Owned Node22/PG18.6 профили alert-engine+probes прошли42380ms:26 source/history SQL cases, GRE/BGP8/actual stability и8 новых Ping cases. Последние проходят через реальный MikrotikClient HTTP к loopback simulator, persisted flags, GET overview Fastify path:401,empty,manual,real loss/zero,API,legacy exact provenance и disabled no-outbound requests. Simulator не является физическим RouterOS/network failure. Финальные unit guards zero/inconsistent counts/malformed probe проверены перед scoped rerun; temporary DB/role/container удалены. Production credentials/JWT не копировались. Type/producer tests подключены к стандартному test:probes; default profile count не увеличен.
Source440 backend+518 frontend inputs/1020 emitted parity совпали SHA256. Both production builds passed, backend image включает новый drizzle0010. Staged deploy: frontend ux-ping173 сначала принял старый API ux-history172, затем backend ux-ping173/version1.0.0-test.ping173. Migration0010 и2 новых columns подтверждены readonly в main PG. Backend/PG healthy, frontend running/HTTP/UI, imageIds verified, running containers3. В.env менялись толькоimage tags; rollback tags сохранились отдельно без secret env копии. Cached прежний frontend следует перезагрузить: новые nullable/unknown DTO требуют совместимого reader.
Независимо выполнен настоящий native Ping4 packets194.226.121.150→104.165.244.7 иобратно через running compiled173: обе команды приняты, обе4/4,0%loss, parsed RTT53ms. Это короткое наблюдение, не WAN SLA/max throughput. Main DB read-only, native конфигурация/пароли не менялись;2 operational Ping commands, routerConfigWrites0/messages0. На production configured probes0:2live UI1440/320 подтверждают actual empty catalog/new filter/reader/overflow/pageerrors0; nonempty/error UI доказан fixtures, не выдан за main positive measurement. Collector row/error flags проверены ownSQL, real parser отдельно native payloads.
Протоколы: [SQL/HTTP8+cleanup](ux-ui/acceptance/ping-measurement-sql-2026-10-12.json), [native4/4](ux-ui/acceptance/ping-measurement-native-2026-10-12.json), [source](ux-ui/acceptance/ping-measurement-source-2026-10-12.json), [compiled](ux-ui/acceptance/ping-measurement-compiled-2026-10-12.json), [interop](ux-ui/acceptance/ping-measurement-interop-2026-10-12.json), [runtime](ux-ui/acceptance/ping-measurement-runtime-2026-10-12.json), [live UI](ux-ui/acceptance/ping-measurement-deployed-2026-10-12.json).
Следующий174 — audit first-wave/invalid traffic rate confidence: ok request и numeric sum не всегда доказывают измеренный rate без previous wave. Не заявлять эту гипотезу как уже выполненное исправление. Source unconfirmed/missing target diagnostics, manual history provenance, unsupported/compound time formats, legacy ambiguous samples, scale/multi-instance/physical WAN/external integrations остаются отдельными условиями12.5. Полная acceptance открыта. Локальный коммит без push.