chore(backend): добавить поддержку ACME и управление сертификатами

This commit is contained in:
Denozordec
2026-05-12 20:00:25 +07:00
parent bfceb07a23
commit d62d212c86
21 changed files with 2183 additions and 301 deletions
File diff suppressed because it is too large Load Diff
+35 -8
View File
@@ -289,8 +289,8 @@ function ProbeSourceCell({ probe, catalog }: { probe: PingProbe; catalog: Server
export default function DashboardPage() {
const pathname = usePathname()
const { mode, backendUrl } = useDataSource()
const isLive = mode === "live"
const { mode, backendUrl, prefsHydrated } = useDataSource()
const isLive = prefsHydrated && mode === "live"
const apiFetch = useMemo(() => makeApiFetch(backendUrl), [backendUrl])
const [liveProbes, setLiveProbes] = useState<PingProbe[] | null>(null)
@@ -306,9 +306,10 @@ export default function DashboardPage() {
const [internetPathError, setInternetPathError] = useState<string | null>(null)
const probeServerCatalog = useMemo(() => {
if (!prefsHydrated) return []
if (!isLive) return mockServers
return liveServersResolved ?? []
}, [isLive, liveServersResolved])
}, [prefsHydrated, isLive, liveServersResolved])
const fetchProbes = useCallback(async (silent: boolean) => {
if (!isLive) return
@@ -523,13 +524,15 @@ export default function DashboardPage() {
}, [mockDashEpoch])
const activeProbesTable = useMemo(() => {
if (!prefsHydrated) return []
if (!isLive) return mockActiveProbes
if (liveProbes === null && probesLoading) return []
if (liveProbes === null) return []
return liveProbes.filter((p) => p.enabled && p.showOnDashboard === true)
}, [isLive, liveProbes, probesLoading, mockActiveProbes])
}, [prefsHydrated, isLive, liveProbes, probesLoading, mockActiveProbes])
const probesSubtitle = useMemo(() => {
if (!prefsHydrated) return "Загрузка…"
if (!isLive) {
const starred = mockActiveProbes.length
return starred > 0
@@ -541,10 +544,13 @@ export default function DashboardPage() {
return n > 0
? `${n} на дашборде · последний час (API)`
: "Нет проб на дашборде · отметьте звёздочкой на странице мониторинга"
}, [isLive, mockActiveProbes.length, probesError, liveProbes, activeProbesTable.length])
}, [prefsHydrated, isLive, mockActiveProbes.length, probesError, liveProbes, activeProbesTable.length])
/** Карточка «Состояние серверов»: в Live — `/api/servers` (тот же запрос, что и для каталога проб). */
const serverStatusModel = useMemo(() => {
if (!prefsHydrated) {
return { kind: "loading" as const, subtitle: "Загрузка…" }
}
if (!isLive) {
return {
kind: "mock" as const,
@@ -571,9 +577,12 @@ export default function DashboardPage() {
servers,
subtitle: `${servers.length} узлов · ${onlineN} онлайн · API`,
}
}, [isLive, liveServersResolved, probesLoading, probesError])
}, [prefsHydrated, isLive, liveServersResolved, probesLoading, probesError])
const latencyChartBlock = useMemo(() => {
if (!prefsHydrated) {
return { kind: "loading" as const }
}
if (!isLive) {
return {
kind: "mock" as const,
@@ -612,7 +621,7 @@ export default function DashboardPage() {
subtitle:
"Средний RTT по источникам проб · окно 1 ч · до 8 узлов · API",
}
}, [isLive, liveProbes, probesLoading, liveServersResolved])
}, [prefsHydrated, isLive, liveProbes, probesLoading, liveServersResolved])
const dashboardKpi = useMemo(() => {
const sparkSrv = [5, 5, 6, 6, 5, 6, 6, 6, 7, 6, 6, 6, 6, 6, 6, 6, 6]
@@ -620,6 +629,24 @@ export default function DashboardPage() {
const sparkBgp = [7800, 7900, 8000, 8100, 8050, 8120, 8200, 8240, 8300, 8350, 8380, 8400, 8420, 8430, 8432]
const sparkAlt = [1, 2, 2, 3, 3, 4, 5, 4, 4, 4, 3, 3, 4, 4, 4]
const loadingKpi = (sparkColor: string) => ({
value: "—",
unit: undefined as string | undefined,
delta: "Загрузка…",
deltaDir: "up" as const,
spark: undefined as number[] | undefined,
sparkColor,
})
if (!prefsHydrated) {
return {
servers: loadingKpi("var(--chart-line-1)"),
filters: loadingKpi("var(--chart-line-2)"),
bgp: loadingKpi("var(--chart-line-4)"),
alerts: loadingKpi("var(--chart-5)"),
}
}
if (!isLive) {
const totalSrv = mockServers.length
const onlineSrv = mockServers.filter((s) => s.status === "online").length
@@ -730,7 +757,7 @@ export default function DashboardPage() {
sparkColor: "var(--chart-5)",
},
}
}, [isLive, liveServersResolved, liveKpi, liveProbes, probesLoading])
}, [prefsHydrated, isLive, liveServersResolved, liveKpi, liveProbes, probesLoading])
return (
<div className="flex flex-col h-full">