93 lines
4.1 KiB
TypeScript
93 lines
4.1 KiB
TypeScript
import Fastify from "fastify"
|
|
import cors from "@fastify/cors"
|
|
import { serializerCompiler, validatorCompiler } from "@fastify/type-provider-zod"
|
|
import { env } from "./config.js"
|
|
import serversRoutes from "./routes/servers.js"
|
|
import bgpRoutes from "./routes/bgp.js"
|
|
import ospfRoutes from "./routes/ospf.js"
|
|
import execRoutes from "./routes/exec.js"
|
|
import filtersRoutes from "./routes/filters.js"
|
|
import recursiveRoutes from "./routes/recursive-routes.js"
|
|
import trafficRoutes from "./routes/traffic.js"
|
|
import serversApiPingRoutes from "./routes/servers-api-ping.js"
|
|
import uptimeRoutes from "./routes/uptime.js"
|
|
import networkRoutes from "./routes/network.js"
|
|
import internetPathRoutes from "./routes/internet-path.js"
|
|
import evobgpRoutes from "./routes/evobgp.js"
|
|
import probesRoutes from "./routes/probes.js"
|
|
import schedulerRoutes from "./routes/scheduler.js"
|
|
import sidebarCountsRoutes from "./routes/sidebar-counts.js"
|
|
import alertsRoutes from "./routes/alerts.js"
|
|
import backupsRoutes from "./routes/backups.js"
|
|
import certificatesRoutes from "./routes/certificates.js"
|
|
import systemDatabaseRoutes from "./routes/system-database.js"
|
|
import eventsRoutes from "./routes/events.js"
|
|
import { refreshScheduler, stopScheduler } from "./services/scheduler.js"
|
|
|
|
// ── app factory ────────────────────────────────────────────────────────────────
|
|
|
|
const app = Fastify({
|
|
logger: {
|
|
transport: {
|
|
target: "pino-pretty",
|
|
options: { colorize: true, translateTime: "HH:MM:ss", ignore: "pid,hostname" },
|
|
},
|
|
},
|
|
})
|
|
|
|
// Use Zod for request validation and response serialization
|
|
app.setValidatorCompiler(validatorCompiler)
|
|
app.setSerializerCompiler(serializerCompiler)
|
|
|
|
// CORS — allow Next.js frontend
|
|
await app.register(cors, {
|
|
origin: env.CORS_ORIGIN,
|
|
/** PATCH — для /api/uptime/probes/:id (звезда на дашборде); без этого браузер режет preflight */
|
|
methods: ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
|
|
})
|
|
|
|
// ── routes ─────────────────────────────────────────────────────────────────────
|
|
|
|
app.get("/health", async () => ({
|
|
status: "ok",
|
|
timestamp: new Date().toISOString(),
|
|
version: process.env.APP_VERSION ?? "dev",
|
|
}))
|
|
|
|
await app.register(serversRoutes, { prefix: "/api/servers" })
|
|
await app.register(bgpRoutes, { prefix: "/api" })
|
|
await app.register(ospfRoutes, { prefix: "/api" })
|
|
await app.register(execRoutes, { prefix: "/api" })
|
|
await app.register(filtersRoutes, { prefix: "/api" })
|
|
await app.register(recursiveRoutes, { prefix: "/api" })
|
|
await app.register(trafficRoutes, { prefix: "/api" })
|
|
await app.register(serversApiPingRoutes, { prefix: "/api" })
|
|
await app.register(uptimeRoutes, { prefix: "/api" })
|
|
await app.register(networkRoutes, { prefix: "/api" })
|
|
await app.register(internetPathRoutes, { prefix: "/api" })
|
|
await app.register(evobgpRoutes, { prefix: "/api" })
|
|
await app.register(probesRoutes, { prefix: "/api" })
|
|
await app.register(schedulerRoutes, { prefix: "/api" })
|
|
await app.register(sidebarCountsRoutes, { prefix: "/api" })
|
|
await app.register(alertsRoutes, { prefix: "/api" })
|
|
await app.register(backupsRoutes, { prefix: "/api" })
|
|
await app.register(certificatesRoutes, { prefix: "/api" })
|
|
await app.register(systemDatabaseRoutes, { prefix: "/api" })
|
|
await app.register(eventsRoutes, { prefix: "/api" })
|
|
|
|
refreshScheduler()
|
|
app.addHook("onClose", async () => {
|
|
stopScheduler()
|
|
})
|
|
|
|
// ── start ──────────────────────────────────────────────────────────────────────
|
|
|
|
try {
|
|
await app.listen({ port: env.PORT, host: "0.0.0.0" })
|
|
console.log(`\n🚀 MikroTik Manager Backend running at http://localhost:${env.PORT}`)
|
|
console.log(` Docs / test: http://localhost:${env.PORT}/health`)
|
|
} catch (err) {
|
|
app.log.error(err)
|
|
process.exit(1)
|
|
}
|