Files
homelab-topology/SPEC.md

15 KiB

Homelab Topology Visualizer - Specification

1. Project Overview

Project Name: Homelab Topology Visualizer (HomelabTV) Type: Interactive Web Application Core Functionality: A visual, interactive graph-based UI that displays the complete topology of a homelab - from network infrastructure (UniFi gateway, VLANs) through hosts, Docker containers/services, to filesystem paths and files. Target Users: Homelab administrators, DevOps engineers, home network enthusiasts


2. UI/UX Specification

Layout Structure

┌─────────────────────────────────────────────────────────────────────────────────┐
│  HEADER: Logo + Title + View Mode Selector + Refresh Button                      │
├─────────────┬───────────────────────────────────────────────────┬───────────────┤
│             │                                                   │               │
│   LEFT      │              MAIN GRAPH CANVAS                   │    RIGHT      │
│   PANEL     │           (React Flow / D3.js)                   │    PANEL      │
│             │                                                   │               │
│  Subnodes   │    Nodes connected by edges showing             │   Details     │
│  of         │    relationships:                                │   Tabs:       │
│  selected   │    Gateway → VLAN → Host → Service → Volume     │               │
│  node       │                                                   │  - Details    │
│             │    [Interactive: click to select,                │  - Config     │
│  - List     │     drag to pan, scroll to zoom]                │  - Files      │
│  - Click    │                                                   │  - Usage      │
│    to       │                                                   │  - Importance │
│    select   │                                                   │               │
│             │                                                   │               │
├─────────────┴───────────────────────────────────────────────────┴───────────────┤
│  FOOTER: Status bar (last refresh, node count, connection status)               │
└─────────────────────────────────────────────────────────────────────────────────┘
  • Header: Fixed, 56px height
  • Left Panel: 280px width, collapsible
  • Right Panel: 360px width, collapsible
  • Graph Canvas: Flexible, fills remaining space
  • Footer: Fixed, 32px height

Responsive Breakpoints

  • Desktop (≥1200px): Full 3-column layout
  • Tablet (768px-1199px): Left panel hidden, right panel 300px
  • Mobile (<768px): Panels as overlays/drawers

Visual Design

Color Palette

/* Network Layer */
--network-gateway: #6366F1;      /* Indigo - UniFi gateway */
--network-vlan: #8B5CF6;         /* Purple - VLANs */
--network-wifi: #EC4899;         /* Pink - Access points */

/* Host Layer */
--host-physical: #10B981;        /* Emerald - Physical servers */
--host-vm: #14B8A6;             /* Teal - Virtual machines */
--host-container: #F59E0B;       /* Amber - LXC containers */

/* Service Layer */
--service-media: #EF4444;        /* Red - Jellyfin, Radarr, etc */
--service-infra: #3B82F6;       /* Blue - Traefik, Authentik */
--service-monitoring: #22C55E;  /* Green - Prometheus, Grafana */
--service-ai: #F97316;          /* Orange - Ollama, Litellm */
--service-storage: #06B6D4;      /* Cyan - Storage services */

/* Filesystem Layer */
--filesystem-nfs: #84CC16;       /* Lime - NFS mounts */
--filesystem-volume: #A855F7;   /* Purple - Docker volumes */
--filesystem-path: #EAB308;      /* Yellow - File paths */

/* UI Colors */
--bg-primary: #0F172A;           /* Slate 900 */
--bg-secondary: #1E293B;         /* Slate 800 */
--bg-tertiary: #334155;         /* Slate 700 */
--text-primary: #F8FAFC;         /* Slate 50 */
--text-secondary: #94A3B8;      /* Slate 400 */
--border: #475569;               /* Slate 600 */
--accent: #38BDF8;              /* Sky 400 */
--success: #22C55E;
--warning: #F59E0B;
--error: #EF4444;

Typography

  • Font Family: "JetBrains Mono", "Fira Code", monospace for data; "Inter", system-ui for UI
  • Sizes:
    • H1 (Title): 24px, weight 700
    • H2 (Section): 18px, weight 600
    • H3 (Node name): 14px, weight 600
    • Body: 13px, weight 400
    • Caption: 11px, weight 400

Spacing System

  • Base unit: 4px
  • Padding: 8px (sm), 12px (md), 16px (lg), 24px (xl)
  • Margins: 4px (xs), 8px (sm), 16px (md), 24px (lg)
  • Border radius: 4px (sm), 8px (md), 12px (lg)

Visual Effects

  • Node shadows: 0 2px 8px rgba(0,0,0,0.3)
  • Panel shadows: 0 4px 24px rgba(0,0,0,0.4)
  • Glow on hover: 0 0 12px var(--node-color)
  • Transitions: 200ms ease-out for all interactive elements
  • Graph edges: Animated dashed lines for active connections

Components

Node Component

  • Shape: Rounded rectangle (120x48px) or circle (48x48px) for endpoints
  • Content: Icon + Label + Status indicator
  • States:
    • Default: bg-secondary, border solid
    • Hover: Glow effect, scale 1.02
    • Selected: Border 2px accent, elevated shadow
    • Running: Green status dot
    • Stopped: Red status dot
    • Warning: Yellow status dot

Edge Component

  • Style: Curved bezier lines with arrows
  • States:
    • Default: border 1px text-secondary
    • Active/Selected: border 2px accent, animated dash

Left Panel - Subnodes

  • Header: "CHILD NODES" with count badge
  • List Items: Icon + Name + Type badge
  • Interaction: Click to focus/select in graph
  • Empty state: "No child nodes"

Right Panel - Details Tabs

  • Tab Bar: Details | Config | Files | Usage | Importance
  • Details Tab: IP, MAC, Status, Uptime, Type, Description
  • Config Tab: YAML/JSON view of configuration
  • Files Tab: Tree view of relevant file paths
  • Usage Tab: CPU, Memory, Network graphs
  • Importance Tab: Critical / High / Medium / Low with reasoning

View Mode Selector

  • Options:
    • 🌐 Network: Shows gateway, VLANs, WiFi, hosts
    • 🖥️ Hosts: Shows hosts and their services
    • 📦 Services: Shows all services and their dependencies
    • 💾 Filesystem: Shows volumes, mounts, paths
    • 🔗 Full: Complete topology (default)

3. Functionality Specification

Core Features

F1: Interactive Graph Visualization

  • Render infrastructure as directed graph
  • Pan, zoom, fit-to-view controls
  • Click node to select (shows details)
  • Double-click to focus/center
  • Drag nodes to rearrange
  • Minimap for navigation

F2: Node Selection & Navigation

  • Single click: Select node, show details in right panel
  • Double click: Zoom to node, expand children
  • Right click: Context menu (copy IP, open URL, etc.)
  • Keyboard: Arrow keys to navigate, Enter to select

F3: Multi-View Modes

  • Network View: UniFi → VLANs → Subnets → Hosts
  • Host View: Hosts → VMs/LXCs → Containers
  • Service View: Services → Dependencies → Volumes
  • Filesystem View: TrueNAS → NFS → Volumes → Paths
  • Full View: Everything connected

F4: Detail Panels

Left Panel (Subnodes):

  • Shows children of selected node
  • Click to select in graph
  • Shows node count per type

Right Panel (Details):

  • 5 tabs with content
  • Details: Basic info (IP, type, status)
  • Config: Docker compose, YAML configs
  • Files: Related file paths (clickable)
  • Usage: Resource consumption
  • Importance: 1-5 stars with why

F5: Data Discovery (Hybrid Approach)

Static Config (JSON/YAML):

{
  "network": {
    "gateway": { "model": "UniFi Dream Machine Pro", "ip": "192.168.1.1" },
    "vlans": [
      { "id": 10, "name": "Family", "subnet": "192.168.10.0/24" },
      { "id": 30, "name": "IoT", "subnet": "192.168.30.0/24" },
      { "id": 50, "name": "Production", "subnet": "192.168.50.0/24" }
    ],
    "wifi": [
      { "ssid": "Will of D.", "vlan": "default" },
      { "ssid": "Will of D. IoT", "vlan": 30 }
    ]
  },
  "hosts": [
    {
      "name": "ubuntu",
      "ip": "192.168.50.61",
      "type": "vm",
      "role": "Primary Docker Host",
      "containers": ["traefik", "jellyfin", "authentik", ...]
    },
    {
      "name": "grizzley",
      "ip": "192.168.50.84", 
      "type": "rpi5",
      "role": "Edge Services",
      "containers": ["frigate", "traefik"]
    }
  ]
}

Auto-Discovery (SSH):

  • SSH to hosts and run commands
  • docker ps --format json for containers
  • docker network inspect for network topology
  • ls /mnt/truenas/ for NFS mounts
  • cat /proc/cpuinfo for hardware info

F6: Search & Filter

  • Search bar: Filter nodes by name
  • Type filter: Show/hide node types
  • Status filter: Running/Stopped/All
  • Quick jump: Cmd+K to open command palette

F7: Real-time Updates

  • Poll intervals: 30s (configurable)
  • WebSocket option for live updates
  • Visual indicator for stale data

User Interactions & Flows

  1. Initial Load:

    • Load static config
    • Run auto-discovery in background
    • Render graph with all nodes
    • Fit to view
  2. Select Node:

    • Click node → Highlight path to root
    • Left panel shows children
    • Right panel shows details (Details tab)
  3. Change View:

    • Click view mode → Re-render graph with filter
    • Preserve selected node if visible
  4. View Service Config:

    • Select service node
    • Click "Config" tab
    • Shows docker-compose.yml content
    • Clickable file paths
  5. Refresh Data:

    • Click refresh → Show loading state
    • Run discovery commands
    • Update graph
    • Show "Last updated: X seconds ago"

Data Handling

  • State Management: React Context + useReducer
  • Persistence: LocalStorage for user preferences (view mode, panel states)
  • Caching: In-memory cache with 30s TTL
  • Error Handling: Show stale data with warning banner if discovery fails

Edge Cases

  • Host unreachable: Show node with "Offline" status, gray out
  • Container stopped: Show with red indicator, allow config view
  • Empty discovery: Use static config as fallback
  • Large graphs (100+ nodes): Enable clustering, lazy render
  • Mobile: Simplified single-panel view with drawer navigation

4. Technical Architecture

Tech Stack

  • Framework: React 18 + TypeScript
  • Build Tool: Vite
  • Graph Library: React Flow (@xyflow/react)
  • Styling: Tailwind CSS
  • State: Zustand (lightweight)
  • HTTP Client: Axios
  • SSH: Node-SSH (backend) or jsch (frontend via proxy)
  • Icons: Lucide React
  • Charts: Recharts (for usage graphs)

Project Structure

homelab-topology/
├── src/
│   ├── components/
│   │   ├── Graph/
│   │   │   ├── TopologyGraph.tsx
│   │   │   ├── NodeComponent.tsx
│   │   │   ├── EdgeComponent.tsx
│   │   │   └── controls.tsx
│   │   ├── Panels/
│   │   │   ├── LeftPanel.tsx
│   │   │   ├── RightPanel.tsx
│   │   │   └── DetailTabs/
│   │   ├── Header/
│   │   │   └── Header.tsx
│   │   └── common/
│   │       ├── Button.tsx
│   │       ├── Badge.tsx
│   │       └── Tabs.tsx
│   ├── hooks/
│   │   ├── useTopology.ts
│   │   ├── useDiscovery.ts
│   │   └── useSelection.ts
│   ├── store/
│   │   └── topologyStore.ts
│   ├── types/
│   │   └── index.ts
│   ├── utils/
│   │   ├── graphLayout.ts
│   │   └── formatters.ts
│   ├── data/
│   │   └── staticConfig.ts
│   ├── services/
│   │   └── discovery.ts
│   ├── App.tsx
│   ├── main.tsx
│   └── index.css
├── public/
├── docker/
│   └── Dockerfile
├── package.json
├── tsconfig.json
├── vite.config.ts
├── tailwind.config.js
└── README.md

Backend/API (Optional)

If running auto-discovery, need a small backend:

  • Technology: Node.js + Express
  • Purpose: Proxy SSH commands to homelab hosts
  • Endpoints:
    • GET /api/discover/:host - Run discovery on specific host
    • GET /api/containers - Get all containers across hosts
    • GET /api/volumes - Get all Docker volumes

5. Acceptance Criteria

Visual Checkpoints

  • Graph renders with nodes and edges
  • Nodes are color-coded by type
  • Clicking a node highlights it and shows details
  • Left panel shows child nodes of selected
  • Right panel shows 5 tabs with content
  • View mode selector changes graph content
  • Panels can be collapsed/expanded
  • Search filters nodes in real-time

Functional Checkpoints

  • Initial data loads from static config
  • Auto-discovery populates missing data
  • Graph is pannable and zoomable
  • Node selection is persistent across view changes
  • Config tab shows Docker compose content
  • Files tab shows relevant file paths
  • Refresh button updates data

Performance Checkpoints

  • Initial load < 2 seconds
  • Graph renders 100+ nodes smoothly
  • Interactions feel responsive (< 100ms)

Deployment Checkpoints

  • Builds successfully with npm run build
  • Docker image builds and runs
  • Accessible at localhost:3000
  • Works in browser via local network

6. Data Model

Node Types

type NodeType = 
  | 'gateway' 
  | 'vlan' 
  | 'wifi' 
  | 'host_physical'
  | 'host_vm' 
  | 'host_container'
  | 'service'
  | 'volume'
  | 'mount'
  | 'path';

interface TopologyNode {
  id: string;
  type: NodeType;
  name: string;
  data: {
    ip?: string;
    mac?: string;
    status: 'running' | 'stopped' | 'unknown';
    metadata: Record<string, any>;
    config?: string;
    files?: string[];
    importance: 1 | 2 | 3 | 4 | 5;
  };
  position?: { x: number; y: number };
}

interface TopologyEdge {
  id: string;
  source: string;
  target: string;
  type?: string;
  label?: string;
}

7. Implementation Priority

Phase 1 (MVP - Week 1)

  1. Set up React + React Flow project
  2. Create static config with hardcoded topology
  3. Render basic graph with nodes and edges
  4. Implement node selection
  5. Build right panel with Details tab
  6. Add view mode selector

Phase 2 (Week 2)

  1. Complete right panel tabs (Config, Files, Usage, Importance)
  2. Build left panel with child nodes
  3. Add search and filters
  4. Implement basic auto-discovery (Docker)

Phase 3 (Week 3)

  1. Add SSH-based discovery
  2. Implement real-time updates
  3. Add animations and polish
  4. Create Docker build

Phase 4 (Ongoing)

  1. Add more node types
  2. Improve auto-discovery coverage
  3. Add mobile optimizations
  4. Add saved layouts