Files
MikrotikManager/backend/src/routes/internet-path.ts
T
DenozordecandCursor ec43591a99
Docker images / prepare-release (push) Successful in 12s
Docker images / backend-test (push) Successful in 4m9s
Docker images / frontend-image (push) Successful in 4m28s
Docker images / updater-image (push) Successful in 58s
Docker images / backend-image (push) Successful in 2m49s
Docker images / notify-webhook (push) Skipped
Docker images / publish-release (push) Successful in 11s
feat(db): перевести хранилище с SQLite на PostgreSQL
При старте backend накатывает схему PostgreSQL 18 и, если база пустая, один раз импортирует mikrotik.db с тома. Повторный старт не копирует данные. Бэкап в UI идёт через pg_dump.

Co-authored-by: Cursor <[email protected]>
2026-09-08 01:36:48 +07:00

66 lines
2.1 KiB
TypeScript

import type { FastifyPluginAsyncZod } from "@fastify/type-provider-zod"
import { refreshScheduler } from "../services/scheduler.js"
import {
getInternetPathSettings,
getLatestInternetPathSnapshot,
updateInternetPathSettings,
} from "../services/internet-path-collector.js"
const internetPathRoutes: FastifyPluginAsyncZod = async (app) => {
app.get("/internet-path/settings", async (_req, reply) => {
const s = await getInternetPathSettings()
return reply.send({
enabled: s.enabled,
intervalSec: s.intervalSec,
retentionDays: s.retentionDays,
lastCollectedAt: s.lastCollectedAt ?? null,
lastDurationMs: s.lastDurationMs ?? null,
lastError: s.lastError || null,
})
})
app.put("/internet-path/settings", async (req, reply) => {
const body = req.body as {
enabled?: boolean
intervalSec?: number | string
retentionDays?: number | string
}
const updated = await updateInternetPathSettings({
enabled: body.enabled,
intervalSec: body.intervalSec == null ? undefined : Math.max(30, Number.parseInt(String(body.intervalSec), 10) || 300),
retentionDays: body.retentionDays == null ? undefined : Math.max(1, Number.parseInt(String(body.retentionDays), 10) || 14),
})
await refreshScheduler()
return reply.send({
ok: true,
settings: {
enabled: updated.enabled,
intervalSec: updated.intervalSec,
retentionDays: updated.retentionDays,
lastCollectedAt: updated.lastCollectedAt ?? null,
lastDurationMs: updated.lastDurationMs ?? null,
lastError: updated.lastError || null,
},
})
})
app.get("/internet-path/latest", async (_req, reply) => {
const row = await getLatestInternetPathSnapshot()
if (!row) return reply.send({ snapshot: null })
let payload: unknown = row.payloadJson
if (typeof row.payloadJson === "string") {
try {
payload = JSON.parse(row.payloadJson)
} catch {
payload = null
}
}
return reply.send({
snapshot: payload,
sampledAt: row.sampledAt,
})
})
}
export default internetPathRoutes