Files
cloudflare-domain-manager/packages/db/src/settings-repo.ts
T
DenozordecandCursor 96783386e0
Build, Test, and Push CFDM Docker Image / test (push) Failing after 3m36s
Build, Test, and Push CFDM Docker Image / build-and-push (push) Has been skipped
Build, Test, and Push CFDM Docker Image / update-wiki (push) Has been skipped
Build, Test, and Push CFDM Docker Image / create-release (push) Has been skipped
feat: интеграция с VPS Tracker
Исходящий sync bindings после updateConfig, настройки в app_settings, страница Интеграции, приём событий vps_down для DNS failover.

Co-authored-by: Cursor <[email protected]>
2026-06-30 16:45:17 +07:00

156 lines
4.3 KiB
TypeScript

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;
}