import { eq } from "drizzle-orm"; import { appSwitcherConfigSchema, type AppSwitcherConfig } from "@cfdm/shared"; import type { Db } from "./client.js"; import { appSettings } from "./schema.js"; const SETTINGS_ID = "settings-main"; const DEFAULT_APP_SWITCHER: AppSwitcherConfig = { menuLabel: "Приложения", apps: [ { id: "vps-tracker", name: "VPS Tracker", subtitle: "Учёт виртуальных серверов", url: "http://192.168.100.67:3001", icon: "server", shortcut: "⌘1", }, { id: "cfdm", name: "CF Domain Manager", subtitle: "Управление доменами", url: "http://192.168.100.67:6363", icon: "cloud", shortcut: "⌘2", }, ], }; export type AppSettingsDto = { id: string; appSwitcher: AppSwitcherConfig; vpsTrackerUrl: string; vpsTrackerIntegrationTokenSet: boolean; vpsTrackerSyncEnabled: boolean; vpsTrackerLastSyncAt: string | null; }; export type AppSettingsPatch = { appSwitcher?: AppSwitcherConfig; vpsTrackerUrl?: string; vpsTrackerIntegrationToken?: string; vpsTrackerSyncEnabled?: boolean; }; function parseAppSwitcher(raw: string | null | undefined): AppSwitcherConfig { if (!raw?.trim()) return DEFAULT_APP_SWITCHER; try { return appSwitcherConfigSchema.parse(JSON.parse(raw)); } catch { return DEFAULT_APP_SWITCHER; } } function toDto(row: typeof appSettings.$inferSelect): AppSettingsDto { return { id: row.id, appSwitcher: parseAppSwitcher(row.app_switcher_json), vpsTrackerUrl: row.vps_tracker_url?.trim() ?? "", vpsTrackerIntegrationTokenSet: Boolean( row.vps_tracker_integration_token?.trim(), ), vpsTrackerSyncEnabled: Boolean(row.vps_tracker_sync_enabled), vpsTrackerLastSyncAt: row.vps_tracker_last_sync_at, }; } export function getAppSettings(db: Db): AppSettingsDto { const row = db .select() .from(appSettings) .where(eq(appSettings.id, SETTINGS_ID)) .get(); if (!row) { db.insert(appSettings).values({ id: SETTINGS_ID }).run(); return toDto( db.select().from(appSettings).where(eq(appSettings.id, SETTINGS_ID)).get()!, ); } return toDto(row); } export function getAppSettingsSecrets(db: Db): { vpsTrackerUrl: string; vpsTrackerIntegrationToken: string; vpsTrackerSyncEnabled: boolean; } { const row = db .select() .from(appSettings) .where(eq(appSettings.id, SETTINGS_ID)) .get(); return { vpsTrackerUrl: row?.vps_tracker_url?.trim() ?? "", vpsTrackerIntegrationToken: row?.vps_tracker_integration_token?.trim() ?? "", vpsTrackerSyncEnabled: Boolean(row?.vps_tracker_sync_enabled), }; } export function updateAppSettings(db: Db, patch: AppSettingsPatch): AppSettingsDto { const existing = db .select() .from(appSettings) .where(eq(appSettings.id, SETTINGS_ID)) .get(); if (!existing) { db.insert(appSettings).values({ id: SETTINGS_ID }).run(); } const current = db .select() .from(appSettings) .where(eq(appSettings.id, SETTINGS_ID)) .get()!; db.update(appSettings) .set({ app_switcher_json: patch.appSwitcher !== undefined ? JSON.stringify(patch.appSwitcher) : current.app_switcher_json, vps_tracker_url: patch.vpsTrackerUrl !== undefined ? patch.vpsTrackerUrl : current.vps_tracker_url, vps_tracker_integration_token: patch.vpsTrackerIntegrationToken !== undefined && patch.vpsTrackerIntegrationToken.trim() !== "" ? patch.vpsTrackerIntegrationToken : current.vps_tracker_integration_token, vps_tracker_sync_enabled: patch.vpsTrackerSyncEnabled !== undefined ? patch.vpsTrackerSyncEnabled : current.vps_tracker_sync_enabled, updated_at: new Date().toISOString(), }) .where(eq(appSettings.id, SETTINGS_ID)) .run(); return getAppSettings(db); } export function touchVpsTrackerSync(db: Db): void { db.update(appSettings) .set({ vps_tracker_last_sync_at: new Date().toISOString(), updated_at: new Date().toISOString(), }) .where(eq(appSettings.id, SETTINGS_ID)) .run(); } export function getAppSwitcher(db: Db): AppSwitcherConfig { return getAppSettings(db).appSwitcher; }