import { DASHBOARD_SCHEMA_VERSION, type DashboardDocument, type DatasourceReference, type MetricValue, type ServiceEntry, type ServiceGroup, type Severity, type TelemetryCard, } from "../schema"; type NumericValueKind = "percent" | "bytes" | "temperature" | "latency" | "number"; interface MetricSeed { id: string; label: string; icon: string; kind: NumericValueKind; value: number; detail: string; severity: Severity; datasource: DatasourceReference; thresholds?: TelemetryCard["thresholds"]; sparkline?: number[]; precision?: number; } interface ServiceSeed { id: string; label: string; description: string; icon: string; datasource: DatasourceReference; href?: string; severity?: Severity; detail?: string; } export const dimensionLabDashboardFixture: DashboardDocument = { schemaVersion: DASHBOARD_SCHEMA_VERSION, metadata: { title: "System Overview", subtitle: "Dimension Lab home infra, GPU, and automation surface", description: "Initial Dimension Lab dashboard seed data. Runtime values are fallback values until datasource adapters are enabled.", timezone: "Europe/Amsterdam", refreshIntervalSeconds: 15, }, layout: { density: "dense", telemetry: [ "infra-ram", "gpu-host-ram", "network-ram", "user-disk-peak", "system-disk-peak", "peak-cpu-busy", "top-cpu-container", "top-ram-container", "gpu-3060-load", "gpu-3060-vram", "gpu-3060-temp", "gpu-3060-fan", "gpu-3090-load", "gpu-3090-vram", "gpu-3090-temp", "gpu-3090-fan", ], serviceGroups: ["essentials", "monitoring", "ai-automation", "systems", "runtime-health"], statusStrips: ["footer-status"], modules: ["weather-amsterdam", "runtime-health-summary"], }, telemetry: [ metric({ id: "infra-ram", label: "Infra RAM", icon: "mdi:memory", kind: "percent", value: 19, detail: "fallback - linux-infra memory used", severity: "ok", thresholds: percentThresholds(), datasource: prometheus( '100 * (1 - node_memory_MemAvailable_bytes{instance="linux-infra"} / node_memory_MemTotal_bytes{instance="linux-infra"})', ), sparkline: [18, 18, 19, 19, 18, 19], }), metric({ id: "gpu-host-ram", label: "GPU Host RAM", icon: "mdi:memory", kind: "percent", value: 17, detail: "fallback - GPU host memory used", severity: "ok", thresholds: percentThresholds(), datasource: prometheus( '100 * (1 - node_memory_MemAvailable_bytes{instance="linux-gpu"} / node_memory_MemTotal_bytes{instance="linux-gpu"})', ), sparkline: [16, 16, 17, 17, 17, 17], }), metric({ id: "network-ram", label: "Network RAM", icon: "mdi:router-network", kind: "percent", value: 5, detail: "fallback - network core memory used", severity: "ok", thresholds: percentThresholds(), datasource: prometheus( '100 * (1 - node_memory_MemAvailable_bytes{instance="network-core"} / node_memory_MemTotal_bytes{instance="network-core"})', ), sparkline: [5, 5, 5, 6, 5, 5], }), metric({ id: "user-disk-peak", label: "User Disk Peak", icon: "mdi:harddisk", kind: "percent", value: 29, detail: "fallback - /home peak usage", severity: "ok", thresholds: percentThresholds(80, 92), datasource: prometheus( '100 * (1 - node_filesystem_avail_bytes{mountpoint="/home"} / node_filesystem_size_bytes{mountpoint="/home"})', ), sparkline: [27, 27, 28, 29, 29, 29], }), metric({ id: "system-disk-peak", label: "System Disk Peak", icon: "mdi:harddisk", kind: "percent", value: 49, detail: "fallback - /boot peak usage", severity: "ok", thresholds: percentThresholds(80, 92), datasource: prometheus( '100 * (1 - node_filesystem_avail_bytes{mountpoint="/boot"} / node_filesystem_size_bytes{mountpoint="/boot"})', ), sparkline: [48, 48, 49, 49, 49, 49], }), metric({ id: "peak-cpu-busy", label: "Peak CPU Busy", icon: "mdi:cpu-64-bit", kind: "percent", value: 3, detail: "fallback - linux-infra 5m CPU busy", severity: "ok", thresholds: percentThresholds(75, 90), datasource: prometheus( '100 - (avg by(instance) (rate(node_cpu_seconds_total{instance="linux-infra",mode="idle"}[5m])) * 100)', ), sparkline: [2, 3, 3, 4, 3, 3], }), metric({ id: "top-cpu-container", label: "Top CPU Container", icon: "mdi:docker", kind: "percent", value: 7.9, precision: 1, detail: "fallback - top container CPU pending label mapping", severity: "ok", thresholds: percentThresholds(70, 90), datasource: placeholder( "fallback top-container CPU query pending container label normalization", ), sparkline: [6.1, 6.4, 7.0, 7.5, 7.2, 7.9], }), metric({ id: "top-ram-container", label: "Top RAM Container", icon: "mdi:docker", kind: "bytes", value: Math.round(5.2 * 1024 ** 3), precision: 1, detail: "fallback - top container RAM pending label mapping", severity: "danger", thresholds: { warning: 3 * 1024 ** 3, danger: 5 * 1024 ** 3 }, datasource: placeholder( "fallback top-container memory query pending container label normalization", ), sparkline: [ 3.1 * 1024 ** 3, 3.5 * 1024 ** 3, 4.1 * 1024 ** 3, 4.8 * 1024 ** 3, 5.0 * 1024 ** 3, 5.2 * 1024 ** 3, ], }), metric({ id: "gpu-3060-load", label: "3060 GPU Load", icon: "mdi:expansion-card", kind: "percent", value: 0, detail: "fallback - RTX 3060 GPU utilization", severity: "ok", thresholds: percentThresholds(85, 95), datasource: prometheus('DCGM_FI_DEV_GPU_UTIL{gpu="rtx-3060"}'), sparkline: [0, 0, 0, 0, 0, 0], }), metric({ id: "gpu-3060-vram", label: "3060 VRAM", icon: "mdi:memory", kind: "percent", value: 0, detail: "fallback - RTX 3060 VRAM used", severity: "ok", thresholds: percentThresholds(80, 92), datasource: prometheus( '100 * DCGM_FI_DEV_FB_USED{gpu="rtx-3060"} / (DCGM_FI_DEV_FB_USED{gpu="rtx-3060"} + DCGM_FI_DEV_FB_FREE{gpu="rtx-3060"})', ), sparkline: [0, 0, 0, 0, 0, 0], }), metric({ id: "gpu-3060-temp", label: "3060 Temp", icon: "mdi:thermometer", kind: "temperature", value: 54, detail: "fallback - RTX 3060 temperature", severity: "ok", thresholds: { warning: 75, danger: 85 }, datasource: prometheus('DCGM_FI_DEV_GPU_TEMP{gpu="rtx-3060"}'), sparkline: [52, 53, 54, 54, 53, 54], }), metric({ id: "gpu-3060-fan", label: "3060 Fan Spin", icon: "mdi:fan", kind: "percent", value: 0, detail: "fallback - RTX 3060 fan duty", severity: "ok", thresholds: percentThresholds(80, 95), datasource: prometheus('DCGM_FI_DEV_FAN_SPEED{gpu="rtx-3060"}'), sparkline: [0, 0, 0, 0, 0, 0], }), metric({ id: "gpu-3090-load", label: "3090 GPU Load", icon: "mdi:expansion-card", kind: "percent", value: 0, detail: "fallback - RTX 3090 GPU utilization", severity: "ok", thresholds: percentThresholds(85, 95), datasource: prometheus('DCGM_FI_DEV_GPU_UTIL{gpu="rtx-3090"}'), sparkline: [0, 0, 0, 0, 0, 0], }), metric({ id: "gpu-3090-vram", label: "3090 VRAM", icon: "mdi:memory", kind: "percent", value: 74, detail: "fallback - RTX 3090 VRAM used", severity: "warning", thresholds: percentThresholds(70, 90), datasource: prometheus( '100 * DCGM_FI_DEV_FB_USED{gpu="rtx-3090"} / (DCGM_FI_DEV_FB_USED{gpu="rtx-3090"} + DCGM_FI_DEV_FB_FREE{gpu="rtx-3090"})', ), sparkline: [68, 70, 72, 74, 73, 74], }), metric({ id: "gpu-3090-temp", label: "3090 Temp", icon: "mdi:thermometer", kind: "temperature", value: 50, detail: "fallback - RTX 3090 temperature", severity: "ok", thresholds: { warning: 75, danger: 85 }, datasource: prometheus('DCGM_FI_DEV_GPU_TEMP{gpu="rtx-3090"}'), sparkline: [49, 50, 50, 51, 50, 50], }), metric({ id: "gpu-3090-fan", label: "3090 Fan Spin", icon: "mdi:fan", kind: "percent", value: 0, detail: "fallback - RTX 3090 fan duty", severity: "ok", thresholds: percentThresholds(80, 95), datasource: prometheus('DCGM_FI_DEV_FAN_SPEED{gpu="rtx-3090"}'), sparkline: [0, 0, 0, 0, 0, 0], }), ], serviceGroups: [ group("essentials", "Essentials", [ service({ id: "vaultwarden", label: "Vaultwarden", description: "Password manager", icon: "simple-icons:vaultwarden", href: "https://vault.dimensionlab.net", datasource: httpStatus("https://vault.dimensionlab.net/alive"), }), service({ id: "forgejo", label: "Forgejo", description: "Git repositories", icon: "simple-icons:forgejo", href: "https://git.dimensionlab.net", datasource: httpStatus("https://git.dimensionlab.net/api/healthz"), }), service({ id: "wiki", label: "Wiki", description: "Internal documentation", icon: "simple-icons:wikidotjs", href: "https://wiki.dimensionlab.net", datasource: httpStatus("https://wiki.dimensionlab.net"), }), service({ id: "aws-start", label: "AWS Start", description: "AWS access portal", icon: "simple-icons:amazonwebservices", href: "https://dimensionlab.awsapps.com/start", datasource: httpStatus("https://dimensionlab.awsapps.com/start"), }), ]), group("monitoring", "Monitoring", [ service({ id: "grafana", label: "Grafana", description: "Capacity and noise dashboard", icon: "simple-icons:grafana", href: "https://grafana.dimensionlab.net", datasource: httpStatus("https://grafana.dimensionlab.net/api/health"), }), service({ id: "uptime-kuma", label: "Uptime Kuma", description: "Service uptime checks", icon: "simple-icons:uptimekuma", href: "https://uptime.dimensionlab.net", datasource: httpStatus("https://uptime.dimensionlab.net/status/dimensionlab"), }), service({ id: "prometheus", label: "Prometheus", description: "Metrics database", icon: "simple-icons:prometheus", href: "https://prometheus.dimensionlab.net", datasource: httpStatus("https://prometheus.dimensionlab.net/-/ready"), }), service({ id: "backrest", label: "Backrest", description: "Restic backup manager", icon: "mdi:backup-restore", href: "https://backups.dimensionlab.net", datasource: httpStatus("https://backups.dimensionlab.net"), }), ]), group("ai-automation", "AI & Automation", [ service({ id: "n8n", label: "n8n", description: "Workflow automation", icon: "simple-icons:n8n", href: "https://workflows.dimensionlab.net", datasource: httpStatus("https://workflows.dimensionlab.net/healthz"), }), service({ id: "open-webui", label: "Open WebUI", description: "Chat and model interface", icon: "mdi:web", href: "https://webui.dimensionlab.net", datasource: httpStatus("https://webui.dimensionlab.net/health"), }), service({ id: "comfyui", label: "ComfyUI", description: "Image generation workflows", icon: "mdi:image-edit-outline", href: "https://comfy.dimensionlab.net", datasource: httpStatus("https://comfy.dimensionlab.net"), }), service({ id: "models", label: "Models", description: "Local model management", icon: "mdi:brain", href: "https://models.dimensionlab.net", datasource: httpStatus("https://models.dimensionlab.net/api/tags"), }), ]), group("systems", "Systems", [ service({ id: "adminer", label: "Adminer", description: "PostgreSQL database browser", icon: "simple-icons:adminer", href: "https://db.dimensionlab.net", datasource: httpStatus("https://db.dimensionlab.net"), }), service({ id: "assistant", label: "Assistant", description: "Personal AI agent gateway", icon: "mdi:robot-outline", href: "https://assistant.dimensionlab.net", datasource: httpStatus("https://assistant.dimensionlab.net/health"), }), service({ id: "suna", label: "Suna", description: "AI command center", icon: "mdi:account-hard-hat-outline", href: "https://suna.dimensionlab.net", datasource: httpStatus("https://suna.dimensionlab.net"), }), service({ id: "cockpit-infra", label: "Cockpit Infra", description: "linux-infra server console", icon: "simple-icons:cockpit", href: "https://infra-cockpit.dimensionlab.net", datasource: httpStatus("https://infra-cockpit.dimensionlab.net"), }), ]), group("runtime-health", "Runtime Health", [ service({ id: "forgejo-ssh-relay", label: "Forgejo SSH Relay", description: "Public Git SSH relay", icon: "simple-icons:forgejo", href: "https://uptime.dimensionlab.net/status/dimensionlab", datasource: custom("tcp:git.dimensionlab.net:22"), detail: "fallback - uptime monitor pending", }), service({ id: "postgresql", label: "PostgreSQL", description: "Shared application database", icon: "simple-icons:postgresql", datasource: prometheus('pg_up{cluster="dimensionlab"}'), detail: "fallback - postgres exporter pending", }), service({ id: "ollama-api", label: "Ollama API", description: "Local model API", icon: "simple-icons:ollama", datasource: httpStatus("http://linux-gpu:11434/api/tags"), detail: "fallback - internal health check pending", }), service({ id: "node-exporter", label: "Node Exporter", description: "Host metrics exporter", icon: "simple-icons:prometheus", datasource: prometheus('up{job="node-exporter"}'), detail: "fallback - exporter health from Prometheus", }), ]), ], statusStrips: [ { id: "footer-status", items: [ { id: "system-status", label: "System Status", value: "Fallback operational", severity: "ok" }, { id: "last-sync", label: "Last Sync", value: "fallback: 2 minutes ago", severity: "stale" }, { id: "uptime", label: "Uptime", value: "fallback: 28d 14h 32m", severity: "ok" }, { id: "load-avg", label: "Load Avg", value: "fallback: 0.47 0.53 0.59", severity: "neutral" }, ], }, ], modules: [ { id: "weather-amsterdam", kind: "weather", title: "Amsterdam", value: "28.3 C", detail: "fallback - weather adapter pending", icon: "mdi:weather-sunny", severity: "ok", datasource: { type: "external", adapter: "weather", reference: "open-meteo:latitude=52.3676&longitude=4.9041", }, }, { id: "runtime-health-summary", kind: "summary", title: "Runtime Health", value: "fallback", detail: "fallback - health adapters pending", icon: "mdi:pulse", severity: "stale", datasource: placeholder("summary pending live health aggregation"), }, ], }; function metric(seed: MetricSeed): TelemetryCard { return { id: seed.id, label: seed.label, icon: seed.icon, value: metricValue(seed.kind, seed.value, seed.precision), detail: seed.detail, severity: seed.severity, thresholds: seed.thresholds, datasource: seed.datasource, sparkline: seed.sparkline, }; } function metricValue( kind: NumericValueKind, value: number, precision?: number, ): MetricValue { return precision === undefined ? { kind, value } : { kind, value, precision }; } function service(seed: ServiceSeed): ServiceEntry { const entry: ServiceEntry = { id: seed.id, label: seed.label, description: seed.description, icon: seed.icon, severity: seed.severity || "ok", detail: seed.detail || "fallback - health check pending", datasource: seed.datasource, }; if (!seed.href) return entry; return { ...entry, link: { href: seed.href, label: `Open ${seed.label}`, external: true, }, }; } function group(id: string, title: string, services: ServiceEntry[]): ServiceGroup { return { id, title, layout: "list", services, }; } function percentThresholds(warning = 80, danger = 92) { return { warning, danger }; } function prometheus(reference: string): DatasourceReference { return { type: "external", adapter: "prometheus", reference, }; } function httpStatus(url: string): DatasourceReference { return { type: "external", adapter: "http-status", reference: `GET ${url}`, }; } function custom(reference: string): DatasourceReference { return { type: "external", adapter: "custom", reference, }; } function placeholder(reason: string): DatasourceReference { return { type: "placeholder", reason, }; }