Files
MikrotikManager/backend/src/routes/speed-test.ts
T

35 lines
2.0 KiB
TypeScript

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>
run: (command: SpeedTestCommand) => Promise<SpeedTestRunResult>
failure: (command: SpeedTestCommand & { message: string }) => Promise<void>
}): FastifyPluginAsyncZod {
return async app => {
app.post("/uptime/speed-test", async (req, reply) => {
const parsed = speedTestCommandSchema.safeParse(req.body)
if (!parsed.success) return reply.code(400).send({ error: "Проверьте источник, назначение, протокол, направление и целую длительность теста от 3 секунд." })
const command = parsed.data
const exists = await Promise.all([deps.serverExists(command.srcServerId), deps.serverExists(command.dstServerId)])
if (exists.some(value => !value)) return reply.code(404).send({ error: "Server not found" })
try {
return reply.send({ ok: true, result: await deps.run(command) })
} catch (error) {
if (error instanceof SpeedRunPersistenceUnknown) {
return reply.code(502).send({ error: error.message, outcome: "unknown", runId: error.runId })
}
const raw = error instanceof Error ? error.message : "Bandwidth test failed"
await deps.failure({ ...command, message: 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 })
}
})
}
}