feat: finish the host-metrics plugin, move host status into core (B16)

This commit is contained in:
LukeGus committed 2026-09-24 11:21:23 -05:00
1 parent 14eb558b85
commit 0a3f05d99d
308 files changed
+53073 -8985

No files matched your search

+5 -88
View File
@@ -288,7 +288,10 @@ export const hosts = sqliteTable(
.notNull()
.default(false),
defaultPath: text("default_path"),
statsConfig: text("stats_config"),
statusCheckEnabled: integer("status_check_enabled", { mode: "boolean" })
.notNull()
.default(true),
statusCheckInterval: integer("status_check_interval"),
dockerConfig: text("docker_config"),
webUiConfig: text("web_ui_config"),
terminalConfig: text("terminal_config"),
@@ -884,40 +887,12 @@ export const userPreferences = sqliteTable("user_preferences", {
.default(sql`CURRENT_TIMESTAMP`),
});
export const hostMetricsPreferences = sqliteTable(
"host_metrics_preferences",
{
id: integer("id").primaryKey({ autoIncrement: true }),
userId: text("user_id")
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
hostId: integer("host_id")
.notNull()
.references(() => hosts.id, { onDelete: "cascade" }),
// JSON-encoded HostMetricsLayout. Layout has no secrets, so it is stored as
// plain JSON (no field-level encryption).
layout: text("layout").notNull(),
createdAt: text("created_at")
.notNull()
.default(sql`CURRENT_TIMESTAMP`),
updatedAt: text("updated_at")
.notNull()
.default(sql`CURRENT_TIMESTAMP`),
},
// One layout per user per host. Enforced in production since the inline DDL
// creates it, but it was never declared here, so the generated Postgres and
// MySQL schemas lacked it — and the upsert has nothing to conflict on.
(table) => [
uniqueIndex("idx_host_metrics_prefs_user_host").on(table.userId, table.hostId),
],
);
export const hostSidebarPreferences = sqliteTable("host_sidebar_preferences", {
userId: text("user_id")
.primaryKey()
.references(() => users.id, { onDelete: "cascade" }),
// JSON-encoded HostSidebarPreferences. No secrets in this blob, stored as
// plain JSON like hostMetricsPreferences.layout.
// plain JSON.
data: text("data").notNull(),
updatedAt: text("updated_at")
.notNull()
@@ -952,47 +927,6 @@ export const uiPreferences = sqliteTable("ui_preferences", {
.default(sql`CURRENT_TIMESTAMP`),
});
export const hostHealthChecks = sqliteTable(
"host_health_checks",
{
id: integer("id").primaryKey({ autoIncrement: true }),
userId: text("user_id")
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
hostId: integer("host_id")
.notNull()
.references(() => hosts.id, { onDelete: "cascade" }),
// JSON array of { id, name, type: "tcp"|"http", target, port, path }
checks: text("checks").notNull(),
intervalSeconds: integer("interval_seconds").notNull().default(300),
createdAt: text("created_at")
.notNull()
.default(sql`CURRENT_TIMESTAMP`),
updatedAt: text("updated_at")
.notNull()
.default(sql`CURRENT_TIMESTAMP`),
},
// Same as above: one set of checks per user per host.
(table) => [
uniqueIndex("idx_host_health_checks_user_host").on(table.userId, table.hostId),
],
);
export const hostHealthHistory = sqliteTable("host_health_history", {
id: integer("id").primaryKey({ autoIncrement: true }),
userId: text("user_id")
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
hostId: integer("host_id")
.notNull()
.references(() => hosts.id, { onDelete: "cascade" }),
checkId: text("check_id").notNull(),
ts: text("ts").notNull().default(sql`CURRENT_TIMESTAMP`),
ok: integer("ok", { mode: "boolean" }).notNull(),
latencyMs: integer("latency_ms"),
detail: text("detail"),
});
export const dashboardServiceLinks = sqliteTable("dashboard_service_links", {
id: integer("id").primaryKey({ autoIncrement: true }),
userId: text("user_id")
@@ -1083,23 +1017,6 @@ export const termixIdentityCa = sqliteTable("termix_identity_ca", {
});
// --- termix-id end ---
// --- metrics-history begin ---
export const hostMetricsHistory = sqliteTable("host_metrics_history", {
id: integer("id").primaryKey({ autoIncrement: true }),
hostId: integer("host_id")
.notNull()
.references(() => hosts.id, { onDelete: "cascade" }),
ts: text("ts")
.notNull()
.default(sql`CURRENT_TIMESTAMP`),
cpuPercent: real("cpu_percent"),
memPercent: real("mem_percent"),
diskPercent: real("disk_percent"),
netRxBytes: integer("net_rx_bytes"),
netTxBytes: integer("net_tx_bytes"),
});
// --- metrics-history end ---
// --- alerts begin ---
export const notificationChannels = sqliteTable("notification_channels", {
id: integer("id").primaryKey({ autoIncrement: true }),