Init 2
This commit is contained in:
@@ -81,6 +81,8 @@ CREATE TABLE IF NOT EXISTS uptime_settings (
|
||||
id INTEGER PRIMARY KEY,
|
||||
enabled INTEGER NOT NULL DEFAULT 1,
|
||||
interval_sec INTEGER NOT NULL DEFAULT 15,
|
||||
probe_interval_sec INTEGER NOT NULL DEFAULT 15,
|
||||
speed_interval_sec INTEGER NOT NULL DEFAULT 60,
|
||||
retention_days INTEGER NOT NULL DEFAULT 14,
|
||||
last_collected_at TEXT,
|
||||
last_duration_ms INTEGER,
|
||||
@@ -97,6 +99,7 @@ CREATE TABLE IF NOT EXISTS uptime_probes (
|
||||
target TEXT NOT NULL,
|
||||
probe_filter TEXT NOT NULL DEFAULT '—',
|
||||
enabled INTEGER NOT NULL DEFAULT 1,
|
||||
show_on_dashboard INTEGER NOT NULL DEFAULT 0,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
@@ -134,6 +137,66 @@ CREATE TABLE IF NOT EXISTS uptime_resource_samples (
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_uptime_resource_samples_server_time
|
||||
ON uptime_resource_samples(server_id, sampled_at);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS uptime_speed_probes (
|
||||
id TEXT PRIMARY KEY,
|
||||
src_server_id INTEGER NOT NULL,
|
||||
dst_server_id INTEGER NOT NULL,
|
||||
src_interface TEXT NOT NULL DEFAULT '',
|
||||
dst_interface TEXT NOT NULL DEFAULT '',
|
||||
protocol TEXT NOT NULL DEFAULT 'tcp',
|
||||
direction TEXT NOT NULL DEFAULT 'both',
|
||||
duration_sec INTEGER NOT NULL DEFAULT 10,
|
||||
enabled INTEGER NOT NULL DEFAULT 1,
|
||||
last_run_at TEXT,
|
||||
last_tx_avg_mbps REAL,
|
||||
last_rx_avg_mbps REAL,
|
||||
last_status TEXT,
|
||||
last_error TEXT,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
FOREIGN KEY (src_server_id) REFERENCES servers(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (dst_server_id) REFERENCES servers(id) ON DELETE CASCADE
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_uptime_speed_probes_src_sort
|
||||
ON uptime_speed_probes(src_server_id, sort_order);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS uptime_speed_test_runs (
|
||||
id TEXT PRIMARY KEY,
|
||||
probe_id TEXT,
|
||||
src_server_id INTEGER NOT NULL,
|
||||
dst_server_id INTEGER NOT NULL,
|
||||
src_interface TEXT NOT NULL DEFAULT '',
|
||||
dst_interface TEXT NOT NULL DEFAULT '',
|
||||
src_address TEXT,
|
||||
dst_address TEXT,
|
||||
src_interface_address TEXT,
|
||||
dst_interface_address TEXT,
|
||||
protocol TEXT NOT NULL DEFAULT 'tcp',
|
||||
direction TEXT NOT NULL DEFAULT 'both',
|
||||
duration_sec INTEGER NOT NULL DEFAULT 10,
|
||||
tx_avg_mbps REAL,
|
||||
rx_avg_mbps REAL,
|
||||
ping_rtt_ms INTEGER,
|
||||
ping_loss_pct INTEGER,
|
||||
ping_error TEXT,
|
||||
status TEXT NOT NULL DEFAULT 'done',
|
||||
error TEXT,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
FOREIGN KEY (src_server_id) REFERENCES servers(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (dst_server_id) REFERENCES servers(id) ON DELETE CASCADE
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_uptime_speed_test_runs_created_at
|
||||
ON uptime_speed_test_runs(created_at);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS evobgp_settings (
|
||||
id INTEGER PRIMARY KEY,
|
||||
base_url TEXT NOT NULL DEFAULT '',
|
||||
api_key TEXT NOT NULL DEFAULT '',
|
||||
enabled INTEGER NOT NULL DEFAULT 0,
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
`)
|
||||
|
||||
// Lightweight schema evolution for existing databases without migrations
|
||||
@@ -148,6 +211,42 @@ const hasSrcInterfaceColumn = uptimeProbeCols.some((c) => c.name === "src_interf
|
||||
if (!hasSrcInterfaceColumn) {
|
||||
sqlite.exec(`ALTER TABLE uptime_probes ADD COLUMN src_interface TEXT NOT NULL DEFAULT ''`)
|
||||
}
|
||||
const hasShowOnDashboardColumn = uptimeProbeCols.some((c) => c.name === "show_on_dashboard")
|
||||
if (!hasShowOnDashboardColumn) {
|
||||
sqlite.exec(`ALTER TABLE uptime_probes ADD COLUMN show_on_dashboard INTEGER NOT NULL DEFAULT 0`)
|
||||
}
|
||||
|
||||
const uptimeSettingsCols = sqlite.prepare(`PRAGMA table_info('uptime_settings')`).all() as Array<{ name?: string }>
|
||||
const hasProbeIntervalColumn = uptimeSettingsCols.some((c) => c.name === "probe_interval_sec")
|
||||
if (!hasProbeIntervalColumn) {
|
||||
sqlite.exec(`ALTER TABLE uptime_settings ADD COLUMN probe_interval_sec INTEGER NOT NULL DEFAULT 15`)
|
||||
}
|
||||
const hasSpeedIntervalColumn = uptimeSettingsCols.some((c) => c.name === "speed_interval_sec")
|
||||
if (!hasSpeedIntervalColumn) {
|
||||
sqlite.exec(`ALTER TABLE uptime_settings ADD COLUMN speed_interval_sec INTEGER NOT NULL DEFAULT 60`)
|
||||
}
|
||||
|
||||
const uptimeSpeedProbeCols = sqlite.prepare(`PRAGMA table_info('uptime_speed_probes')`).all() as Array<{ name?: string }>
|
||||
const ensureSpeedProbeCol = (name: string, ddl: string) => {
|
||||
if (!uptimeSpeedProbeCols.some((c) => c.name === name)) sqlite.exec(ddl)
|
||||
}
|
||||
ensureSpeedProbeCol("last_run_at", `ALTER TABLE uptime_speed_probes ADD COLUMN last_run_at TEXT`)
|
||||
ensureSpeedProbeCol("last_tx_avg_mbps", `ALTER TABLE uptime_speed_probes ADD COLUMN last_tx_avg_mbps REAL`)
|
||||
ensureSpeedProbeCol("last_rx_avg_mbps", `ALTER TABLE uptime_speed_probes ADD COLUMN last_rx_avg_mbps REAL`)
|
||||
ensureSpeedProbeCol("last_status", `ALTER TABLE uptime_speed_probes ADD COLUMN last_status TEXT`)
|
||||
ensureSpeedProbeCol("last_error", `ALTER TABLE uptime_speed_probes ADD COLUMN last_error TEXT`)
|
||||
ensureSpeedProbeCol("last_ping_rtt_ms", `ALTER TABLE uptime_speed_probes ADD COLUMN last_ping_rtt_ms INTEGER`)
|
||||
ensureSpeedProbeCol("last_ping_loss_pct", `ALTER TABLE uptime_speed_probes ADD COLUMN last_ping_loss_pct INTEGER`)
|
||||
ensureSpeedProbeCol("last_ping_at", `ALTER TABLE uptime_speed_probes ADD COLUMN last_ping_at TEXT`)
|
||||
ensureSpeedProbeCol("last_ping_error", `ALTER TABLE uptime_speed_probes ADD COLUMN last_ping_error TEXT`)
|
||||
|
||||
const serverCols = sqlite.prepare(`PRAGMA table_info('servers')`).all() as Array<{ name?: string }>
|
||||
if (!serverCols.some((c) => c.name === "lan_subnet")) {
|
||||
sqlite.exec(`ALTER TABLE servers ADD COLUMN lan_subnet TEXT NOT NULL DEFAULT ''`)
|
||||
}
|
||||
if (!serverCols.some((c) => c.name === "wan_uplinks")) {
|
||||
sqlite.exec(`ALTER TABLE servers ADD COLUMN wan_uplinks TEXT NOT NULL DEFAULT '[]'`)
|
||||
}
|
||||
|
||||
sqlite.exec(`
|
||||
INSERT INTO traffic_settings (id, enabled, interval_sec, retention_days)
|
||||
@@ -161,4 +260,10 @@ SELECT 1, 1, 15, 14
|
||||
WHERE NOT EXISTS (SELECT 1 FROM uptime_settings WHERE id = 1);
|
||||
`)
|
||||
|
||||
sqlite.exec(`
|
||||
INSERT INTO evobgp_settings (id, base_url, api_key, enabled)
|
||||
SELECT 1, '', '', 0
|
||||
WHERE NOT EXISTS (SELECT 1 FROM evobgp_settings WHERE id = 1);
|
||||
`)
|
||||
|
||||
export const db = drizzle(sqlite, { schema })
|
||||
|
||||
@@ -27,6 +27,11 @@ export const servers = sqliteTable("servers", {
|
||||
comment: text("comment").notNull().default(""),
|
||||
enabled: integer("enabled", { mode: "boolean" }).notNull().default(true),
|
||||
|
||||
/** Подсеть LAN (home-router), текст из формы */
|
||||
lanSubnet: text("lan_subnet").notNull().default(""),
|
||||
/** JSON-массив WAN-аплинков [{ id, name, isp, iface, ip, maxDl, maxUl }, …] */
|
||||
wanUplinks: text("wan_uplinks").notNull().default("[]"),
|
||||
|
||||
createdAt: text("created_at").notNull().default(sql`(datetime('now'))`),
|
||||
updatedAt: text("updated_at").notNull().default(sql`(datetime('now'))`),
|
||||
})
|
||||
@@ -133,6 +138,8 @@ export const uptimeSettings = sqliteTable("uptime_settings", {
|
||||
id: integer("id").primaryKey(),
|
||||
enabled: integer("enabled", { mode: "boolean" }).notNull().default(true),
|
||||
intervalSec: integer("interval_sec").notNull().default(15),
|
||||
probeIntervalSec: integer("probe_interval_sec").notNull().default(15),
|
||||
speedIntervalSec: integer("speed_interval_sec").notNull().default(60),
|
||||
retentionDays: integer("retention_days").notNull().default(14),
|
||||
lastCollectedAt: text("last_collected_at"),
|
||||
lastDurationMs: integer("last_duration_ms"),
|
||||
@@ -151,6 +158,8 @@ export const uptimeProbes = sqliteTable("uptime_probes", {
|
||||
target: text("target").notNull(),
|
||||
probeFilter: text("probe_filter").notNull().default("—"),
|
||||
enabled: integer("enabled", { mode: "boolean" }).notNull().default(true),
|
||||
/** Выводить пробу в блоке «Активные пробы» на дашборде */
|
||||
showOnDashboard: integer("show_on_dashboard", { mode: "boolean" }).notNull().default(false),
|
||||
sortOrder: integer("sort_order").notNull().default(0),
|
||||
createdAt: text("created_at").notNull().default(sql`(datetime('now'))`),
|
||||
updatedAt: text("updated_at").notNull().default(sql`(datetime('now'))`),
|
||||
@@ -184,6 +193,68 @@ export const uptimeResourceSamples = sqliteTable("uptime_resource_samples", {
|
||||
rosVersion: text("ros_version").notNull().default(""),
|
||||
})
|
||||
|
||||
export const uptimeSpeedProbes = sqliteTable("uptime_speed_probes", {
|
||||
id: text("id").primaryKey(),
|
||||
srcServerId: integer("src_server_id")
|
||||
.notNull()
|
||||
.references(() => servers.id, { onDelete: "cascade" }),
|
||||
dstServerId: integer("dst_server_id")
|
||||
.notNull()
|
||||
.references(() => servers.id, { onDelete: "cascade" }),
|
||||
srcInterface: text("src_interface").notNull().default(""),
|
||||
dstInterface: text("dst_interface").notNull().default(""),
|
||||
protocol: text("protocol", { enum: ["tcp", "udp"] }).notNull().default("tcp"),
|
||||
direction: text("direction", { enum: ["transmit", "receive", "both"] }).notNull().default("both"),
|
||||
durationSec: integer("duration_sec").notNull().default(10),
|
||||
enabled: integer("enabled", { mode: "boolean" }).notNull().default(true),
|
||||
lastRunAt: text("last_run_at"),
|
||||
lastTxAvgMbps: real("last_tx_avg_mbps"),
|
||||
lastRxAvgMbps: real("last_rx_avg_mbps"),
|
||||
lastStatus: text("last_status", { enum: ["done", "error"] }),
|
||||
lastError: text("last_error"),
|
||||
lastPingRttMs: integer("last_ping_rtt_ms"),
|
||||
lastPingLossPct: integer("last_ping_loss_pct"),
|
||||
lastPingAt: text("last_ping_at"),
|
||||
lastPingError: text("last_ping_error"),
|
||||
sortOrder: integer("sort_order").notNull().default(0),
|
||||
createdAt: text("created_at").notNull().default(sql`(datetime('now'))`),
|
||||
updatedAt: text("updated_at").notNull().default(sql`(datetime('now'))`),
|
||||
})
|
||||
|
||||
// ── EvoBGP integration (URL + API key на сервере) ─────────────────────────────
|
||||
|
||||
export const evobgpSettings = sqliteTable("evobgp_settings", {
|
||||
id: integer("id").primaryKey(),
|
||||
baseUrl: text("base_url").notNull().default(""),
|
||||
apiKey: text("api_key").notNull().default(""),
|
||||
enabled: integer("enabled", { mode: "boolean" }).notNull().default(false),
|
||||
updatedAt: text("updated_at").notNull().default(sql`(datetime('now'))`),
|
||||
})
|
||||
|
||||
export const uptimeSpeedTestRuns = sqliteTable("uptime_speed_test_runs", {
|
||||
id: text("id").primaryKey(),
|
||||
probeId: text("probe_id"),
|
||||
srcServerId: integer("src_server_id").notNull().references(() => servers.id, { onDelete: "cascade" }),
|
||||
dstServerId: integer("dst_server_id").notNull().references(() => servers.id, { onDelete: "cascade" }),
|
||||
srcInterface: text("src_interface").notNull().default(""),
|
||||
dstInterface: text("dst_interface").notNull().default(""),
|
||||
srcAddress: text("src_address"),
|
||||
dstAddress: text("dst_address"),
|
||||
srcInterfaceAddress:text("src_interface_address"),
|
||||
dstInterfaceAddress:text("dst_interface_address"),
|
||||
protocol: text("protocol", { enum: ["tcp", "udp"] }).notNull().default("tcp"),
|
||||
direction: text("direction", { enum: ["transmit", "receive", "both"] }).notNull().default("both"),
|
||||
durationSec: integer("duration_sec").notNull().default(10),
|
||||
txAvgMbps: real("tx_avg_mbps"),
|
||||
rxAvgMbps: real("rx_avg_mbps"),
|
||||
pingRttMs: integer("ping_rtt_ms"),
|
||||
pingLossPct: integer("ping_loss_pct"),
|
||||
pingError: text("ping_error"),
|
||||
status: text("status", { enum: ["done", "error"] }).notNull().default("done"),
|
||||
error: text("error"),
|
||||
createdAt: text("created_at").notNull().default(sql`(datetime('now'))`),
|
||||
})
|
||||
|
||||
// ── inferred types ─────────────────────────────────────────────────────────────
|
||||
|
||||
export type Server = typeof servers.$inferSelect
|
||||
@@ -198,3 +269,6 @@ export type UptimeSettingsRow = typeof uptimeSettings.$inferSelect
|
||||
export type UptimeProbeRow = typeof uptimeProbes.$inferSelect
|
||||
export type UptimeProbeSampleRow = typeof uptimeProbeSamples.$inferSelect
|
||||
export type UptimeResourceSampleRow = typeof uptimeResourceSamples.$inferSelect
|
||||
export type UptimeSpeedProbeRow = typeof uptimeSpeedProbes.$inferSelect
|
||||
export type UptimeSpeedTestRunRow = typeof uptimeSpeedTestRuns.$inferSelect
|
||||
export type EvobgpSettingsRow = typeof evobgpSettings.$inferSelect
|
||||
|
||||
Reference in New Issue
Block a user