fix(uptime): объяснить неизвестный результат теста скорости
This commit is contained in:
1 parent
dbe1e7c917
commit
5944e5e751
13 files changed
+190
-24
No files matched your search
@@ -28,12 +28,22 @@ missing = true; assert.equal((await send(base)).statusCode, 404); assert.equal(c
|
||||
for (const [error, code] of [[new SpeedProbeEndpointsChanged(), 409], [new SpeedProbeContextChanged(), 409], [Error("На интерфейсе назначения нет активного IP"), 400], [Error("Server not found"), 400], [Error("authentication failed"), 502], [Error("socket hang up"), 502]] as const) {
|
||||
problem = error; const response = await send({ ...base, runId: "failed", direction: "transmit", durationSec: 20 }); assert.equal(response.statusCode, code); assert.equal(failures.at(-1)?.runId, "failed"); assert.equal(failures.at(-1)?.durationSec, 20); assert.equal(failures.at(-1)?.direction, "transmit")
|
||||
}
|
||||
const beforeUnknown = { runs: commands.length, failures: failures.length }
|
||||
for (const transport of ["Connection timed out after 30s", "socket hang up", "read ECONNRESET"]) {
|
||||
problem = Error(transport)
|
||||
const response = await send({ ...base, runId: "transport-failed" })
|
||||
assert.equal(response.statusCode, 502)
|
||||
assert.match(response.json().error, /Результат теста скорости неизвестен/)
|
||||
assert.doesNotMatch(response.json().error, /socket|ECONNRESET|timed out/)
|
||||
assert.equal(failures.at(-1)?.message, transport)
|
||||
}
|
||||
problem = Error("RouterOS отклонил авторизацию bandwidth-test")
|
||||
assert.equal((await send(base)).json().error, problem.message)
|
||||
const beforePersistenceUnknown = { runs: commands.length, failures: failures.length }
|
||||
problem = new SpeedRunPersistenceUnknown("actual-run-id")
|
||||
const unknown = await send(base)
|
||||
assert.equal(unknown.statusCode, 502); assert.equal(unknown.json().outcome, "unknown")
|
||||
assert.equal(unknown.json().runId, "actual-run-id"); assert.match(unknown.json().error, /сохранение результата не подтверждено/)
|
||||
assert.equal(failures.length, beforeUnknown.failures); assert.equal(commands.length, beforeUnknown.runs + 1)
|
||||
assert.equal(failures.length, beforePersistenceUnknown.failures); assert.equal(commands.length, beforePersistenceUnknown.runs + 1)
|
||||
await app.close(); console.log("Speed-test HTTP:26 invalid inputs; explicit persistence unknown/runId skips failure write and command retry")
|
||||
process.env.AUTH_REQUIRED = "true"; process.env.AUTH_JWT_SECRET = "speed-command-test-secret"; process.env.AUTH_ISSUER = "https://auth.test.local"; process.env.NODE_ENV = "test"
|
||||
const { default: authPlugin, requireAuth } = await import("../plugins/auth.js")
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { FastifyPluginAsyncZod } from "@fastify/type-provider-zod"
|
||||
import { speedTestCommandSchema, type SpeedTestCommand } from "@mmapp/contracts"
|
||||
import type { SpeedTestRunResult } from "../services/uptime-speed-service.js"
|
||||
import { SpeedProbeContextChanged, SpeedRunPersistenceUnknown } from "../services/speed-run-persistence.js"
|
||||
import { speedRunErrorMessage } from "../services/speed-run-error-message.js"
|
||||
|
||||
export function createSpeedTestRoute(deps: {
|
||||
serverExists: (id: number) => Promise<boolean>
|
||||
@@ -23,9 +24,7 @@ export function createSpeedTestRoute(deps: {
|
||||
}
|
||||
const raw = error instanceof Error ? error.message : "Bandwidth test failed"
|
||||
await deps.failure({ ...command, message: raw })
|
||||
const message = /timed out|socket hang up|ECONNRESET/i.test(raw)
|
||||
? "BTTest timeout/socket hang up: проверь доступность destination, /tool bandwidth-server, firewall и корректность интерфейсов"
|
||||
: raw
|
||||
const message = speedRunErrorMessage(raw)
|
||||
if (error instanceof SpeedProbeContextChanged) return reply.code(409).send({ error: message })
|
||||
if (/активного IP|Server not found/i.test(raw)) return reply.code(400).send({ error: message })
|
||||
return reply.code(502).send({ error: message })
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
/** A lost transport receipt cannot establish whether RouterOS completed the test. */
|
||||
export function speedRunErrorMessage(raw: string): string {
|
||||
return /timed out|socket hang up|ECONNRESET/i.test(raw)
|
||||
? "Результат теста скорости неизвестен: ответ устройства не получен. Проверьте его состояние перед повторным запуском."
|
||||
: raw
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import { parsePing } from "./uptime-collector.js"
|
||||
import { assertBandwidthTestCompleted } from "./bandwidth-test-status.js"
|
||||
import { assertSpeedProbeContext, persistSpeedRun, SpeedRunPersistenceUnknown, type SpeedProbeContext } from "./speed-run-persistence.js"
|
||||
import { readBandwidthTestRates } from "./bandwidth-test-rates.js"
|
||||
import { speedRunErrorMessage } from "./speed-run-error-message.js"
|
||||
|
||||
type SpeedWriteTransaction = Parameters<Parameters<typeof db.transaction>[0]>[0]
|
||||
function speedProbeContextWhere(target: SpeedProbeContext) {
|
||||
@@ -73,12 +74,6 @@ export interface SpeedTestRunResult {
|
||||
}
|
||||
}
|
||||
|
||||
function humanizeSpeedError(raw: string): string {
|
||||
return /timed out|socket hang up|ECONNRESET/i.test(raw)
|
||||
? "BTTest timeout/socket hang up: проверь доступность destination, /tool bandwidth-server, firewall и корректность интерфейсов"
|
||||
: raw
|
||||
}
|
||||
|
||||
/** Полный цикл bandwidth-test + after-ping + запись в БД. Вызывать внутри withBtestNodeLocks при необходимости — здесь lock уже снаружи. */
|
||||
export async function executeBandwidthSpeedTestInner(params: SpeedTestRunParams): Promise<SpeedTestRunResult> {
|
||||
const probeId = String(params.probeId ?? "").trim()
|
||||
@@ -232,7 +227,7 @@ export async function recordSpeedTestFailure(params: {
|
||||
message: string
|
||||
}) {
|
||||
const probeId = String(params.probeId ?? "").trim()
|
||||
const message = humanizeSpeedError(params.message)
|
||||
const message = speedRunErrorMessage(params.message)
|
||||
await persistSpeedRun<SpeedWriteTransaction, SpeedProbeContext>(probeId ? {
|
||||
id: probeId, srcServerId: params.srcServerId, dstServerId: params.dstServerId,
|
||||
srcInterface: String(params.srcInterface ?? "").trim(), dstInterface: String(params.dstInterface ?? "").trim(),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# UX/UI: протокол внешней приёмки 12.5
|
||||
|
||||
Актуальное продолжение 2026-10-10: завершены12.5.93–97. Реальный HTTP receipt disconnect после передачи короткой bandwidth команды: API502/error history, предыдущие snapshots сохранены, native1/noauto retry, independent native done и UI2/2. Own DB fixtures удалены. Следующий12.5.98 — заменить техническое timeout/socket сообщение понятным пояснением неизвестного native результата, профильная проверка/deploy; затем общая регрессия. Runtime backend ux-diagnostics89/frontend ux-ospf91. Этап12.5 открыт.
|
||||
Актуальное продолжение 2026-10-10: завершены12.5.93–98. На стенде backend ux-speed98/frontend ux-ospf91; неизвестный native результат при transport loss теперь явно объяснён одинаково в API/history/UI, live2/2. Собственные fixtures очищены, credentials не менялись. Следующий12.5.99 — общая backend/main/context регрессия; backend/main уже запущены и пока не объявлены прошедшими. Актуальная внешняя матрица docs/ux-ui-remaining-acceptance.md; этап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).
|
||||
|
||||
@@ -700,7 +700,7 @@ flowchart LR
|
||||
|
||||
## 12.5.77 — основной блок IPsec (2026-10-09)
|
||||
|
||||
Актуальное продолжение 2026-10-10: завершены12.5.93–97. Реальный HTTP receipt disconnect после передачи короткой bandwidth команды: API502/error history, предыдущие snapshots сохранены, native1/noauto retry, independent native done и UI2/2. Own DB fixtures удалены. Следующий12.5.98 — заменить техническое timeout/socket сообщение понятным пояснением неизвестного native результата, профильная проверка/deploy; затем общая регрессия. Runtime backend ux-diagnostics89/frontend ux-ospf91. Этап12.5 открыт.
|
||||
Актуальное продолжение 2026-10-09: 12.5.77 завершил укрупнённый основной блок IPsec: достоверное чтение, запрет опроса выключенных устройств, совместимый RouterOS7 мастер, раздельные ID клиентов, безопаснее удаление, URL устройства/вкладки, Docker обеих частей и реальная приёмка. Local30/30 + context6/6 + backend67, live browser4/4, PSK и сертификатный защищённый GRE/Ping3/3 на двух CHR; cleanup/DB controls passed. Runtime backend/frontend ux-ipsec77, version1.0.0-test.ipsec77. Следующий12.5.78 — остаточная профильная приёмка IPsec: сопоставление active-peer/online, выдача mode-config, поздние ошибки операций и история восстановления; затем маршрутизация. Этап12.5 открыт.
|
||||
|
||||
Подробный объём, протоколы, схема и ограничения: [12.5.77 в журнале](ux-ui-progress.md).
|
||||
|
||||
@@ -925,3 +925,13 @@ API502, history error/TXRX/Pingnull, probe error с прежними42/17/15/0;
|
||||
Свои history/probe exact IDs удалены, исходные списки совпали, только3 compose containers/backend/PG healthy. Один короткий capped native запуск с первой попытки, без RouterOS configuration/account changes/build/deploy. Native команда не отменялась; physical WAN failure/abort/multi-instance locks не приняты. Lab AUTH_REQUIRED=false, rights не проверялись повторно. HTTP ошибка приложения не доказывает failure native команды.
|
||||
|
||||
Обнаружено оставшееся UX ограничение: timeout/socket message техническая и не объясняет неопределённость native результата. Следующий98 — единый понятный transport error для HTTP/history, профильные tests и один backend build/live повтор только изменённого message path; затем общая регрессия на согласованном runtime. Этап12.5 открыт. Один локальный коммит без push.
|
||||
|
||||
## 12.5.98 — понятный неизвестный результат теста скорости (2026-10-10)
|
||||
|
||||
После реального lost receipt97 техническое сообщение заменено единым speedRunErrorMessage для HTTP и сохраняемой истории: «Результат теста скорости неизвестен: ответ устройства не получен. Проверьте его состояние перед повторным запуском». Timeout/socket hang up/ECONNRESET не означают доказанный native failure. Известный отказ авторизации и остальные конкретные ошибки сохраняются; неизвестное сохранение PG остаётся отдельным outcome=unknown/runId. HTTP502/history error означают ошибку получения результата приложением; schema/status/автоматический retry не расширялись.
|
||||
|
||||
**Проверки.** Speed-test HTTP validation/persistence/RBAC и дополнительные3 transport cases/известная auth error passed; локальный contracts/backend production build и scoped ESLint passed. Service иroute используют один formatter. [Deployment](ux-ui/acceptance/deployed-speed-message-2026-10-10.json): одна Docker backend сборка из context diagnostics89 +3 working-tree files, package/lockfile неизменны, production tsc/entry/node --check/pg_restore18.6/compose --wait passed. Runtime backend ux-speed98/version1.0.0-test.speed98/image779b0fc010c9…; frontend ux-ospf91 прежний. Label speed98 — блок, не Git SHA. Приватный .env backup сохранён; обновлён только BACKEND_IMAGE_TAG.
|
||||
|
||||
[Native/API/PG](ux-ui/acceptance/speed-message-2026-10-10.json) и [browser](ux-ui/acceptance/browser-speed-message-2026-10-10.json): повторён только изменённый receipt path, одна capped10Mbit/s TCP3s команда, реальное закрытие socket после передачи, native independently done, API/history содержат новое сообщение; прежние синтетические42/17/15/0 сохранены, native1/noauto retry. Live1280/3202/2, сообщение видно в probe card, reload/document fits/pageerror0/UI command POST0. Свои disabled probe/history удалены, исходные IDs совпали, только3 compose containers/backend/PG healthy; RouterOS/credentials не менялись.
|
||||
|
||||
При согласовании указателей94–97 обнаружено, что массовая замена также затронула исторический абзац77 в плане/протоколе. Восстановлен точный абзац из40f730b, история/дата2026-10-09 сохранены; следующие обновления ограничены текущими указателями. Следующий99 — одна общая backend/main/context регрессия на текущем source, с восстановлением исходных доказательств, затем итоговая сводка. General backend/main runs уже запущены, их результат этим блоком не заявлен. Квота23% использовано; этап12.5 открыт. Один локальный commit без push.
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
# План реализации UX/UI по пятичасовым окнам
|
||||
|
||||
Актуальное продолжение 2026-10-10: завершены12.5.93–97. Реальный HTTP receipt disconnect после передачи короткой bandwidth команды: API502/error history, предыдущие snapshots сохранены, native1/noauto retry, independent native done и UI2/2. Own DB fixtures удалены. Следующий12.5.98 — заменить техническое timeout/socket сообщение понятным пояснением неизвестного native результата, профильная проверка/deploy; затем общая регрессия. Runtime backend ux-diagnostics89/frontend ux-ospf91. Этап12.5 открыт.
|
||||
Актуальное продолжение 2026-10-10: завершены12.5.93–98. На стенде backend ux-speed98/frontend ux-ospf91; неизвестный native результат при transport loss теперь явно объяснён одинаково в API/history/UI, live2/2. Собственные fixtures очищены, credentials не менялись. Следующий12.5.99 — общая backend/main/context регрессия; backend/main уже запущены и пока не объявлены прошедшими. Актуальная внешняя матрица docs/ux-ui-remaining-acceptance.md; этап12.5 открыт.
|
||||
|
||||
Общий план проекта MikrotikManager. Основан на согласованном плане из задачи; точка продолжения обновлена 2026-10-10. Источник фактического прогресса, проверок и ограничений — [журнал реализации](ux-ui-progress.md). Этот документ задаёт объём и критерии завершения, журнал фиксирует результат.
|
||||
|
||||
## Актуальная точка продолжения — 2026-10-10
|
||||
|
||||
Актуальное продолжение 2026-10-10: завершены12.5.93–97. Реальный HTTP receipt disconnect после передачи короткой bandwidth команды: API502/error history, предыдущие snapshots сохранены, native1/noauto retry, independent native done и UI2/2. Own DB fixtures удалены. Следующий12.5.98 — заменить техническое timeout/socket сообщение понятным пояснением неизвестного native результата, профильная проверка/deploy; затем общая регрессия. Runtime backend ux-diagnostics89/frontend ux-ospf91. Этап12.5 открыт.
|
||||
Актуальное продолжение 2026-10-10: завершены12.5.93–98. На стенде backend ux-speed98/frontend ux-ospf91; неизвестный native результат при transport loss теперь явно объяснён одинаково в API/history/UI, live2/2. Собственные fixtures очищены, credentials не менялись. Следующий12.5.99 — общая backend/main/context регрессия; backend/main уже запущены и пока не объявлены прошедшими. Актуальная внешняя матрица docs/ux-ui-remaining-acceptance.md; этап12.5 открыт.
|
||||
|
||||
Этапы0–11 завершены в локальных границах журнала. История выполненных внешних блоков и доказательства сохранены в [журнале](ux-ui-stage-12.md) и [протоколе](ux-ui-external-acceptance.md). Реальная Telegram доставка, Portal SSO, multi-instance и оставшиеся профильные сетевые ограничения открыты.
|
||||
|
||||
@@ -371,6 +371,6 @@ flowchart LR
|
||||
|
||||
## 12.5.77 — основной блок IPsec (2026-10-09)
|
||||
|
||||
Актуальное продолжение 2026-10-10: завершены12.5.93–97. Реальный HTTP receipt disconnect после передачи короткой bandwidth команды: API502/error history, предыдущие snapshots сохранены, native1/noauto retry, independent native done и UI2/2. Own DB fixtures удалены. Следующий12.5.98 — заменить техническое timeout/socket сообщение понятным пояснением неизвестного native результата, профильная проверка/deploy; затем общая регрессия. Runtime backend ux-diagnostics89/frontend ux-ospf91. Этап12.5 открыт.
|
||||
Актуальное продолжение 2026-10-09: 12.5.77 завершил укрупнённый основной блок IPsec: достоверное чтение, запрет опроса выключенных устройств, совместимый RouterOS7 мастер, раздельные ID клиентов, безопаснее удаление, URL устройства/вкладки, Docker обеих частей и реальная приёмка. Local30/30 + context6/6 + backend67, live browser4/4, PSK и сертификатный защищённый GRE/Ping3/3 на двух CHR; cleanup/DB controls passed. Runtime backend/frontend ux-ipsec77, version1.0.0-test.ipsec77. Следующий12.5.78 — остаточная профильная приёмка IPsec: сопоставление active-peer/online, выдача mode-config, поздние ошибки операций и история восстановления; затем маршрутизация. Этап12.5 открыт.
|
||||
|
||||
Подробный объём, протоколы, схема и ограничения: [12.5.77 в журнале](ux-ui-progress.md).
|
||||
+12
-2
@@ -1,6 +1,6 @@
|
||||
# UX/UI: журнал реализации
|
||||
|
||||
Актуальное продолжение 2026-10-10: завершены12.5.93–97. Реальный HTTP receipt disconnect после передачи короткой bandwidth команды: API502/error history, предыдущие snapshots сохранены, native1/noauto retry, independent native done и UI2/2. Own DB fixtures удалены. Следующий12.5.98 — заменить техническое timeout/socket сообщение понятным пояснением неизвестного native результата, профильная проверка/deploy; затем общая регрессия. Runtime backend ux-diagnostics89/frontend ux-ospf91. Этап12.5 открыт.
|
||||
Актуальное продолжение 2026-10-10: завершены12.5.93–98. На стенде backend ux-speed98/frontend ux-ospf91; неизвестный native результат при transport loss теперь явно объяснён одинаково в API/history/UI, live2/2. Собственные fixtures очищены, credentials не менялись. Следующий12.5.99 — общая backend/main/context регрессия; backend/main уже запущены и пока не объявлены прошедшими. Актуальная внешняя матрица docs/ux-ui-remaining-acceptance.md; этап12.5 открыт.
|
||||
|
||||
Общий план: [UX/UI по этапам и пятичасовым окнам](ux-ui-plan.md). План задаёт объём, этот журнал фиксирует выполненные блоки и ограничения. Записи расположены от новых к старым; подробная история этапа12 также сохранена в [ux-ui-stage-12.md](ux-ui-stage-12.md).
|
||||
|
||||
@@ -36,7 +36,17 @@
|
||||
| 10 | Маршрутизация, диагностика, карта и терминал | Завершён в границах локальной приёмки 2026-10-01; блоки 10.1–10.71, внешние ограничения в 10.71 |
|
||||
| 11А | Пользователи, контейнеры, сертификаты и резервные копии | Завершён в границах локальной приёмки 2026-10-01; 11А.1–11А.33, внешние ограничения в 11А.33 |
|
||||
| 11Б | Оповещения, сбор данных, интеграции, релизы и настройки | Завершён в границах локальной приёмки 2026-10-03; ограничения и evidence в11Б.7 |
|
||||
| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Локальная приёмка завершена в границах12.3.83; внешняя12.5 в работе, выполненные блоки1–97 и ограничения ниже. Runtime backend ux-diagnostics89/frontend ux-ospf91. |
|
||||
| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Локальная приёмка завершена в границах12.3.83; внешняя12.5 в работе, выполненные блоки1–98 и ограничения ниже. Runtime backend ux-diagnostics89/frontend ux-ospf91. |
|
||||
|
||||
## 12.5.98 — понятный неизвестный результат теста скорости (2026-10-10)
|
||||
|
||||
После реального lost receipt97 техническое сообщение заменено единым speedRunErrorMessage для HTTP и сохраняемой истории: «Результат теста скорости неизвестен: ответ устройства не получен. Проверьте его состояние перед повторным запуском». Timeout/socket hang up/ECONNRESET не означают доказанный native failure. Известный отказ авторизации и остальные конкретные ошибки сохраняются; неизвестное сохранение PG остаётся отдельным outcome=unknown/runId. HTTP502/history error означают ошибку получения результата приложением; schema/status/автоматический retry не расширялись.
|
||||
|
||||
**Проверки.** Speed-test HTTP validation/persistence/RBAC и дополнительные3 transport cases/известная auth error passed; локальный contracts/backend production build и scoped ESLint passed. Service иroute используют один formatter. [Deployment](ux-ui/acceptance/deployed-speed-message-2026-10-10.json): одна Docker backend сборка из context diagnostics89 +3 working-tree files, package/lockfile неизменны, production tsc/entry/node --check/pg_restore18.6/compose --wait passed. Runtime backend ux-speed98/version1.0.0-test.speed98/image779b0fc010c9…; frontend ux-ospf91 прежний. Label speed98 — блок, не Git SHA. Приватный .env backup сохранён; обновлён только BACKEND_IMAGE_TAG.
|
||||
|
||||
[Native/API/PG](ux-ui/acceptance/speed-message-2026-10-10.json) и [browser](ux-ui/acceptance/browser-speed-message-2026-10-10.json): повторён только изменённый receipt path, одна capped10Mbit/s TCP3s команда, реальное закрытие socket после передачи, native independently done, API/history содержат новое сообщение; прежние синтетические42/17/15/0 сохранены, native1/noauto retry. Live1280/3202/2, сообщение видно в probe card, reload/document fits/pageerror0/UI command POST0. Свои disabled probe/history удалены, исходные IDs совпали, только3 compose containers/backend/PG healthy; RouterOS/credentials не менялись.
|
||||
|
||||
При согласовании указателей94–97 обнаружено, что массовая замена также затронула исторический абзац77 в плане/протоколе. Восстановлен точный абзац из40f730b, история/дата2026-10-09 сохранены; следующие обновления ограничены текущими указателями. Следующий99 — одна общая backend/main/context регрессия на текущем source, с восстановлением исходных доказательств, затем итоговая сводка. General backend/main runs уже запущены, их результат этим блоком не заявлен. Квота23% использовано; этап12.5 открыт. Один локальный commit без push.
|
||||
|
||||
## 12.5.97 — реальный обрыв HTTP receipt bandwidth-test (2026-10-10)
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Оставшаяся внешняя приёмка — 2026-10-10
|
||||
|
||||
Это актуальная матрица после 12.5.97. Исторические записи сохраняют версии и ограничения на момент выполнения; поздние проверки ниже уточняют их. Этап 12.5 открыт. Успех в двух CHR и одном backend не означает приёмку всех конфигураций, интеграций или полной регрессии.
|
||||
Это актуальная матрица после 12.5.98. Исторические записи сохраняют версии и ограничения на момент выполнения; поздние проверки ниже уточняют их. Этап 12.5 открыт. Успех в двух CHR и одном backend не означает приёмку всех конфигураций, интеграций или полной регрессии.
|
||||
|
||||
Стенд: Debian13/Compose, PostgreSQL18.6, два CHR RouterOS7.24.5. Backend `ux-diagnostics89`, frontend `ux-ospf91`; production lab использует AUTH_REQUIRED=false. Подписанные JWT/RBAC проверялись в изолированных процессах. Все собственные объекты последнего сценария удалены, исходные11 коллекций×2 восстановлены; пароли не менялись.
|
||||
Стенд: Debian13/Compose, PostgreSQL18.6, два CHR RouterOS7.24.5. Backend `ux-speed98`, frontend `ux-ospf91`; production lab использует AUTH_REQUIRED=false. Подписанные JWT/RBAC проверялись в изолированных процессах. Все собственные объекты последнего сценария удалены, исходные11 коллекций×2 восстановлены; пароли не менялись.
|
||||
|
||||
| Раздел | Подтверждено | Осталось / условие завершения |
|
||||
| --- | --- | --- |
|
||||
@@ -25,7 +25,7 @@
|
||||
## Следующая последовательность
|
||||
|
||||
1. **12.5.95 завершён:** [source/context/compiled audit](ux-ui/acceptance/deployment-source-audit-2026-10-10.json), production source drift не выявлен; нормализация и исключения явно указаны.
|
||||
2. **12.5.96 timezone завершён:** [6 live UI cases](ux-ui/acceptance/browser-speed-timezone-2026-10-10.json). 97 HTTP receipt disconnect принят: [протокол](ux-ui/acceptance/speed-disconnect-2026-10-10.json). Следующий98 — понятное сообщение неизвестного native результата.
|
||||
2. **12.5.96 timezone завершён:** [6 live UI cases](ux-ui/acceptance/browser-speed-timezone-2026-10-10.json). 97 HTTP receipt disconnect принят: [протокол](ux-ui/acceptance/speed-disconnect-2026-10-10.json). 98 сообщение неизвестного native результата исправлено/развёрнуто. Следующий99 — общая регрессия.
|
||||
3. **Заключительный профильный контроль:** после последнего исправления собрать только затронутую часть, проверить её live и обновить матрицу. Общую регрессию выполнить один раз на согласованном runtime.
|
||||
4. **Внешние зависимости:** Telegram/Portal/client OS/multi-WAN/scale проходят отдельную приёмку при наличии нужных аккаунтов, устройств и разрешений. Лабораторный результат двух CHR не закрывает их автоматически.
|
||||
|
||||
|
||||
@@ -2234,3 +2234,13 @@ API502, history error/TXRX/Pingnull, probe error с прежними42/17/15/0;
|
||||
Свои history/probe exact IDs удалены, исходные списки совпали, только3 compose containers/backend/PG healthy. Один короткий capped native запуск с первой попытки, без RouterOS configuration/account changes/build/deploy. Native команда не отменялась; physical WAN failure/abort/multi-instance locks не приняты. Lab AUTH_REQUIRED=false, rights не проверялись повторно. HTTP ошибка приложения не доказывает failure native команды.
|
||||
|
||||
Обнаружено оставшееся UX ограничение: timeout/socket message техническая и не объясняет неопределённость native результата. Следующий98 — единый понятный transport error для HTTP/history, профильные tests и один backend build/live повтор только изменённого message path; затем общая регрессия на согласованном runtime. Этап12.5 открыт. Один локальный коммит без push.
|
||||
|
||||
## 12.5.98 — понятный неизвестный результат теста скорости (2026-10-10)
|
||||
|
||||
После реального lost receipt97 техническое сообщение заменено единым speedRunErrorMessage для HTTP и сохраняемой истории: «Результат теста скорости неизвестен: ответ устройства не получен. Проверьте его состояние перед повторным запуском». Timeout/socket hang up/ECONNRESET не означают доказанный native failure. Известный отказ авторизации и остальные конкретные ошибки сохраняются; неизвестное сохранение PG остаётся отдельным outcome=unknown/runId. HTTP502/history error означают ошибку получения результата приложением; schema/status/автоматический retry не расширялись.
|
||||
|
||||
**Проверки.** Speed-test HTTP validation/persistence/RBAC и дополнительные3 transport cases/известная auth error passed; локальный contracts/backend production build и scoped ESLint passed. Service иroute используют один formatter. [Deployment](ux-ui/acceptance/deployed-speed-message-2026-10-10.json): одна Docker backend сборка из context diagnostics89 +3 working-tree files, package/lockfile неизменны, production tsc/entry/node --check/pg_restore18.6/compose --wait passed. Runtime backend ux-speed98/version1.0.0-test.speed98/image779b0fc010c9…; frontend ux-ospf91 прежний. Label speed98 — блок, не Git SHA. Приватный .env backup сохранён; обновлён только BACKEND_IMAGE_TAG.
|
||||
|
||||
[Native/API/PG](ux-ui/acceptance/speed-message-2026-10-10.json) и [browser](ux-ui/acceptance/browser-speed-message-2026-10-10.json): повторён только изменённый receipt path, одна capped10Mbit/s TCP3s команда, реальное закрытие socket после передачи, native independently done, API/history содержат новое сообщение; прежние синтетические42/17/15/0 сохранены, native1/noauto retry. Live1280/3202/2, сообщение видно в probe card, reload/document fits/pageerror0/UI command POST0. Свои disabled probe/history удалены, исходные IDs совпали, только3 compose containers/backend/PG healthy; RouterOS/credentials не менялись.
|
||||
|
||||
При согласовании указателей94–97 обнаружено, что массовая замена также затронула исторический абзац77 в плане/протоколе. Восстановлен точный абзац из40f730b, история/дата2026-10-09 сохранены; следующие обновления ограничены текущими указателями. Следующий99 — одна общая backend/main/context регрессия на текущем source, с восстановлением исходных доказательств, затем итоговая сводка. General backend/main runs уже запущены, их результат этим блоком не заявлен. Квота23% использовано; этап12.5 открыт. Один локальный commit без push.
|
||||
@@ -1,6 +1,6 @@
|
||||
# Тестовый сервер UX/UI — 2026-10-10
|
||||
|
||||
Сервер161.104.46.222 предоставлен для временного тестирования. Backend ux-diagnostics89/version1.0.0-test.diagnostics89, frontend ux-ospf91/version1.0.0-test.ospf91; backend/PG healthy, frontend HTTP/browser passed. Основной блок IPsec77 принят в границах журнала, own fixtures/fake DB rows удалены; каталог flash CHR2 сохранён из-за неподтверждённого ownership. SSH/оба CHR доступны, пароли прежние.
|
||||
Сервер161.104.46.222 предоставлен для временного тестирования. Backend ux-speed98/version1.0.0-test.speed98, frontend ux-ospf91/version1.0.0-test.ospf91; backend/PG healthy, frontend HTTP/browser passed. Основной блок IPsec77 принят в границах журнала, own fixtures/fake DB rows удалены; каталог flash CHR2 сохранён из-за неподтверждённого ownership. SSH/оба CHR доступны, пароли прежние.
|
||||
|
||||
| Параметр | Проверенное состояние |
|
||||
| --- | --- |
|
||||
@@ -14,7 +14,7 @@
|
||||
| PostgreSQL | postgres:18-alpine,18.6;mmapp-test-postgres healthy;SELECT version() passed |
|
||||
| Данные | Отдельный Compose project mmapp-test,том mmapp-test_mmapp-pgdata и каталог ./data |
|
||||
| Доступ | PostgreSQL не публикуется;frontend3000/backend8000 привязаны к127.0.0.1 после запуска |
|
||||
| Образы приложения | mmapp-test/backend:ux-diagnostics89 и mmapp-test/frontend:ux-ospf91; запущены |
|
||||
| Образы приложения | mmapp-test/backend:ux-speed98 и mmapp-test/frontend:ux-ospf91; запущены |
|
||||
|
||||
Compose SHA256:3052bd6ab5d9865f97605cebfb5ff27a4410cd3357b81153a65a87fb7c92582f. OptionalBACKEND_IMAGE_TAG позволяетобновлятьbackendотдельно. Локальный и удалённый файлы совпали. Шаблоны: [Compose](../deploy/docker-compose.test.yml), [env без секретов](../deploy/env.test.example).
|
||||
|
||||
@@ -747,3 +747,13 @@ API502, history error/TXRX/Pingnull, probe error с прежними42/17/15/0;
|
||||
Свои history/probe exact IDs удалены, исходные списки совпали, только3 compose containers/backend/PG healthy. Один короткий capped native запуск с первой попытки, без RouterOS configuration/account changes/build/deploy. Native команда не отменялась; physical WAN failure/abort/multi-instance locks не приняты. Lab AUTH_REQUIRED=false, rights не проверялись повторно. HTTP ошибка приложения не доказывает failure native команды.
|
||||
|
||||
Обнаружено оставшееся UX ограничение: timeout/socket message техническая и не объясняет неопределённость native результата. Следующий98 — единый понятный transport error для HTTP/history, профильные tests и один backend build/live повтор только изменённого message path; затем общая регрессия на согласованном runtime. Этап12.5 открыт. Один локальный коммит без push.
|
||||
|
||||
## 12.5.98 — понятный неизвестный результат теста скорости (2026-10-10)
|
||||
|
||||
После реального lost receipt97 техническое сообщение заменено единым speedRunErrorMessage для HTTP и сохраняемой истории: «Результат теста скорости неизвестен: ответ устройства не получен. Проверьте его состояние перед повторным запуском». Timeout/socket hang up/ECONNRESET не означают доказанный native failure. Известный отказ авторизации и остальные конкретные ошибки сохраняются; неизвестное сохранение PG остаётся отдельным outcome=unknown/runId. HTTP502/history error означают ошибку получения результата приложением; schema/status/автоматический retry не расширялись.
|
||||
|
||||
**Проверки.** Speed-test HTTP validation/persistence/RBAC и дополнительные3 transport cases/известная auth error passed; локальный contracts/backend production build и scoped ESLint passed. Service иroute используют один formatter. [Deployment](ux-ui/acceptance/deployed-speed-message-2026-10-10.json): одна Docker backend сборка из context diagnostics89 +3 working-tree files, package/lockfile неизменны, production tsc/entry/node --check/pg_restore18.6/compose --wait passed. Runtime backend ux-speed98/version1.0.0-test.speed98/image779b0fc010c9…; frontend ux-ospf91 прежний. Label speed98 — блок, не Git SHA. Приватный .env backup сохранён; обновлён только BACKEND_IMAGE_TAG.
|
||||
|
||||
[Native/API/PG](ux-ui/acceptance/speed-message-2026-10-10.json) и [browser](ux-ui/acceptance/browser-speed-message-2026-10-10.json): повторён только изменённый receipt path, одна capped10Mbit/s TCP3s команда, реальное закрытие socket после передачи, native independently done, API/history содержат новое сообщение; прежние синтетические42/17/15/0 сохранены, native1/noauto retry. Live1280/3202/2, сообщение видно в probe card, reload/document fits/pageerror0/UI command POST0. Свои disabled probe/history удалены, исходные IDs совпали, только3 compose containers/backend/PG healthy; RouterOS/credentials не менялись.
|
||||
|
||||
При согласовании указателей94–97 обнаружено, что массовая замена также затронула исторический абзац77 в плане/протоколе. Восстановлен точный абзац из40f730b, история/дата2026-10-09 сохранены; следующие обновления ограничены текущими указателями. Следующий99 — одна общая backend/main/context регрессия на текущем source, с восстановлением исходных доказательств, затем итоговая сводка. General backend/main runs уже запущены, их результат этим блоком не заявлен. Квота23% использовано; этап12.5 открыт. Один локальный commit без push.
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"date": "2026-10-10",
|
||||
"cases": [
|
||||
{
|
||||
"width": 1280,
|
||||
"errorHistoryVisible": true,
|
||||
"previousSnapshot42and17Preserved": true,
|
||||
"reload": true,
|
||||
"documentFits": true,
|
||||
"unknownNativeMessageVisible": true
|
||||
},
|
||||
{
|
||||
"width": 320,
|
||||
"errorHistoryVisible": true,
|
||||
"previousSnapshot42and17Preserved": true,
|
||||
"reload": true,
|
||||
"documentFits": true,
|
||||
"unknownNativeMessageVisible": true
|
||||
}
|
||||
],
|
||||
"errors": [],
|
||||
"httpMocks": false,
|
||||
"uiNativePosts": 0
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"date": "2026-10-10",
|
||||
"backendImage": "mmapp-test/backend:ux-speed98",
|
||||
"backendVersion": "1.0.0-test.speed98",
|
||||
"backendImageId": "sha256:779b0fc010c9d0a52b9a774429cce77d28163d2374c24e4d2f64a3ab7ea18792",
|
||||
"frontendImage": "mmapp-test/frontend:ux-ospf91",
|
||||
"buildContext": "build-diagnostics89 copied to build-speed98; 3 working-tree production overrides",
|
||||
"revisionLabel": "speed98 (stage label, not Git SHA)",
|
||||
"archiveSha256": "1659e9b7fa1b135cbd3e61b77e097eb2bf6d0ee74816c508e989a374f60cb4a0",
|
||||
"overrides": [
|
||||
{
|
||||
"path": "backend/src/routes/speed-test.ts",
|
||||
"normalizedSha256": "28d876438f8ac5ab6200f1193d53ce416018f28d847229c99eae82c1c5ec9111"
|
||||
},
|
||||
{
|
||||
"path": "backend/src/services/uptime-speed-service.ts",
|
||||
"normalizedSha256": "9ffd217471ebc090dea178f2717ffb5cdb8bb27efe6f3db5e2346d8d066d2ea9"
|
||||
},
|
||||
{
|
||||
"path": "backend/src/services/speed-run-error-message.ts",
|
||||
"normalizedSha256": "e31365d1282b87cd15b479c8a4b45333af997839d6f2f9cffb4887886b9f0d37"
|
||||
}
|
||||
],
|
||||
"validation": {
|
||||
"localContractsBackendBuild": true,
|
||||
"scopedEslint": true,
|
||||
"speedHttpAndSignedJwtTests": true,
|
||||
"dockerProductionBuild": true,
|
||||
"entryNodeCheck": true,
|
||||
"pgRestoreVersion": "18.6",
|
||||
"composeWaitHealthy": true,
|
||||
"liveUiCases": 2
|
||||
},
|
||||
"limits": [
|
||||
"General backend/main UI regression running separately; not claimed passed in this block",
|
||||
"Only backend image changed; frontend/dependencies/migrations/account configuration unchanged",
|
||||
"History error is application receipt outcome; native completion remains unknown to app on transport loss"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"date": "2026-10-10",
|
||||
"name": "mm-drop98-1791571091446",
|
||||
"rateLimitBps": 10000000,
|
||||
"durationSec": 3,
|
||||
"syntheticPreviousSnapshot": {
|
||||
"txAvgMbps": 42,
|
||||
"rxAvgMbps": 17,
|
||||
"pingRttMs": 15,
|
||||
"pingLossPct": 0
|
||||
},
|
||||
"httpMocks": false,
|
||||
"routerOsMocks": false,
|
||||
"receiptSocketDestroyed": true,
|
||||
"httpStatus": 502,
|
||||
"receipt": {
|
||||
"error": "Результат теста скорости неизвестен: ответ устройства не получен. Проверьте его состояние перед повторным запуском."
|
||||
},
|
||||
"nativeCompletion": {
|
||||
"status": "done testing",
|
||||
"responseRows": 5,
|
||||
"httpStatus": 200
|
||||
},
|
||||
"nativeCount": 1,
|
||||
"probe": {
|
||||
"id": "mm-drop98-1791571091446",
|
||||
"last_status": "error",
|
||||
"last_tx_avg_mbps": 42,
|
||||
"last_rx_avg_mbps": 17,
|
||||
"last_ping_rtt_ms": 15,
|
||||
"last_ping_loss_pct": 0,
|
||||
"last_error": "Результат теста скорости неизвестен: ответ устройства не получен. Проверьте его состояние перед повторным запуском."
|
||||
},
|
||||
"history": [
|
||||
{
|
||||
"id": "mm-drop98-1791571091446",
|
||||
"status": "error",
|
||||
"tx_avg_mbps": null,
|
||||
"rx_avg_mbps": null,
|
||||
"ping_rtt_ms": null,
|
||||
"ping_loss_pct": null,
|
||||
"error": "Результат теста скорости неизвестен: ответ устройства не получен. Проверьте его состояние перед повторным запуском."
|
||||
}
|
||||
],
|
||||
"automaticRetry": false,
|
||||
"limits": [
|
||||
"Real Node HTTP client socket closed after request forwarded; RouterOS independently completed. Not physical WAN loss or cancelled native command.",
|
||||
"Previous metrics deliberately seeded on own disabled probe, not new real measurements.",
|
||||
"History error means application did not obtain confirmed test result; native completion was observed only by independent relay."
|
||||
],
|
||||
"cleanupHistory": true,
|
||||
"cleanupProbes": true
|
||||
}
|
||||
Reference in new issue
Block a user