From 4c12c55c9d4ca1fda2b901193a4969ba0e33e797 Mon Sep 17 00:00:00 2001 From: Denozordec Date: Wed, 7 Oct 2026 23:37:06 +0700 Subject: [PATCH] =?UTF-8?q?fix(api):=20=D0=B8=D1=81=D0=BA=D0=BB=D1=8E?= =?UTF-8?q?=D1=87=D0=B8=D1=82=D1=8C=20=D0=B2=D1=8B=D0=BA=D0=BB=D1=8E=D1=87?= =?UTF-8?q?=D0=B5=D0=BD=D0=BD=D1=8B=D0=B5=20=D1=81=D0=B5=D1=80=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D1=8B=20=D0=B8=D0=B7=20=D0=BC=D0=BE=D0=BD=D0=B8=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=B8=D0=BD=D0=B3=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/services/monitoring-server-catalog.ts | 11 ++ .../services/servers-rest-ping-collector.ts | 12 +-- backend/src/services/uptime-collector.ts | 11 +- backend/src/services/uptime-speed-service.ts | 6 +- docs/ux-ui-external-acceptance.md | 4 + docs/ux-ui-plan.md | 2 +- docs/ux-ui-progress.md | 14 ++- docs/ux-ui-stage-12.md | 14 ++- docs/ux-ui-test-server.md | 4 + .../monitoring-enabled-2026-10-07.json | 100 ++++++++++++++++++ 10 files changed, 160 insertions(+), 18 deletions(-) create mode 100644 backend/src/services/monitoring-server-catalog.ts create mode 100644 docs/ux-ui/acceptance/monitoring-enabled-2026-10-07.json diff --git a/backend/src/services/monitoring-server-catalog.ts b/backend/src/services/monitoring-server-catalog.ts new file mode 100644 index 00000000..43c39859 --- /dev/null +++ b/backend/src/services/monitoring-server-catalog.ts @@ -0,0 +1,11 @@ +import { eq } from "drizzle-orm" +import { db } from "../db/index.js" +import { servers } from "../db/schema.js" + +export async function listEnabledMonitoringServers() { + return db.select().from(servers).where(eq(servers.enabled, true)) +} + +export function assertMonitoringServersEnabled(...targets: { enabled: boolean }[]): void { + if (targets.some(server => !server.enabled)) throw new Error("Сервер отключён: включите его перед запуском теста") +} diff --git a/backend/src/services/servers-rest-ping-collector.ts b/backend/src/services/servers-rest-ping-collector.ts index bd7135ba..689e11cf 100644 --- a/backend/src/services/servers-rest-ping-collector.ts +++ b/backend/src/services/servers-rest-ping-collector.ts @@ -1,6 +1,7 @@ -import { eq, or } from "drizzle-orm" +import { eq } from "drizzle-orm" +import { listEnabledMonitoringServers } from "./monitoring-server-catalog.js" import { db, dbAll, dbQuery } from "../db/index.js" -import { servers, serversApiPingSettings, serversRestPingSamples } from "../db/schema.js" +import { serversApiPingSettings, serversRestPingSamples } from "../db/schema.js" import type { ServersRestPingRunSnapshot } from "../types/scheduler-run-snapshot.js" import { SCHEDULER_RUN_SNAPSHOT_VERSION } from "../types/scheduler-run-snapshot.js" import { MikrotikClient } from "./mikrotik.js" @@ -21,12 +22,9 @@ async function getSettingsRow() { return (await db.select().from(serversApiPingSettings).where(eq(serversApiPingSettings.id, 1)).limit(1))[0] } -/** Как uptime: включённые в каталоге или Home Router (часто «выкл.» при доступе только из LAN). */ +/** Same enabled-only policy as uptime. */ async function serversForRestProbe() { - return await db - .select() - .from(servers) - .where(or(eq(servers.enabled, true), eq(servers.type, "home-router"))) + return listEnabledMonitoringServers() } export async function getServersApiPingSettings() { diff --git a/backend/src/services/uptime-collector.ts b/backend/src/services/uptime-collector.ts index 0d589c2d..70a46124 100644 --- a/backend/src/services/uptime-collector.ts +++ b/backend/src/services/uptime-collector.ts @@ -1,9 +1,9 @@ import { replacePingProbes } from "./ping-probe-replacement.js" import type { PingProbeWrite } from "@mmapp/contracts" -import { and, asc, eq, gte, inArray, max, or, sql } from "drizzle-orm" +import { and, asc, eq, gte, inArray, max, sql } from "drizzle-orm" +import { listEnabledMonitoringServers } from "./monitoring-server-catalog.js" import { db } from "../db/index.js" import { - servers, uptimeProbeSamples, uptimeProbes, uptimeResourceSamples, @@ -95,12 +95,9 @@ export function parsePing(results: Array<{ time?: string; status?: string; sent? return { avgRtt, loss, status } } -/** Узлы с REST-опросом для uptime: включённые в каталоге или любой Home Router (см. /servers — HR часто «выкл.» при доступе только из LAN). */ +/** Disabled excludes every server type from resource and ping collection. */ async function serversForUptimeRosPoll() { - return await db - .select() - .from(servers) - .where(or(eq(servers.enabled, true), eq(servers.type, "home-router"))) + return listEnabledMonitoringServers() } async function lastProbeSampleTimes(): Promise> { diff --git a/backend/src/services/uptime-speed-service.ts b/backend/src/services/uptime-speed-service.ts index 30642d20..88b0da45 100644 --- a/backend/src/services/uptime-speed-service.ts +++ b/backend/src/services/uptime-speed-service.ts @@ -87,6 +87,7 @@ export async function executeBandwidthSpeedTestInner(params: SpeedTestRunParams) const src = (await db.select().from(servers).where(eq(servers.id, srcId)).limit(1))[0] const dst = (await db.select().from(servers).where(eq(servers.id, dstId)).limit(1))[0] if (!src || !dst) throw new Error("Server not found") + assertMonitoringServersEnabled(src, dst) const protocol = params.protocol === "udp" ? "udp" : "tcp" const direction = params.direction === "transmit" || params.direction === "receive" ? params.direction : "both" @@ -284,7 +285,9 @@ export async function runScheduledSpeedProbesOnce(): Promise r.enabled !== false && r.srcServerId !== r.dstServerId) + const enabledIds = new Set((await listEnabledMonitoringServers()).map(server => server.id)) + const enabled = rows.filter((r) => r.enabled !== false && r.srcServerId !== r.dstServerId + && enabledIds.has(r.srcServerId) && enabledIds.has(r.dstServerId)) const protocol = (p: (typeof enabled)[number]) => (p.protocol === "udp" ? "udp" : "tcp") const direction = (p: (typeof enabled)[number]) => p.direction === "transmit" || p.direction === "receive" ? p.direction : "both" @@ -356,3 +359,4 @@ export async function runScheduledSpeedProbesOnce(): Promise