fix(api): проверить каталог speed-проб и изолировать источник

This commit is contained in:
Denozordec committed 2026-10-04 10:31:02 +07:00
1 parent f30319ac55
commit d4f2961f76
13 files changed
+123 -51

No files matched your search

@@ -0,0 +1,8 @@
import { test } from "node:test"
import assert from "node:assert/strict"
import { mapSpeedProbeRead } from "./speed-probe-dto.js"
import type { UptimeSpeedProbeRow } from "../db/schema.js"
const row:UptimeSpeedProbeRow={id:"probe-1",srcServerId:1,dstServerId:2,srcInterface:"",dstInterface:"",protocol:"tcp",direction:"both",durationSec:10,enabled:false,lastRunAt:null,lastTxAvgMbps:null,lastRxAvgMbps:0,lastStatus:null,lastError:null,lastPingRttMs:null,lastPingLossPct:0,lastPingAt:null,lastPingError:null,sortOrder:0,createdAt:"2026-10-04T00:00:00Z",updatedAt:"2026-10-04T00:00:00Z"}
test("Speed probe: null/zero/disabled и неизвестный status не подменяются",()=>{const dto=mapSpeedProbeRead(row);assert.equal(dto.enabled,false);assert.equal(dto.lastTxAvgMbps,null);assert.equal(dto.lastRxAvgMbps,0);assert.equal(dto.lastStatus,null);assert.equal(dto.lastPingRttMs,null);assert.equal(dto.lastPingLossPct,0)})
test("Speed probe: timestamp PostgreSQL сохраняет instant",()=>{assert.equal(mapSpeedProbeRead({...row,lastRunAt:"2026-10-04 07:00:00+07"}).lastRunAt,"2026-10-04T00:00:00.000Z")})
test("Speed probe: некорректная DB запись отклоняется без fallback",()=>{for(const raw of [{...row,protocol:"bad"},{...row,direction:"bad"},{...row,durationSec:0},{...row,enabled:null},{...row,lastStatus:"bad"},{...row,lastTxAvgMbps:-1},{...row,lastRunAt:"bad"},{...row,srcServerId:0}])assert.throws(()=>mapSpeedProbeRead(raw as UptimeSpeedProbeRow))})
+13
View File
@@ -0,0 +1,13 @@
import { speedProbeReadSchema } from "@mmapp/contracts"
import type { UptimeSpeedProbeRow } from "../db/schema.js"
const timestamp = (value: string | null) => value === null ? null : new Date(value).toISOString()
export function mapSpeedProbeRead(row: UptimeSpeedProbeRow) {
return speedProbeReadSchema.parse({
id: row.id, srcServerId: String(row.srcServerId), dstServerId: String(row.dstServerId),
srcInterface: row.srcInterface, dstInterface: row.dstInterface,
protocol: row.protocol, direction: row.direction, durationSec: String(row.durationSec), enabled: row.enabled,
lastRunAt: timestamp(row.lastRunAt), lastTxAvgMbps: row.lastTxAvgMbps, lastRxAvgMbps: row.lastRxAvgMbps,
lastStatus: row.lastStatus, lastError: row.lastError,
lastPingRttMs: row.lastPingRttMs, lastPingLossPct: row.lastPingLossPct, lastPingAt: timestamp(row.lastPingAt), lastPingError: row.lastPingError,
})
}