fix(traffic): проверить сбор трафика через HTTP и PostgreSQL

This commit is contained in:
Denozordec committed 2026-10-12 18:13:48 +07:00
1 parent 4527e5537c
commit 737e04a6a9
12 files changed
+1257 -13

No files matched your search

+1 -1
View File
@@ -19,7 +19,7 @@
"test:exec": "tsx src/services/mikrotik-logs.test.ts && tsx src/routes/exec.test.ts && tsx src/plugins/auth.exec.test.ts",
"test:auth": "tsx src/lib/permissions.test.ts && tsx src/plugins/auth.smoke.test.ts && tsx src/plugins/auth.ospf-optimizer.test.ts",
"test:wireguard": "npx tsx src/services/wireguard-config.test.ts && npx tsx src/services/wireguard-ipv6.test.ts && npx tsx --test src/services/wireguard-import.test.ts src/services/wireguard-import-apply.test.ts src/services/wireguard-import-revision.test.ts src/services/wireguard-delete.test.ts && npx tsx src/routes/wireguard-import.test.ts",
"test:traffic-rate": "tsx src/services/traffic-rate.test.ts && tsx src/services/traffic-observation.test.ts",
"test:traffic-rate": "tsx src/services/traffic-rate.test.ts && tsx src/services/traffic-observation.test.ts && tsx src/services/traffic-observation-sql.test.ts",
"test:traffic-flow": "tsx src/routes/traffic-flow-query.test.ts && tsx src/services/traffic-flow-month.test.ts && tsx src/services/traffic-flow-parse.test.ts && tsx src/services/traffic-flow-ipv6-pipeline.test.ts && tsx src/services/traffic-flow-map-exporter.test.ts && tsx src/services/traffic-flow-ifaces.test.ts && tsx src/services/traffic-flow-ifindex.test.ts && tsx src/services/traffic-flow-dedup.test.ts && tsx src/services/traffic-flow-planes.test.ts && tsx src/services/traffic-flow-ip.test.ts && tsx src/services/traffic-flow-dest.test.ts && tsx src/services/traffic-flow-classify.test.ts && tsx src/services/traffic-flow-ripe.test.ts && tsx src/services/traffic-flow-brands.test.ts && tsx src/services/traffic-flow-ingest.test.ts && tsx src/services/traffic-flow-analytics.test.ts && tsx src/services/traffic-flow-map-hops.test.ts && tsx src/services/traffic-flow-purge.test.ts && tsx src/services/traffic-flow-geoip.test.ts && tsx src/services/traffic-flow-facts.test.ts && tsx src/services/traffic-flow-facts-filter.test.ts && tsx src/services/traffic-flow-facts-rebuild.test.ts && tsx src/services/statistics-aggregate.test.ts",
"test:users": "tsx src/modules/users/iface-type.test.ts && tsx src/modules/users/bindings.test.ts && tsx src/modules/users/interface-inventory.test.ts && tsx src/routes/users-catalog.test.ts",
"test:pg": "tsx src/db/pg-pool.test.ts && tsx src/db/sql-bind.test.ts && tsx src/db/sqlite-json.test.ts && tsx src/db/traffic-flags.test.ts && tsx src/db/pg-schema.test.ts && tsx src/services/config-revisions.test.ts",
@@ -0,0 +1,65 @@
import assert from "node:assert/strict"
import { createServer } from "node:http"
import { pool, closePool } from "../db/index.js"
import { initDatabase } from "../db/bootstrap.js"
import { collectTrafficOnce } from "./traffic-collector.js"
import { buildSignalSnapshotFromCollectors } from "./alert-engine/signals-from-collectors.js"
const database = process.env.MMAPP_OWN_SQL_DB
if (!database) console.log("traffic observation SQL: skipped; explicit owned database required")
else {
assert(/^mm_accept_166_\d+$/.test(database))
assert.equal(new URL(process.env.DATABASE_URL!).pathname, "/" + database)
assert.equal((await pool.query("SELECT current_database() AS name")).rows[0].name, database)
const prefix = "own-traffic175-" + Date.now() + "-"
let serverId: number | undefined, counters: unknown = "1000", second = false, cases = 0, requests = 0
const http = createServer((req, res) => {
requests++; res.setHeader("Content-Type", "application/json")
const rows = [{ name: "ether1", running: "true", disabled: "false", "rx-byte": counters, "tx-byte": counters }]
if (second) rows.push({ name: "ether2", running: "true", disabled: "false", "rx-byte": "1000", "tx-byte": "1000" })
res.end(JSON.stringify(req.url?.includes("/wireguard/") ? [] : rows))
})
await new Promise<void>(resolve => http.listen(0, "127.0.0.1", resolve))
const address = http.address(); assert(address && typeof address === "object")
try {
await initDatabase()
serverId = Number((await pool.query("INSERT INTO servers(name,host,port,use_ssl,enabled,username,password,updated_at) VALUES($1,'127.0.0.1',$2,false,true,'fixture','fixture',$3) RETURNING id", [prefix + "server", address.port, new Date(Date.now() - 3_600_000).toISOString()])).rows[0].id)
await pool.query("INSERT INTO traffic_settings(id,enabled,interval_sec) VALUES(1,true,30) ON CONFLICT(id) DO UPDATE SET enabled=true,interval_sec=30")
const count = async () => Number((await pool.query("SELECT count(*) AS n FROM traffic_samples WHERE server_id=$1", [serverId])).rows[0].n)
const collect = async (known: boolean) => {
const snapshot = await collectTrafficOnce(), row = snapshot.servers.find(s => s.serverId === serverId)!
assert.equal(typeof row.sumRxMbps === "number", known)
assert.equal(typeof row.sumTxMbps === "number", known)
await pool.query("DELETE FROM scheduler_runs WHERE job_key='traffic'")
await pool.query("INSERT INTO scheduler_runs(id,job_key,started_at,finished_at,status,result_json) VALUES($1,'traffic',$2,$3,'ok',$4::jsonb)", [prefix + cases, snapshot.sampledAt, new Date().toISOString(), JSON.stringify(snapshot)])
const source = (await buildSignalSnapshotFromCollectors()).trafficByServer
assert.equal(source.length, Number(known)); cases++
return row
}
let row = await collect(false); assert.equal(row.ok, true); assert.equal(await count(), 1)
// Move the fixture baseline, not the clock, to avoid slow sleeps and equal timestamps.
const age = async () => {
await pool.query("DELETE FROM traffic_samples WHERE server_id=$1 AND sampled_at<>(SELECT max(sampled_at) FROM traffic_samples WHERE server_id=$1)", [serverId])
await pool.query("UPDATE traffic_samples SET sampled_at=$1 WHERE server_id=$2", [new Date(Date.now() - 30_000).toISOString(), serverId])
}
await age(); row = await collect(true); assert.equal(row.sumRxMbps, 0)
await age(); counters = "10"; row = await collect(false); assert.equal(row.ok, true)
await age(); const beforeBad = await count(); counters = "123bad"; row = await collect(false)
assert.equal(row.ok, false); assert.match(row.error!, /некорректный счётчик/); assert.equal(await count(), beforeBad)
await age(); counters = undefined; row = await collect(false); assert.equal(row.ok, false); assert.equal(await count(), beforeBad)
await age(); counters = "10"; second = true; row = await collect(false); assert.equal(row.ok, true)
await age(); row = await collect(true); assert.equal(row.sumRxMbps, 0)
await age(); counters = "3750010"; row = await collect(true); assert(row.sumRxMbps! > 0.9)
await pool.query("UPDATE servers SET enabled=false WHERE id=$1", [serverId]); const beforeDisabled = requests
assert.equal((await collectTrafficOnce()).servers.length, 0); assert.equal(requests, beforeDisabled); cases++
console.log(`traffic observation owned SQL: ${cases} cases; actual HTTP/collector/persistence/scheduler/source/disabled passed`)
} finally {
await new Promise<void>(resolve => http.close(() => resolve()))
await pool.query("DELETE FROM scheduler_runs WHERE id LIKE $1", [prefix + "%"])
if (serverId !== undefined) {
await pool.query("DELETE FROM traffic_samples WHERE server_id=$1", [serverId])
await pool.query("DELETE FROM servers WHERE id=$1", [serverId])
}
await closePool()
}
}
+14 -2
View File
@@ -1,6 +1,6 @@
# UX/UI: протокол внешней приёмки 12.5
Актуальное продолжение 2026-10-12: завершён локальный блок12.5.174 — воспроизведены ложные нули трафика; сумма scheduler snapshot выдаётся только при достоверных дельтах всех учитываемых интерфейсов, invalid counters отклоняются. Профиль traffic-rate (включая actual collector body) и backend production build прошли. Стенд остаётся ux-ping173; SQL/HTTP-приёмка producer и deployment нового guard — следующий175. Этап12.5 открыт.
Актуальное продолжение 2026-10-12: завершён12.5.175 — real HTTP client/traffic producer→owned PostgreSQL→scheduler JSON→source confidence,9 SQL controls passed за9358ms; ownDB/role/container удалены. Backend ux-traffic175 deployed/healthy, frontend ux-ping173;1024 compiled parity,2live UI/3API passed. Следующий176 — проверить compound RouterOS RTT duration parser по сохранённым native payloads; legacy counters/history freshness остаются открыты. Этап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.174 — воспроизведены ложные нули трафика; сумма scheduler snapshot выдаётся только при достоверных дельтах всех учитываемых интерфейсов, invalid counters отклоняются. Профиль traffic-rate (включая actual collector body) и backend production build прошли. Стенд остаётся ux-ping173; SQL/HTTP-приёмка producer и deployment нового guard — следующий175. Этап12.5 открыт.
Актуальное продолжение 2026-10-12: завершён12.5.175 — real HTTP client/traffic producer→owned PostgreSQL→scheduler JSON→source confidence,9 SQL controls passed за9358ms; ownDB/role/container удалены. Backend ux-traffic175 deployed/healthy, frontend ux-ping173;1024 compiled parity,2live UI/3API passed. Следующий176 — проверить compound RouterOS RTT duration parser по сохранённым native payloads; legacy counters/history freshness остаются открыты. Этап12.5 открыт.
Подробный объём, протоколы, схема и ограничения: [12.5.77 в журнале](ux-ui-progress.md).
@@ -1985,3 +1985,15 @@ Existing snapshot types уже имеют optional суммы; source decoder174
npm --prefix backend run test:traffic-rate прошёл: существующие формулы/observations, новый counter/rate/source guard и actual collectTrafficOnce body через AST с in-memory DB/HTTP boundaries (first wave, zero, reset, malformed/no insert, excluded interfaces). Извлечение исполняет исходный collector, не копию алгоритма; это не реальный PostgreSQL или RouterOS. npm --prefix backend run build прошёл. [Local check](ux-ui/acceptance/traffic-confidence-local-2026-10-12.json) фиксирует хеши изменённых source и границы доказательства. Full regression/remote deployment не выполнялись, поскольку изменён только локальный producer guard.
Следующий175: real MikrotikClient loopback HTTP→owned PostgreSQL→scheduler resultJson→source decoder с first-wave/next-zero/reset/malformed/mixed-interface controls; проверить очистку своих объектов и исключение stale historical samples. После profile acceptance собрать backend и развернуть guard на тестовом стенде; frontend ux-ping173 совместим с absent optional totals. Сейчас оба сервиса удалённого стенда всё ещё ux-ping173, native Ping4/4 подтверждён в173; новое исправление там ещё не доступно. Пароли, конфигурация CHR и тестовый runtime этим блоком не менялись. Локальный коммит без push.
## 12.5.175 — SQL/HTTP-приёмка достоверности трафика и развёртывание (2026-10-12)
Producer guard174 проверен через настоящий MikrotikClient к loopback HTTP simulator, actual collectTrafficOnce, PostgreSQL18.6 и buildSignalSnapshotFromCollectors. Девять SQL controls: first wave без суммы/со stored valid counters; следующая genuine zero; reset без суммы; malformed123bad и missing counter дают ok=false/no insert; новый второй интерфейс не даёт частичную сумму; следующая полная zero wave; положительная скорость; disabled server без outbound HTTP. Каждая актуальная wave сохраняется в scheduler_runs и проходит реальный source reader. Fixture clock не задерживает тест: в своей базе сохраняется только последняя baseline wave и сдвигается её время на30s. Это не проверка длинной historical continuity/retention и не физический RouterOS counter reset.
Профиль test:traffic-rate дополнен тестом traffic-observation-sql.test.ts. Локально SQL явно skipped без own database; удалённый Node22/PG18.6 профиль прошёл9358ms без SQL skip. База mm_accept_166_1791803283546 принадлежала временному LOGIN без SUPERUSER/CREATEDB/CREATEROLE/BYPASSRLS. Актуальные production DB/JWT secrets не копировались. Тестовые rows убраны finally, база/роль/container удалены trap и отсутствие DB/role проверено каталогами; остались только3 основные контейнера. [SQL](ux-ui/acceptance/traffic-confidence-sql-2026-10-12.json).
Production backend build прошёл локально и на Debian; [1024 compiled artifacts](ux-ui/acceptance/traffic-confidence-compiled-2026-10-12.json) совпали SHA256 с локальными, different/missing0. Backend ux-traffic175/version1.0.0-test.traffic175 развёрнут; frontend ux-ping173 сохранён и совместим с optional sums. До сборки исправлена строка Docker base, которую ошибочно заменила blanket tag substitution; неисправный Dockerfile не собирался и не выпускался. В.env менялся только BACKEND_IMAGE_TAG, rollback tag ux-ping173 сохранён без копии секретного env. [Runtime](ux-ui/acceptance/traffic-confidence-runtime-2026-10-12.json): verified imageIds, backend healthy/frontend running.
[Read-only live smoke](ux-ui/acceptance/traffic-confidence-deployed-2026-10-12.json): /traffic1440/320, traffic servers200/no pageerrors/no overflow; /servers,/traffic/servers,/scheduler/runs?jobKey=traffic200. Это проверка доступности/совместимости UI, не доказательство доставки Telegram или возникновения всех edge cases в main DB. Нет manual scheduler run/config/password/message writes; автоматический scheduler остаётся штатным. Пароли CHR не менялись; native Ping4/4 в обе стороны подтверждён ранее в173, здесь повторно не заявлен.
Следующий176 — inspect native compound durations53ms561us и parseFloat prefix fallback в Ping parser; положительные source payloads уже сохранены в173, не требуются новые сетевые сущности для первоначального доказательства. Legacy invalid traffic counters/raw-rate consumers, history freshness/failed attempt barriers, interface identity/config changes, scale/multiple backend и внешние интеграции остаются условиями12.5. Не считать guard174–175 полной приёмкой трафика. Локальный коммит без push.
+3 -3
View File
@@ -1,12 +1,12 @@
# План реализации UX/UI по пятичасовым окнам
Актуальное продолжение 2026-10-12: завершён локальный блок12.5.174 — воспроизведены ложные нули трафика; сумма scheduler snapshot выдаётся только при достоверных дельтах всех учитываемых интерфейсов, invalid counters отклоняются. Профиль traffic-rate (включая actual collector body) и backend production build прошли. Стенд остаётся ux-ping173; SQL/HTTP-приёмка producer и deployment нового guard — следующий175. Этап12.5 открыт.
Актуальное продолжение 2026-10-12: завершён12.5.175 — real HTTP client/traffic producer→owned PostgreSQL→scheduler JSON→source confidence,9 SQL controls passed за9358ms; ownDB/role/container удалены. Backend ux-traffic175 deployed/healthy, frontend ux-ping173;1024 compiled parity,2live UI/3API passed. Следующий176 — проверить compound RouterOS RTT duration parser по сохранённым native payloads; legacy counters/history freshness остаются открыты. Этап12.5 открыт.
Общий план проекта MikrotikManager. Основан на согласованном плане из задачи; точка продолжения обновлена 2026-10-12. Источник фактического прогресса, проверок и ограничений — [журнал реализации](ux-ui-progress.md). Этот документ задаёт объём и критерии завершения, журнал фиксирует результат.
## Актуальная точка продолжения — 2026-10-12
Актуальное продолжение 2026-10-12: завершён локальный блок12.5.174 — воспроизведены ложные нули трафика; сумма scheduler snapshot выдаётся только при достоверных дельтах всех учитываемых интерфейсов, invalid counters отклоняются. Профиль traffic-rate (включая actual collector body) и backend production build прошли. Стенд остаётся ux-ping173; SQL/HTTP-приёмка producer и deployment нового guard — следующий175. Этап12.5 открыт.
Актуальное продолжение 2026-10-12: завершён12.5.175 — real HTTP client/traffic producer→owned PostgreSQL→scheduler JSON→source confidence,9 SQL controls passed за9358ms; ownDB/role/container удалены. Backend ux-traffic175 deployed/healthy, frontend ux-ping173;1024 compiled parity,2live UI/3API passed. Следующий176 — проверить compound RouterOS RTT duration parser по сохранённым native payloads; legacy counters/history freshness остаются открыты. Этап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-12: завершён локальный блок12.5.174 — воспроизведены ложные нули трафика; сумма scheduler snapshot выдаётся только при достоверных дельтах всех учитываемых интерфейсов, invalid counters отклоняются. Профиль traffic-rate (включая actual collector body) и backend production build прошли. Стенд остаётся ux-ping173; SQL/HTTP-приёмка producer и deployment нового guard — следующий175. Этап12.5 открыт.
Актуальное продолжение 2026-10-12: завершён12.5.175 — real HTTP client/traffic producer→owned PostgreSQL→scheduler JSON→source confidence,9 SQL controls passed за9358ms; ownDB/role/container удалены. Backend ux-traffic175 deployed/healthy, frontend ux-ping173;1024 compiled parity,2live UI/3API passed. Следующий176 — проверить compound RouterOS RTT duration parser по сохранённым native payloads; legacy counters/history freshness остаются открыты. Этап12.5 открыт.
Подробный объём, протоколы, схема и ограничения: [12.5.77 в журнале](ux-ui-progress.md).
+13 -1
View File
@@ -1,6 +1,6 @@
# UX/UI: журнал реализации
Актуальное продолжение 2026-10-12: завершён локальный блок12.5.174 — воспроизведены ложные нули трафика; сумма scheduler snapshot выдаётся только при достоверных дельтах всех учитываемых интерфейсов, invalid counters отклоняются. Профиль traffic-rate (включая actual collector body) и backend production build прошли. Стенд остаётся ux-ping173; SQL/HTTP-приёмка producer и deployment нового guard — следующий175. Этап12.5 открыт.
Актуальное продолжение 2026-10-12: завершён12.5.175 — real HTTP client/traffic producer→owned PostgreSQL→scheduler JSON→source confidence,9 SQL controls passed за9358ms; ownDB/role/container удалены. Backend ux-traffic175 deployed/healthy, frontend ux-ping173;1024 compiled parity,2live UI/3API passed. Следующий176 — проверить compound RouterOS RTT duration parser по сохранённым native payloads; legacy counters/history freshness остаются открыты. Этап12.5 открыт.
Общий план: [UX/UI по этапам и пятичасовым окнам](ux-ui-plan.md). План задаёт объём, этот журнал фиксирует выполненные блоки и ограничения. Записи расположены от новых к старым; подробная история этапа12 также сохранена в [ux-ui-stage-12.md](ux-ui-stage-12.md).
@@ -38,6 +38,18 @@
| 11Б | Оповещения, сбор данных, интеграции, релизы и настройки | Завершён в границах локальной приёмки 2026-10-03; ограничения и evidence в11Б.7 |
| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Локальная приёмка завершена в границах12.3.83; внешняя12.5 в работе, выполненные блоки1–168 и ограничения ниже. Runtime backend ux-month149/frontend ux-sessions150. |
## 12.5.175 — SQL/HTTP-приёмка достоверности трафика и развёртывание (2026-10-12)
Producer guard174 проверен через настоящий MikrotikClient к loopback HTTP simulator, actual collectTrafficOnce, PostgreSQL18.6 и buildSignalSnapshotFromCollectors. Девять SQL controls: first wave без суммы/со stored valid counters; следующая genuine zero; reset без суммы; malformed123bad и missing counter дают ok=false/no insert; новый второй интерфейс не даёт частичную сумму; следующая полная zero wave; положительная скорость; disabled server без outbound HTTP. Каждая актуальная wave сохраняется в scheduler_runs и проходит реальный source reader. Fixture clock не задерживает тест: в своей базе сохраняется только последняя baseline wave и сдвигается её время на30s. Это не проверка длинной historical continuity/retention и не физический RouterOS counter reset.
Профиль test:traffic-rate дополнен тестом traffic-observation-sql.test.ts. Локально SQL явно skipped без own database; удалённый Node22/PG18.6 профиль прошёл9358ms без SQL skip. База mm_accept_166_1791803283546 принадлежала временному LOGIN без SUPERUSER/CREATEDB/CREATEROLE/BYPASSRLS. Актуальные production DB/JWT secrets не копировались. Тестовые rows убраны finally, база/роль/container удалены trap и отсутствие DB/role проверено каталогами; остались только3 основные контейнера. [SQL](ux-ui/acceptance/traffic-confidence-sql-2026-10-12.json).
Production backend build прошёл локально и на Debian; [1024 compiled artifacts](ux-ui/acceptance/traffic-confidence-compiled-2026-10-12.json) совпали SHA256 с локальными, different/missing0. Backend ux-traffic175/version1.0.0-test.traffic175 развёрнут; frontend ux-ping173 сохранён и совместим с optional sums. До сборки исправлена строка Docker base, которую ошибочно заменила blanket tag substitution; неисправный Dockerfile не собирался и не выпускался. В.env менялся только BACKEND_IMAGE_TAG, rollback tag ux-ping173 сохранён без копии секретного env. [Runtime](ux-ui/acceptance/traffic-confidence-runtime-2026-10-12.json): verified imageIds, backend healthy/frontend running.
[Read-only live smoke](ux-ui/acceptance/traffic-confidence-deployed-2026-10-12.json): /traffic1440/320, traffic servers200/no pageerrors/no overflow; /servers,/traffic/servers,/scheduler/runs?jobKey=traffic200. Это проверка доступности/совместимости UI, не доказательство доставки Telegram или возникновения всех edge cases в main DB. Нет manual scheduler run/config/password/message writes; автоматический scheduler остаётся штатным. Пароли CHR не менялись; native Ping4/4 в обе стороны подтверждён ранее в173, здесь повторно не заявлен.
Следующий176 — inspect native compound durations53ms561us и parseFloat prefix fallback в Ping parser; положительные source payloads уже сохранены в173, не требуются новые сетевые сущности для первоначального доказательства. Legacy invalid traffic counters/raw-rate consumers, history freshness/failed attempt barriers, interface identity/config changes, scale/multiple backend и внешние интеграции остаются условиями12.5. Не считать guard174–175 полной приёмкой трафика. Локальный коммит без push.
## 12.5.174 — достоверность суммы трафика: аудит и локальное исправление (2026-10-12)
На исходном8fb46b1 гипотеза подтверждена исполнением настоящих private sampleRate/toNum, извлечённых TypeScript AST, затем существующих collectSourceSignals/evaluateRule. Семь source fixtures: first-wave/reset/equal timestamps/missing/malformed counters дают0 и ложный RX<1; genuine zero даёт правильное срабатывание, positive1Mbps не срабатывает. Протокол [baseline audit](ux-ui/acceptance/traffic-confidence-audit-2026-10-12.json) намеренно fixed=false и относится к исходной версии, а не к финальному исправлению. Это локальное source воспроизведение; отправки Telegram, реальной SQL persistence и физического сброса RouterOS не было.
+15 -3
View File
@@ -1,8 +1,8 @@
# Оставшаяся внешняя приёмка — 2026-10-12
Это актуальная матрица после 12.5.174. Исторические записи сохраняют версии и ограничения на момент выполнения; поздние проверки ниже уточняют их. Этап 12.5 открыт. Успех в двух CHR и одном backend не означает приёмку всех конфигураций, интеграций или полной регрессии.
Это актуальная матрица после 12.5.175. Исторические записи сохраняют версии и ограничения на момент выполнения; поздние проверки ниже уточняют их. Этап 12.5 открыт. Успех в двух CHR и одном backend не означает приёмку всех конфигураций, интеграций или полной регрессии.
Стенд: Debian13/Compose, PostgreSQL18.6, два CHR RouterOS7.24.5. Backend `ux-ping173`, frontend `ux-ping173`; production lab использует AUTH_REQUIRED=false. Подписанные JWT/RBAC проверялись в изолированных процессах. Все собственные объекты112 удалены, исходные13 коллекций×2 (включая logging/certificates/files/routes) проверены; пароли не менялись.
Стенд: Debian13/Compose, PostgreSQL18.6, два CHR RouterOS7.24.5. Backend `ux-traffic175`, frontend `ux-ping173`; production lab использует AUTH_REQUIRED=false. Подписанные JWT/RBAC проверялись в изолированных процессах. Все собственные объекты112 удалены, исходные13 коллекций×2 (включая logging/certificates/files/routes) проверены; пароли не менялись.
| Раздел | Подтверждено | Осталось / условие завершения |
| --- | --- | --- |
@@ -18,7 +18,7 @@
| Recursive routes | Production PUT/change/own history restore88, disabled guards, partial/unknown/applied outcomes, live формы/контекст | Автоматический rollback/retry, durable receipts и несколько экземпляров отсутствуют; PUT не является idempotent noop. Полная произвольная legacy catalog миграция не принята |
| Diagnostics/terminal | Allowlist/native reads, Ping/trace/route/MTU/DNS, actual avg-rtt, disabled guards, JWT/live PC/mobile89; real default memory tail/log limits/API/UI133 | DNS использует backend resolver; MTU — ограниченная оценка, не гарантированный максимум. Stop ожидания не доказывает остановку RouterOS команды; arbitrary CLI и physical disconnect не приняты |
| Portal/интеграции | Локальные и isolated JWT guards; UI/API error states в границах журналов | Настоящий Portal issuer/login/отзыв прав; RIPE SDK two-IP/no-fetch passed140, native IPv6 ULA flow pipeline passed145 (IPv4 transport), public IPv6 WAN/local licensed MaxMind/S3/container/certificate jobs и Gitea delivery требуют отдельных тестовых endpoints/аккаунтов. Не отправлять сообщения и не публиковать релиз без соответствующего поручения |
| Общая приёмка | Локальная12.3.83; UI1244/context221/compiled984 parity139; профильные build/E2E/live проверки последующих блоков | Traffic initial live mock-id gate passed141; IPv6 special ranges/cache passed142; unknown RIPE coordinates passed143; IPv6 synthetic UDP/worker/SQL passed144; native CHR ULA/IPFIX/API/UI passed145; ICMPv6/IPv6 endpoint labels passed146; HTTP DTO validation passed147; scoped flow catalog/serverId guards passed148; strict monthly calendar passed149; Sessions labels passed150; application GRE static IPv6 lifecycle151 passed; WireGuard static IPv6 lifecycle152 и disabled SQL/API gates passed; OSPF/BFD boundary/warning153 passed; OSPFv3 routes154 accepted in recorded bounds; BGP IPv6 basic155 passed; bigint ID/SQL guards156 passed; общая UI1260/context221/backend24 regression157 passed; IPv6 BFD correlation158 profile/deployed passed; native OSPFv3/BFDv6 boundary/recovery159 passed; BGP IPv6/BFD withdrawal/recovery160 passed; selected BGP/alert unknown guards161 replay/profiles/deployed passed (SQL stability skipped); private4-byte ASN162 native/API/UI passed; duplicate BGP alert keys163 replay/profiles/deployed passed; nullable selected BGP164 replay/profiles/API/UI passed; collector165 parallel/current guards/read-only PG passed; positive partial/error SQL166/full24 with PG passed (optional network SQL not repeated); GRE/BGP freshness167/SQL8 passed; other source audit168 выявил identity/disabled/freshness gaps; локальный server/traffic identity guard169 passed без SQL/deploy, source/per-probe/freshness170/ownSQL16/compiled1008/deployed passed; source diagnostics171/42E2E/ownSQL metadata/live2 passed; monitoring history172/ownSQL26/compiled1020/deployed passed; Ping known/error173/ownHTTP-SQL8/85uniqueE2E/native4/4/deployed passed; traffic confidence174 baseline reproduced/local guard passed; owned SQL/deploy175 pending; последующие изменения проверять отдельно; scoped axe не означает полную WCAG сертификацию |
| Общая приёмка | Локальная12.3.83; UI1244/context221/compiled984 parity139; профильные build/E2E/live проверки последующих блоков | Traffic initial live mock-id gate passed141; IPv6 special ranges/cache passed142; unknown RIPE coordinates passed143; IPv6 synthetic UDP/worker/SQL passed144; native CHR ULA/IPFIX/API/UI passed145; ICMPv6/IPv6 endpoint labels passed146; HTTP DTO validation passed147; scoped flow catalog/serverId guards passed148; strict monthly calendar passed149; Sessions labels passed150; application GRE static IPv6 lifecycle151 passed; WireGuard static IPv6 lifecycle152 и disabled SQL/API gates passed; OSPF/BFD boundary/warning153 passed; OSPFv3 routes154 accepted in recorded bounds; BGP IPv6 basic155 passed; bigint ID/SQL guards156 passed; общая UI1260/context221/backend24 regression157 passed; IPv6 BFD correlation158 profile/deployed passed; native OSPFv3/BFDv6 boundary/recovery159 passed; BGP IPv6/BFD withdrawal/recovery160 passed; selected BGP/alert unknown guards161 replay/profiles/deployed passed (SQL stability skipped); private4-byte ASN162 native/API/UI passed; duplicate BGP alert keys163 replay/profiles/deployed passed; nullable selected BGP164 replay/profiles/API/UI passed; collector165 parallel/current guards/read-only PG passed; positive partial/error SQL166/full24 with PG passed (optional network SQL not repeated); GRE/BGP freshness167/SQL8 passed; other source audit168 выявил identity/disabled/freshness gaps; локальный server/traffic identity guard169 passed без SQL/deploy, source/per-probe/freshness170/ownSQL16/compiled1008/deployed passed; source diagnostics171/42E2E/ownSQL metadata/live2 passed; monitoring history172/ownSQL26/compiled1020/deployed passed; Ping known/error173/ownHTTP-SQL8/85uniqueE2E/native4/4/deployed passed; traffic confidence174 baseline reproduced/local guard passed; owned SQL9/9358ms/deploy175/1024compiled/live smoke passed; legacy history/provenance open; последующие изменения проверять отдельно; scoped axe не означает полную WCAG сертификацию |
Доказательства и точные ограничения: [полная история этапа12](ux-ui-stage-12.md), [внешний протокол](ux-ui-external-acceptance.md), [BGP93](ux-ui/acceptance/bgp-failover-2026-10-10.json), [паспорт стенда](ux-ui-test-server.md). Невыполненные пункты не являются все блокерами данного лабораторного сценария: для выпуска необходимо явно определить требуемые конфигурации и принять их либо согласовать ограничение.
@@ -900,3 +900,15 @@ Existing snapshot types уже имеют optional суммы; source decoder174
npm --prefix backend run test:traffic-rate прошёл: существующие формулы/observations, новый counter/rate/source guard и actual collectTrafficOnce body через AST с in-memory DB/HTTP boundaries (first wave, zero, reset, malformed/no insert, excluded interfaces). Извлечение исполняет исходный collector, не копию алгоритма; это не реальный PostgreSQL или RouterOS. npm --prefix backend run build прошёл. [Local check](ux-ui/acceptance/traffic-confidence-local-2026-10-12.json) фиксирует хеши изменённых source и границы доказательства. Full regression/remote deployment не выполнялись, поскольку изменён только локальный producer guard.
Следующий175: real MikrotikClient loopback HTTP→owned PostgreSQL→scheduler resultJson→source decoder с first-wave/next-zero/reset/malformed/mixed-interface controls; проверить очистку своих объектов и исключение stale historical samples. После profile acceptance собрать backend и развернуть guard на тестовом стенде; frontend ux-ping173 совместим с absent optional totals. Сейчас оба сервиса удалённого стенда всё ещё ux-ping173, native Ping4/4 подтверждён в173; новое исправление там ещё не доступно. Пароли, конфигурация CHR и тестовый runtime этим блоком не менялись. Локальный коммит без push.
## 12.5.175 — SQL/HTTP-приёмка достоверности трафика и развёртывание (2026-10-12)
Producer guard174 проверен через настоящий MikrotikClient к loopback HTTP simulator, actual collectTrafficOnce, PostgreSQL18.6 и buildSignalSnapshotFromCollectors. Девять SQL controls: first wave без суммы/со stored valid counters; следующая genuine zero; reset без суммы; malformed123bad и missing counter дают ok=false/no insert; новый второй интерфейс не даёт частичную сумму; следующая полная zero wave; положительная скорость; disabled server без outbound HTTP. Каждая актуальная wave сохраняется в scheduler_runs и проходит реальный source reader. Fixture clock не задерживает тест: в своей базе сохраняется только последняя baseline wave и сдвигается её время на30s. Это не проверка длинной historical continuity/retention и не физический RouterOS counter reset.
Профиль test:traffic-rate дополнен тестом traffic-observation-sql.test.ts. Локально SQL явно skipped без own database; удалённый Node22/PG18.6 профиль прошёл9358ms без SQL skip. База mm_accept_166_1791803283546 принадлежала временному LOGIN без SUPERUSER/CREATEDB/CREATEROLE/BYPASSRLS. Актуальные production DB/JWT secrets не копировались. Тестовые rows убраны finally, база/роль/container удалены trap и отсутствие DB/role проверено каталогами; остались только3 основные контейнера. [SQL](ux-ui/acceptance/traffic-confidence-sql-2026-10-12.json).
Production backend build прошёл локально и на Debian; [1024 compiled artifacts](ux-ui/acceptance/traffic-confidence-compiled-2026-10-12.json) совпали SHA256 с локальными, different/missing0. Backend ux-traffic175/version1.0.0-test.traffic175 развёрнут; frontend ux-ping173 сохранён и совместим с optional sums. До сборки исправлена строка Docker base, которую ошибочно заменила blanket tag substitution; неисправный Dockerfile не собирался и не выпускался. В.env менялся только BACKEND_IMAGE_TAG, rollback tag ux-ping173 сохранён без копии секретного env. [Runtime](ux-ui/acceptance/traffic-confidence-runtime-2026-10-12.json): verified imageIds, backend healthy/frontend running.
[Read-only live smoke](ux-ui/acceptance/traffic-confidence-deployed-2026-10-12.json): /traffic1440/320, traffic servers200/no pageerrors/no overflow; /servers,/traffic/servers,/scheduler/runs?jobKey=traffic200. Это проверка доступности/совместимости UI, не доказательство доставки Telegram или возникновения всех edge cases в main DB. Нет manual scheduler run/config/password/message writes; автоматический scheduler остаётся штатным. Пароли CHR не менялись; native Ping4/4 в обе стороны подтверждён ранее в173, здесь повторно не заявлен.
Следующий176 — inspect native compound durations53ms561us и parseFloat prefix fallback в Ping parser; положительные source payloads уже сохранены в173, не требуются новые сетевые сущности для первоначального доказательства. Legacy invalid traffic counters/raw-rate consumers, history freshness/failed attempt barriers, interface identity/config changes, scale/multiple backend и внешние интеграции остаются условиями12.5. Не считать guard174–175 полной приёмкой трафика. Локальный коммит без push.
+13 -1
View File
@@ -1,6 +1,6 @@
# Этап 12: итоговая приёмка UX/UI
Актуальное продолжение 2026-10-12: завершён локальный блок12.5.174 — воспроизведены ложные нули трафика; сумма scheduler snapshot выдаётся только при достоверных дельтах всех учитываемых интерфейсов, invalid counters отклоняются. Профиль traffic-rate (включая actual collector body) и backend production build прошли. Стенд остаётся ux-ping173; SQL/HTTP-приёмка producer и deployment нового guard — следующий175. Этап12.5 открыт.
Актуальное продолжение 2026-10-12: завершён12.5.175 — real HTTP client/traffic producer→owned PostgreSQL→scheduler JSON→source confidence,9 SQL controls passed за9358ms; ownDB/role/container удалены. Backend ux-traffic175 deployed/healthy, frontend ux-ping173;1024 compiled parity,2live UI/3API passed. Следующий176 — проверить compound RouterOS RTT duration parser по сохранённым native payloads; legacy counters/history freshness остаются открыты. Этап12.5 открыт.
План: [ux-ui-plan.md](ux-ui-plan.md). Фактические результаты: [ux-ui-progress.md](ux-ui-progress.md). Подготовлен после сводных проверок 11Б; завершение каждого блока требует локального коммита без push.
@@ -3290,3 +3290,15 @@ Existing snapshot types уже имеют optional суммы; source decoder174
npm --prefix backend run test:traffic-rate прошёл: существующие формулы/observations, новый counter/rate/source guard и actual collectTrafficOnce body через AST с in-memory DB/HTTP boundaries (first wave, zero, reset, malformed/no insert, excluded interfaces). Извлечение исполняет исходный collector, не копию алгоритма; это не реальный PostgreSQL или RouterOS. npm --prefix backend run build прошёл. [Local check](ux-ui/acceptance/traffic-confidence-local-2026-10-12.json) фиксирует хеши изменённых source и границы доказательства. Full regression/remote deployment не выполнялись, поскольку изменён только локальный producer guard.
Следующий175: real MikrotikClient loopback HTTP→owned PostgreSQL→scheduler resultJson→source decoder с first-wave/next-zero/reset/malformed/mixed-interface controls; проверить очистку своих объектов и исключение stale historical samples. После profile acceptance собрать backend и развернуть guard на тестовом стенде; frontend ux-ping173 совместим с absent optional totals. Сейчас оба сервиса удалённого стенда всё ещё ux-ping173, native Ping4/4 подтверждён в173; новое исправление там ещё не доступно. Пароли, конфигурация CHR и тестовый runtime этим блоком не менялись. Локальный коммит без push.
## 12.5.175 — SQL/HTTP-приёмка достоверности трафика и развёртывание (2026-10-12)
Producer guard174 проверен через настоящий MikrotikClient к loopback HTTP simulator, actual collectTrafficOnce, PostgreSQL18.6 и buildSignalSnapshotFromCollectors. Девять SQL controls: first wave без суммы/со stored valid counters; следующая genuine zero; reset без суммы; malformed123bad и missing counter дают ok=false/no insert; новый второй интерфейс не даёт частичную сумму; следующая полная zero wave; положительная скорость; disabled server без outbound HTTP. Каждая актуальная wave сохраняется в scheduler_runs и проходит реальный source reader. Fixture clock не задерживает тест: в своей базе сохраняется только последняя baseline wave и сдвигается её время на30s. Это не проверка длинной historical continuity/retention и не физический RouterOS counter reset.
Профиль test:traffic-rate дополнен тестом traffic-observation-sql.test.ts. Локально SQL явно skipped без own database; удалённый Node22/PG18.6 профиль прошёл9358ms без SQL skip. База mm_accept_166_1791803283546 принадлежала временному LOGIN без SUPERUSER/CREATEDB/CREATEROLE/BYPASSRLS. Актуальные production DB/JWT secrets не копировались. Тестовые rows убраны finally, база/роль/container удалены trap и отсутствие DB/role проверено каталогами; остались только3 основные контейнера. [SQL](ux-ui/acceptance/traffic-confidence-sql-2026-10-12.json).
Production backend build прошёл локально и на Debian; [1024 compiled artifacts](ux-ui/acceptance/traffic-confidence-compiled-2026-10-12.json) совпали SHA256 с локальными, different/missing0. Backend ux-traffic175/version1.0.0-test.traffic175 развёрнут; frontend ux-ping173 сохранён и совместим с optional sums. До сборки исправлена строка Docker base, которую ошибочно заменила blanket tag substitution; неисправный Dockerfile не собирался и не выпускался. В.env менялся только BACKEND_IMAGE_TAG, rollback tag ux-ping173 сохранён без копии секретного env. [Runtime](ux-ui/acceptance/traffic-confidence-runtime-2026-10-12.json): verified imageIds, backend healthy/frontend running.
[Read-only live smoke](ux-ui/acceptance/traffic-confidence-deployed-2026-10-12.json): /traffic1440/320, traffic servers200/no pageerrors/no overflow; /servers,/traffic/servers,/scheduler/runs?jobKey=traffic200. Это проверка доступности/совместимости UI, не доказательство доставки Telegram или возникновения всех edge cases в main DB. Нет manual scheduler run/config/password/message writes; автоматический scheduler остаётся штатным. Пароли CHR не менялись; native Ping4/4 в обе стороны подтверждён ранее в173, здесь повторно не заявлен.
Следующий176 — inspect native compound durations53ms561us и parseFloat prefix fallback в Ping parser; положительные source payloads уже сохранены в173, не требуются новые сетевые сущности для первоначального доказательства. Legacy invalid traffic counters/raw-rate consumers, history freshness/failed attempt barriers, interface identity/config changes, scale/multiple backend и внешние интеграции остаются условиями12.5. Не считать guard174–175 полной приёмкой трафика. Локальный коммит без push.
+14 -2
View File
@@ -1,6 +1,6 @@
# Тестовый сервер UX/UI — 2026-10-10
Сервер161.104.46.222: завершён локальный блок12.5.174 — воспроизведены ложные нули трафика; сумма scheduler snapshot выдаётся только при достоверных дельтах всех учитываемых интерфейсов, invalid counters отклоняются. Профиль traffic-rate (включая actual collector body) и backend production build прошли. Стенд остаётся ux-ping173; SQL/HTTP-приёмка producer и deployment нового guard — следующий175. Этап12.5 открыт.
Сервер161.104.46.222: завершён12.5.175 — real HTTP client/traffic producer→owned PostgreSQL→scheduler JSON→source confidence,9 SQL controls passed за9358ms; ownDB/role/container удалены. Backend ux-traffic175 deployed/healthy, frontend ux-ping173;1024 compiled parity,2live UI/3API passed. Следующий176 — проверить compound RouterOS RTT duration parser по сохранённым native payloads; legacy counters/history freshness остаются открыты. Этап12.5 открыт.
| Параметр | Проверенное состояние |
| --- | --- |
@@ -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-ping173 и mmapp-test/frontend:ux-ping173; запущены |
| Образы приложения | mmapp-test/backend:ux-traffic175 и mmapp-test/frontend:ux-ping173; запущены |
Compose SHA256:3052bd6ab5d9865f97605cebfb5ff27a4410cd3357b81153a65a87fb7c92582f. OptionalBACKEND_IMAGE_TAG позволяетобновлятьbackendотдельно. Локальный и удалённый файлы совпали. Шаблоны: [Compose](../deploy/docker-compose.test.yml), [env без секретов](../deploy/env.test.example).
@@ -1716,3 +1716,15 @@ Existing snapshot types уже имеют optional суммы; source decoder174
npm --prefix backend run test:traffic-rate прошёл: существующие формулы/observations, новый counter/rate/source guard и actual collectTrafficOnce body через AST с in-memory DB/HTTP boundaries (first wave, zero, reset, malformed/no insert, excluded interfaces). Извлечение исполняет исходный collector, не копию алгоритма; это не реальный PostgreSQL или RouterOS. npm --prefix backend run build прошёл. [Local check](ux-ui/acceptance/traffic-confidence-local-2026-10-12.json) фиксирует хеши изменённых source и границы доказательства. Full regression/remote deployment не выполнялись, поскольку изменён только локальный producer guard.
Следующий175: real MikrotikClient loopback HTTP→owned PostgreSQL→scheduler resultJson→source decoder с first-wave/next-zero/reset/malformed/mixed-interface controls; проверить очистку своих объектов и исключение stale historical samples. После profile acceptance собрать backend и развернуть guard на тестовом стенде; frontend ux-ping173 совместим с absent optional totals. Сейчас оба сервиса удалённого стенда всё ещё ux-ping173, native Ping4/4 подтверждён в173; новое исправление там ещё не доступно. Пароли, конфигурация CHR и тестовый runtime этим блоком не менялись. Локальный коммит без push.
## 12.5.175 — SQL/HTTP-приёмка достоверности трафика и развёртывание (2026-10-12)
Producer guard174 проверен через настоящий MikrotikClient к loopback HTTP simulator, actual collectTrafficOnce, PostgreSQL18.6 и buildSignalSnapshotFromCollectors. Девять SQL controls: first wave без суммы/со stored valid counters; следующая genuine zero; reset без суммы; malformed123bad и missing counter дают ok=false/no insert; новый второй интерфейс не даёт частичную сумму; следующая полная zero wave; положительная скорость; disabled server без outbound HTTP. Каждая актуальная wave сохраняется в scheduler_runs и проходит реальный source reader. Fixture clock не задерживает тест: в своей базе сохраняется только последняя baseline wave и сдвигается её время на30s. Это не проверка длинной historical continuity/retention и не физический RouterOS counter reset.
Профиль test:traffic-rate дополнен тестом traffic-observation-sql.test.ts. Локально SQL явно skipped без own database; удалённый Node22/PG18.6 профиль прошёл9358ms без SQL skip. База mm_accept_166_1791803283546 принадлежала временному LOGIN без SUPERUSER/CREATEDB/CREATEROLE/BYPASSRLS. Актуальные production DB/JWT secrets не копировались. Тестовые rows убраны finally, база/роль/container удалены trap и отсутствие DB/role проверено каталогами; остались только3 основные контейнера. [SQL](ux-ui/acceptance/traffic-confidence-sql-2026-10-12.json).
Production backend build прошёл локально и на Debian; [1024 compiled artifacts](ux-ui/acceptance/traffic-confidence-compiled-2026-10-12.json) совпали SHA256 с локальными, different/missing0. Backend ux-traffic175/version1.0.0-test.traffic175 развёрнут; frontend ux-ping173 сохранён и совместим с optional sums. До сборки исправлена строка Docker base, которую ошибочно заменила blanket tag substitution; неисправный Dockerfile не собирался и не выпускался. В.env менялся только BACKEND_IMAGE_TAG, rollback tag ux-ping173 сохранён без копии секретного env. [Runtime](ux-ui/acceptance/traffic-confidence-runtime-2026-10-12.json): verified imageIds, backend healthy/frontend running.
[Read-only live smoke](ux-ui/acceptance/traffic-confidence-deployed-2026-10-12.json): /traffic1440/320, traffic servers200/no pageerrors/no overflow; /servers,/traffic/servers,/scheduler/runs?jobKey=traffic200. Это проверка доступности/совместимости UI, не доказательство доставки Telegram или возникновения всех edge cases в main DB. Нет manual scheduler run/config/password/message writes; автоматический scheduler остаётся штатным. Пароли CHR не менялись; native Ping4/4 в обе стороны подтверждён ранее в173, здесь повторно не заявлен.
Следующий176 — inspect native compound durations53ms561us и parseFloat prefix fallback в Ping parser; положительные source payloads уже сохранены в173, не требуются новые сетевые сущности для первоначального доказательства. Legacy invalid traffic counters/raw-rate consumers, history freshness/failed attempt barriers, interface identity/config changes, scale/multiple backend и внешние интеграции остаются условиями12.5. Не считать guard174–175 полной приёмкой трафика. Локальный коммит без push.
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,41 @@
{
"date": "2026-10-12",
"block": "12.5.175",
"runtime": {
"backend": "ux-traffic175",
"frontend": "ux-ping173"
},
"apis": [
{
"path": "/api/servers",
"status": 200
},
{
"path": "/api/traffic/servers",
"status": 200
},
{
"path": "/api/scheduler/runs?jobKey=traffic&limit=1",
"status": 200
}
],
"cases": [
{
"width": 1440,
"trafficServers200": true,
"pageErrors": 0,
"noOverflow": true
},
{
"width": 320,
"trafficServers200": true,
"pageErrors": 0,
"noOverflow": true
}
],
"bounds": [
"Read-only smoke, no claim of physical counter reset/Telegram delivery",
"Producer edge states verified in owned SQL/HTTP simulator",
"No manual scheduler/config/password/message writes"
]
}
@@ -0,0 +1,24 @@
{
"date": "2026-10-12",
"block": "12.5.175",
"secretEnvCopied": false,
"services": {
"backend": {
"image": "mmapp-test/backend:ux-traffic175",
"imageId": "sha256:9227f029e30fed1ac14a362b0149474dbc58d9296a4375146029a5d96d2e713d",
"state": "running",
"health": "healthy",
"matchedVerifiedImage": true
},
"frontend": {
"image": "mmapp-test/frontend:ux-ping173",
"imageId": "sha256:b73d9cbd1e056839fe17b66f5f2b1324cd809fbc2699b4512fcd8040cc7501f3",
"state": "running",
"health": null,
"matchedVerifiedImage": true
}
},
"rollbackTags": {
"BACKEND_IMAGE_TAG": "ux-ping173"
}
}
@@ -0,0 +1,20 @@
{
"date": "2026-10-12",
"block": "12.5.175",
"database": "mm_accept_166_1791803283546",
"scope": "ephemeral role and precreated owned database; no copied production credentials",
"tests": [
{
"command": "npm --prefix backend run test:traffic-rate",
"passed": true,
"durationMs": 9358,
"ownedTrafficSqlCases": 9,
"postgresUnavailableSkip": false
}
],
"scopedRoleVerified": true,
"passed": true,
"databaseRemoved": true,
"roleRemoved": true,
"testContainerRemoved": true
}