diff --git a/backend/app/version.py b/backend/app/version.py index 1b3feb1..39ad46f 100644 --- a/backend/app/version.py +++ b/backend/app/version.py @@ -1,5 +1,5 @@ """Единый источник версии SAC (API, health, логи, OpenAPI).""" APP_NAME = "Security Alert Center" -APP_VERSION = "0.9.3" +APP_VERSION = "0.9.4" APP_VERSION_LABEL = f"{APP_NAME} v.{APP_VERSION}" diff --git a/frontend/src/components/AppSidebar.vue b/frontend/src/components/AppSidebar.vue index 9bbf8d1..cca7836 100644 --- a/frontend/src/components/AppSidebar.vue +++ b/frontend/src/components/AppSidebar.vue @@ -34,10 +34,9 @@ import { computed } from "vue"; import { useRoute, useRouter } from "vue-router"; import { clearToken, isAdmin } from "../api"; import SidebarSystemStats from "./SidebarSystemStats.vue"; -import { APP_NAME, APP_VERSION } from "../version"; +import { useSacVersion } from "../composables/useSacVersion"; -const appName = APP_NAME; -const appVersion = APP_VERSION; +const { appName, appVersion } = useSacVersion(); const route = useRoute(); const router = useRouter(); diff --git a/frontend/src/composables/useSacVersion.ts b/frontend/src/composables/useSacVersion.ts new file mode 100644 index 0000000..e9280d4 --- /dev/null +++ b/frontend/src/composables/useSacVersion.ts @@ -0,0 +1,57 @@ +import { onMounted, ref } from "vue"; +import { APP_NAME, APP_VERSION } from "../version"; + +export interface SacVersionInfo { + name: string; + version: string; +} + +let cached: SacVersionInfo | null = null; +let inflight: Promise | null = null; + +async function fetchSacVersion(): Promise { + if (cached) { + return cached; + } + if (inflight) { + return inflight; + } + + inflight = (async () => { + const fallback: SacVersionInfo = { name: APP_NAME, version: APP_VERSION }; + try { + const response = await fetch("/health"); + if (!response.ok) { + return fallback; + } + const data = (await response.json()) as { name?: string; version?: string }; + const info: SacVersionInfo = { + name: (data.name || APP_NAME).trim() || APP_NAME, + version: (data.version || APP_VERSION).trim() || APP_VERSION, + }; + cached = info; + return info; + } catch { + return fallback; + } finally { + inflight = null; + } + })(); + + return inflight; +} + +/** Версия SAC с бэкенда (/health); fallback — frontend/src/version.ts */ +export function useSacVersion() { + const appName = ref(APP_NAME); + const appVersion = ref(APP_VERSION); + + onMounted(() => { + void fetchSacVersion().then((info) => { + appName.value = info.name; + appVersion.value = info.version; + }); + }); + + return { appName, appVersion }; +} diff --git a/frontend/src/version.ts b/frontend/src/version.ts index 76f7eda..b1432df 100644 --- a/frontend/src/version.ts +++ b/frontend/src/version.ts @@ -1,3 +1,4 @@ +/** Fallback до загрузки /health; при релизе держите в sync с backend/app/version.py */ export const APP_NAME = "Security Alert Center"; -export const APP_VERSION = "0.9.3"; +export const APP_VERSION = "0.9.4"; export const APP_VERSION_LABEL = `${APP_NAME} v.${APP_VERSION}`; diff --git a/frontend/src/views/DashboardView.vue b/frontend/src/views/DashboardView.vue index 3024785..d918210 100644 --- a/frontend/src/views/DashboardView.vue +++ b/frontend/src/views/DashboardView.vue @@ -1,6 +1,7 @@