     1→-- GuruRMM Clients and Sites Schema
     2→-- Adds multi-tenant support with clients, sites, and site-based agent registration
     3→
     4→-- Clients table (organizations/companies)
     5→CREATE TABLE clients (
     6→    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
     7→    name VARCHAR(255) NOT NULL,
     8→    code VARCHAR(50) UNIQUE, -- Optional short code like "ACME"
     9→    notes TEXT,
    10→    is_active BOOLEAN DEFAULT TRUE,
    11→    created_at TIMESTAMPTZ DEFAULT NOW(),
    12→    updated_at TIMESTAMPTZ DEFAULT NOW()
    13→);
    14→
    15→CREATE INDEX idx_clients_name ON clients(name);
    16→CREATE INDEX idx_clients_code ON clients(code);
    17→
    18→-- Trigger for clients updated_at
    19→CREATE TRIGGER update_clients_updated_at
    20→    BEFORE UPDATE ON clients
    21→    FOR EACH ROW
    22→    EXECUTE FUNCTION update_updated_at_column();
    23→
    24→-- Sites table (locations under a client)
    25→CREATE TABLE sites (
    26→    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    27→    client_id UUID NOT NULL REFERENCES clients(id) ON DELETE CASCADE,
    28→    name VARCHAR(255) NOT NULL,
    29→    -- Site code: human-friendly, used for agent registration (e.g., "BLUE-TIGER-4829")
    30→    site_code VARCHAR(50) UNIQUE NOT NULL,
    31→    -- API key hash for this site (all agents at site share this key)
    32→    api_key_hash VARCHAR(255) NOT NULL,
    33→    address TEXT,
    34→    notes TEXT,
    35→    is_active BOOLEAN DEFAULT TRUE,
    36→    created_at TIMESTAMPTZ DEFAULT NOW(),
    37→    updated_at TIMESTAMPTZ DEFAULT NOW()
    38→);
    39→
    40→CREATE INDEX idx_sites_client ON sites(client_id);
    41→CREATE INDEX idx_sites_code ON sites(site_code);
    42→CREATE INDEX idx_sites_api_key ON sites(api_key_hash);
    43→
    44→-- Trigger for sites updated_at
    45→CREATE TRIGGER update_sites_updated_at
    46→    BEFORE UPDATE ON sites
    47→    FOR EACH ROW
    48→    EXECUTE FUNCTION update_updated_at_column();
    49→
    50→-- Add new columns to agents table
    51→-- device_id: unique hardware-derived identifier for the machine
    52→ALTER TABLE agents ADD COLUMN device_id VARCHAR(255);
    53→
    54→-- site_id: which site this agent belongs to (nullable for legacy agents)
    55→ALTER TABLE agents ADD COLUMN site_id UUID REFERENCES sites(id) ON DELETE SET NULL;
    56→
    57→-- Make api_key_hash nullable (new agents will use site's api_key)
    58→ALTER TABLE agents ALTER COLUMN api_key_hash DROP NOT NULL;
    59→
    60→-- Index for looking up agents by device_id within a site
    61→CREATE UNIQUE INDEX idx_agents_site_device ON agents(site_id, device_id) WHERE site_id IS NOT NULL AND device_id IS NOT NULL;
    62→
    63→-- Index for site lookups
    64→CREATE INDEX idx_agents_site ON agents(site_id);
    65→
    66→-- Registration tokens table (optional: for secure site code distribution)
    67→CREATE TABLE registration_tokens (
    68→    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    69→    site_id UUID NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
    70→    token_hash VARCHAR(255) NOT NULL,
    71→    description VARCHAR(255),
    72→    uses_remaining INTEGER, -- NULL = unlimited
    73→    expires_at TIMESTAMPTZ,
    74→    created_at TIMESTAMPTZ DEFAULT NOW(),
    75→    created_by UUID REFERENCES users(id) ON DELETE SET NULL
    76→);
    77→
    78→CREATE INDEX idx_reg_tokens_site ON registration_tokens(site_id);
    79→CREATE INDEX idx_reg_tokens_hash ON registration_tokens(token_hash);
    80→
    81→-- Function to generate a random site code (WORD-WORD-####)
    82→-- This is just a helper; actual generation should be in application code
    83→-- for better word lists
    84→CREATE OR REPLACE FUNCTION generate_site_code() RETURNS VARCHAR(50) AS $$
    85→DECLARE
    86→    words TEXT[] := ARRAY['ALPHA', 'BETA', 'GAMMA', 'DELTA', 'ECHO', 'FOXTROT',
    87→                          'BLUE', 'GREEN', 'RED', 'GOLD', 'SILVER', 'IRON',
    88→                          'HAWK', 'EAGLE', 'TIGER', 'LION', 'WOLF', 'BEAR',
    89→                          'NORTH', 'SOUTH', 'EAST', 'WEST', 'PEAK', 'VALLEY',
    90→                          'RIVER', 'OCEAN', 'STORM', 'CLOUD', 'STAR', 'MOON'];
    91→    word1 TEXT;
    92→    word2 TEXT;
    93→    num INTEGER;
    94→BEGIN
    95→    word1 := words[1 + floor(random() * array_length(words, 1))::int];
    96→    word2 := words[1 + floor(random() * array_length(words, 1))::int];
    97→    num := 1000 + floor(random() * 9000)::int;
    98→    RETURN word1 || '-' || word2 || '-' || num::text;
    99→END;
   100→$$ LANGUAGE plpgsql;
   101→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>

-- GuruRMM Clients and Sites Schema
-- Adds multi-tenant support with clients, sites, and site-based agent registration

-- Clients table (organizations/companies)
CREATE TABLE clients (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(255) NOT NULL,
    code VARCHAR(50) UNIQUE, -- Optional short code like "ACME"
    notes TEXT,
    is_active BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX idx_clients_name ON clients(name);
CREATE INDEX idx_clients_code ON clients(code);

-- Trigger for clients updated_at
CREATE TRIGGER update_clients_updated_at
    BEFORE UPDATE ON clients
    FOR EACH ROW
    EXECUTE FUNCTION update_updated_at_column();

-- Sites table (locations under a client)
CREATE TABLE sites (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    client_id UUID NOT NULL REFERENCES clients(id) ON DELETE CASCADE,
    name VARCHAR(255) NOT NULL,
    -- Site code: human-friendly, used for agent registration (e.g., "BLUE-TIGER-4829")
    site_code VARCHAR(50) UNIQUE NOT NULL,
    -- API key hash for this site (all agents at site share this key)
    api_key_hash VARCHAR(255) NOT NULL,
    address TEXT,
    notes TEXT,
    is_active BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX idx_sites_client ON sites(client_id);
CREATE INDEX idx_sites_code ON sites(site_code);
CREATE INDEX idx_sites_api_key ON sites(api_key_hash);

-- Trigger for sites updated_at
CREATE TRIGGER update_sites_updated_at
    BEFORE UPDATE ON sites
    FOR EACH ROW
    EXECUTE FUNCTION update_updated_at_column();

-- Add new columns to agents table
-- device_id: unique hardware-derived identifier for the machine
ALTER TABLE agents ADD COLUMN device_id VARCHAR(255);

-- site_id: which site this agent belongs to (nullable for legacy agents)
ALTER TABLE agents ADD COLUMN site_id UUID REFERENCES sites(id) ON DELETE SET NULL;

-- Make api_key_hash nullable (new agents will use site's api_key)
ALTER TABLE agents ALTER COLUMN api_key_hash DROP NOT NULL;

-- Index for looking up agents by device_id within a site
CREATE UNIQUE INDEX idx_agents_site_device ON agents(site_id, device_id) WHERE site_id IS NOT NULL AND device_id IS NOT NULL;

-- Index for site lookups
CREATE INDEX idx_agents_site ON agents(site_id);

-- Registration tokens table (optional: for secure site code distribution)
CREATE TABLE registration_tokens (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    site_id UUID NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
    token_hash VARCHAR(255) NOT NULL,
    description VARCHAR(255),
    uses_remaining INTEGER, -- NULL = unlimited
    expires_at TIMESTAMPTZ,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    created_by UUID REFERENCES users(id) ON DELETE SET NULL
);

CREATE INDEX idx_reg_tokens_site ON registration_tokens(site_id);
CREATE INDEX idx_reg_tokens_hash ON registration_tokens(token_hash);

-- Function to generate a random site code (WORD-WORD-####)
-- This is just a helper; actual generation should be in application code
-- for better word lists
CREATE OR REPLACE FUNCTION generate_site_code() RETURNS VARCHAR(50) AS $$
DECLARE
    words TEXT[] := ARRAY['ALPHA', 'BETA', 'GAMMA', 'DELTA', 'ECHO', 'FOXTROT',
                          'BLUE', 'GREEN', 'RED', 'GOLD', 'SILVER', 'IRON',
                          'HAWK', 'EAGLE', 'TIGER', 'LION', 'WOLF', 'BEAR',
                          'NORTH', 'SOUTH', 'EAST', 'WEST', 'PEAK', 'VALLEY',
                          'RIVER', 'OCEAN', 'STORM', 'CLOUD', 'STAR', 'MOON'];
    word1 TEXT;
    word2 TEXT;
    num INTEGER;
BEGIN
    word1 := words[1 + floor(random() * array_length(words, 1))::int];
    word2 := words[1 + floor(random() * array_length(words, 1))::int];
    num := 1000 + floor(random() * 9000)::int;
    RETURN word1 || '-' || word2 || '-' || num::text;
END;
$$ LANGUAGE plpgsql;


Now let me check the authorization/multi-tenant schema:


     1→-- Multi-tenant authorization system
     2→-- Adds organization limits and user-organization relationships
     3→
     4→-- Add organization limits to clients table
     5→ALTER TABLE clients ADD COLUMN IF NOT EXISTS tech_seat_limit INTEGER DEFAULT NULL;
     6→ALTER TABLE clients ADD COLUMN IF NOT EXISTS endpoint_limit INTEGER DEFAULT NULL;
     7→ALTER TABLE clients ADD COLUMN IF NOT EXISTS is_organization BOOLEAN DEFAULT TRUE;
     8→
     9→-- User-Organization relationship table
    10→-- Replaces the simple role column on users table for multi-tenant access
    11→CREATE TABLE IF NOT EXISTS user_organizations (
    12→    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    13→    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    14→    client_id UUID NOT NULL REFERENCES clients(id) ON DELETE CASCADE,
    15→    role VARCHAR(50) NOT NULL DEFAULT 'org_user',  -- org_admin, org_user
    16→    created_at TIMESTAMPTZ DEFAULT NOW(),
    17→    created_by UUID REFERENCES users(id) ON DELETE SET NULL,
    18→    UNIQUE(user_id, client_id)
    19→);
    20→
    21→-- Indexes for efficient querying
    22→CREATE INDEX IF NOT EXISTS idx_user_orgs_user ON user_organizations(user_id);
    23→CREATE INDEX IF NOT EXISTS idx_user_orgs_client ON user_organizations(client_id);
    24→CREATE INDEX IF NOT EXISTS idx_user_orgs_role ON user_organizations(role);
    25→
    26→-- View for organization statistics (limits and current usage)
    27→CREATE OR REPLACE VIEW organization_stats AS
    28→SELECT
    29→    c.id as client_id,
    30→    c.name as client_name,
    31→    c.tech_seat_limit,
    32→    c.endpoint_limit,
    33→    COALESCE((SELECT COUNT(*) FROM user_organizations WHERE client_id = c.id), 0)::INTEGER as tech_count,
    34→    COALESCE((SELECT COUNT(*) FROM agents a JOIN sites s ON a.site_id = s.id WHERE s.client_id = c.id), 0)::INTEGER as endpoint_count
    35→FROM clients c
    36→WHERE c.is_organization = TRUE;
    37→
    38→-- Update users table: ensure role column supports system-level roles
    39→-- 'dev_admin' = system admin (full access)
    40→-- 'support' = support tier (future)
    41→-- 'user' = regular user (access via org membership only)
    42→-- Existing 'admin' role users will need to be migrated to dev_admin or org_admin
    43→
    44→COMMENT ON TABLE user_organizations IS 'Maps users to organizations with their role within each org';
    45→COMMENT ON COLUMN user_organizations.role IS 'Role within the organization: org_admin or org_user';
    46→COMMENT ON COLUMN clients.tech_seat_limit IS 'Maximum number of users allowed in this organization (NULL = unlimited)';
    47→COMMENT ON COLUMN clients.endpoint_limit IS 'Maximum number of agents allowed in this organization (NULL = unlimited)';
    48→COMMENT ON COLUMN clients.is_organization IS 'Whether this client is a paying organization';
    49→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>

-- Multi-tenant authorization system
-- Adds organization limits and user-organization relationships

-- Add organization limits to clients table
ALTER TABLE clients ADD COLUMN IF NOT EXISTS tech_seat_limit INTEGER DEFAULT NULL;
ALTER TABLE clients ADD COLUMN IF NOT EXISTS endpoint_limit INTEGER DEFAULT NULL;
ALTER TABLE clients ADD COLUMN IF NOT EXISTS is_organization BOOLEAN DEFAULT TRUE;

-- User-Organization relationship table
-- Replaces the simple role column on users table for multi-tenant access
CREATE TABLE IF NOT EXISTS user_organizations (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    client_id UUID NOT NULL REFERENCES clients(id) ON DELETE CASCADE,
    role VARCHAR(50) NOT NULL DEFAULT 'org_user',  -- org_admin, org_user
    created_at TIMESTAMPTZ DEFAULT NOW(),
    created_by UUID REFERENCES users(id) ON DELETE SET NULL,
    UNIQUE(user_id, client_id)
);

-- Indexes for efficient querying
CREATE INDEX IF NOT EXISTS idx_user_orgs_user ON user_organizations(user_id);
CREATE INDEX IF NOT EXISTS idx_user_orgs_client ON user_organizations(client_id);
CREATE INDEX IF NOT EXISTS idx_user_orgs_role ON user_organizations(role);

-- View for organization statistics (limits and current usage)
CREATE OR REPLACE VIEW organization_stats AS
SELECT
    c.id as client_id,
    c.name as client_name,
    c.tech_seat_limit,
    c.endpoint_limit,
    COALESCE((SELECT COUNT(*) FROM user_organizations WHERE client_id = c.id), 0)::INTEGER as tech_count,
    COALESCE((SELECT COUNT(*) FROM agents a JOIN sites s ON a.site_id = s.id WHERE s.client_id = c.id), 0)::INTEGER as endpoint_count
FROM clients c
WHERE c.is_organization = TRUE;

-- Update users table: ensure role column supports system-level roles
-- 'dev_admin' = system admin (full access)
-- 'support' = support tier (future)
-- 'user' = regular user (access via org membership only)
-- Existing 'admin' role users will need to be migrated to dev_admin or org_admin

COMMENT ON TABLE user_organizations IS 'Maps users to organizations with their role within each org';
COMMENT ON COLUMN user_organizations.role IS 'Role within the organization: org_admin or org_user';
COMMENT ON COLUMN clients.tech_seat_limit IS 'Maximum number of users allowed in this organization (NULL = unlimited)';
COMMENT ON COLUMN clients.endpoint_limit IS 'Maximum number of agents allowed in this organization (NULL = unlimited)';
COMMENT ON COLUMN clients.is_organization IS 'Whether this client is a paying organization';


Perfect! Now let me check the dashboard components to understand the UI structure:


Bash

ls -la "C:\Users\MikeSwanson\claude-projects\gururmm\dashboard\src\components" | head -30


total 24
drwxr-xr-x 1 AzureAD+MikeSwanson 4096    0 Dec 20 17:55 ./
drwxr-xr-x 1 AzureAD+MikeSwanson 4096    0 Dec 21 09:55 ../
-rw-r--r-- 1 AzureAD+MikeSwanson 4096 2066 Dec 20 17:55 Button.tsx
-rw-r--r-- 1 AzureAD+MikeSwanson 4096 1657 Dec 20 17:55 Card.tsx
-rw-r--r-- 1 AzureAD+MikeSwanson 4096  853 Dec 20 17:55 Input.tsx
-rw-r--r-- 1 AzureAD+MikeSwanson 4096 4408 Dec 20 17:55 Layout.tsx


Let me check the agent transport layer to understand agent-server communication:


total 32
drwxr-xr-x 1 AzureAD+MikeSwanson 4096     0 Dec 20 17:55 ./
drwxr-xr-x 1 AzureAD+MikeSwanson 4096     0 Dec 20 18:17 ../
-rw-r--r-- 1 AzureAD+MikeSwanson 4096  7610 Dec 20 17:55 mod.rs
-rw-r--r-- 1 AzureAD+MikeSwanson 4096 17611 Dec 20 17:55 websocket.rs


Perfect! Now I have enough information. Let me compile a comprehensive summary of the GuruRMM project:


     1→-- Extended metrics and agent state
     2→-- Adds columns for uptime, user info, IPs, and network state storage
     3→
     4→-- Add extended columns to metrics table
     5→ALTER TABLE metrics ADD COLUMN IF NOT EXISTS uptime_seconds BIGINT;
     6→ALTER TABLE metrics ADD COLUMN IF NOT EXISTS boot_time BIGINT;
     7→ALTER TABLE metrics ADD COLUMN IF NOT EXISTS logged_in_user VARCHAR(255);
     8→ALTER TABLE metrics ADD COLUMN IF NOT EXISTS user_idle_seconds BIGINT;
     9→ALTER TABLE metrics ADD COLUMN IF NOT EXISTS public_ip VARCHAR(45);  -- Supports IPv6
    10→
    11→-- Agent state table for current/latest agent information
    12→-- This stores the latest snapshot of extended agent info (not time-series)
    13→CREATE TABLE IF NOT EXISTS agent_state (
    14→    agent_id UUID PRIMARY KEY REFERENCES agents(id) ON DELETE CASCADE,
    15→    -- Network state
    16→    network_interfaces JSONB,
    17→    network_state_hash VARCHAR(32),
    18→    -- Latest extended metrics (cached for quick access)
    19→    uptime_seconds BIGINT,
    20→    boot_time BIGINT,
    21→    logged_in_user VARCHAR(255),
    22→    user_idle_seconds BIGINT,
    23→    public_ip VARCHAR(45),
    24→    -- Timestamps
    25→    network_updated_at TIMESTAMPTZ,
    26→    metrics_updated_at TIMESTAMPTZ DEFAULT NOW()
    27→);
    28→
    29→-- Index for finding agents by public IP (useful for diagnostics)
    30→CREATE INDEX IF NOT EXISTS idx_agent_state_public_ip ON agent_state(public_ip);
    31→
    32→-- Add memory_total_bytes and disk_total_bytes to metrics for completeness
    33→ALTER TABLE metrics ADD COLUMN IF NOT EXISTS memory_total_bytes BIGINT;
    34→ALTER TABLE metrics ADD COLUMN IF NOT EXISTS disk_total_bytes BIGINT;
    35→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>

-- Extended metrics and agent state
-- Adds columns for uptime, user info, IPs, and network state storage

-- Add extended columns to metrics table
ALTER TABLE metrics ADD COLUMN IF NOT EXISTS uptime_seconds BIGINT;
ALTER TABLE metrics ADD COLUMN IF NOT EXISTS boot_time BIGINT;
ALTER TABLE metrics ADD COLUMN IF NOT EXISTS logged_in_user VARCHAR(255);
ALTER TABLE metrics ADD COLUMN IF NOT EXISTS user_idle_seconds BIGINT;
ALTER TABLE metrics ADD COLUMN IF NOT EXISTS public_ip VARCHAR(45);  -- Supports IPv6

-- Agent state table for current/latest agent information
-- This stores the latest snapshot of extended agent info (not time-series)
CREATE TABLE IF NOT EXISTS agent_state (
    agent_id UUID PRIMARY KEY REFERENCES agents(id) ON DELETE CASCADE,
    -- Network state
    network_interfaces JSONB,
    network_state_hash VARCHAR(32),
    -- Latest extended metrics (cached for quick access)
    uptime_seconds BIGINT,
    boot_time BIGINT,
    logged_in_user VARCHAR(255),
    user_idle_seconds BIGINT,
    public_ip VARCHAR(45),
    -- Timestamps
    network_updated_at TIMESTAMPTZ,
    metrics_updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- Index for finding agents by public IP (useful for diagnostics)
CREATE INDEX IF NOT EXISTS idx_agent_state_public_ip ON agent_state(public_ip);

-- Add memory_total_bytes and disk_total_bytes to metrics for completeness
ALTER TABLE metrics ADD COLUMN IF NOT EXISTS memory_total_bytes BIGINT;
ALTER TABLE metrics ADD COLUMN IF NOT EXISTS disk_total_bytes BIGINT;


Excellent! Now I have comprehensive information about the GuruRMM project. Let me create a detailed summary document.

## GuruRMM Project Comprehensive Overview

### Project Summary
**GuruRMM** is a custom-built Remote Monitoring and Management (RMM) system designed for managed service providers (MSPs). It's a production-grade, open-source RMM platform built with Rust (backend and agent), React (dashboard), and PostgreSQL. The project is designed to be API-first with real-time WebSocket communication between agents and the server.

**Current Version:** 0.5.1 (Agent), 0.2.0 (Server), 0.2.0 (Dashboard)

---

### Architecture Overview

```
┌─────────────────────┐         ┌──────────────────┐
│   Client Devices    │         │   macOS/Linux    │
│   (Windows/Linux)   │         │    Workstations  │
│                     │         │                  │
│ ┌─────────────────┐ │         │ ┌──────────────┐ │
│ │GuruRMM Agent    │ │◄────────►│ GuruRMM Agent │ │
│ │(Rust Binary)    │ │WebSocket │  (Rust)      │ │
│ │+ Tray Icon      │ │          │              │ │
│ │+ Watchdog       │ │          └──────────────┘ │
│ │+ Metrics        │ │                            │
│ └─────────────────┘ │                            │
└─────────────────────┘                            └──────────────────┘
         │                               │
         │                               │
         │         SSL/TLS               │
         └──────────────┬────────────────┘
                        │
                 ┌──────▼──────┐
                 │ Jupiter     │
                 │(172.16.3.20)│
                 │ NPM (7818)  │
                 │ Gitea(3000) │
                 └──────┬──────┘
                        │
         ┌──────────────┼──────────────┐
         │              │              │
    ┌────▼─────┐  ┌────▼─────┐  ┌────▼──────┐
    │  Server  │  │Dashboard │  │PostgreSQL │
    │  Rust    │  │  React   │  │  (Port?)  │
    │ :3001    │  │ :3000    │  │           │
    └──────────┘  └──────────┘  └───────────┘
```

**External Deployment:**
- API: https://rmm-api.azcomputerguru.com (behind NPM reverse proxy)
- WebSocket: wss://rmm-api.azcomputerguru.com/ws
- Dashboard: https://rmm-api.azcomputerguru.com/

---

### Core Components

#### 1. **Agent (Rust)**
**Location:** `agent/`
**Language:** Rust
**Version:** 0.5.1

**Purpose:** Runs on managed endpoints (Windows, Linux, macOS), collects metrics, executes commands, monitors services

**Key Features:**
- **Cross-Platform Support:**
  - Windows (x64 native service via Windows Service API)
  - Windows Server 2008 R2 (legacy mode via NSSM wrapper + PowerShell agent)
  - Linux (systemd)
  - macOS (planned)

- **Metrics Collection:**
  - CPU usage (%)
  - Memory (usage %, used/total bytes)
  - Disk (usage %, used/total bytes, per-disk)
  - Network (RX/TX bytes since last collection)
  - System uptime and boot time
  - OS info (type, version)
  - Hostname and device ID
  - Logged-in user
  - User idle time
  - Public/WAN IP address
  - Temperature sensors (CPU, GPU, all sensors)
  - Network interfaces (local IPs)

- **Communication:**
  - WebSocket client (TLS for production, fallback HTTP for registration)
  - Heartbeat mechanism (~every 60 seconds)
  - JSON message protocol

- **Command Execution:**
  - PowerShell (Windows)
  - Bash (Linux/macOS)
  - Cross-platform command runner
  - Result streaming (stdout/stderr/exit code)

- **Service Watchdog:**
  - Monitor specified services
  - Track service restarts
  - Alert on service failures
  - Auto-restart capability (configurable)

- **Self-Update:**
  - Download and verify updates from server
  - SHA256 checksum validation
  - Atomic binary replacement
  - Auto-rollback on connection failure
  - Version tracking

- **Tray Application (Windows):**
  - System tray icon (green/yellow/red/gray states)
  - Connection status indicator
  - Admin-controlled visibility and menu items
  - IPC communication (named pipes)
  - Support ticket creation form
  - Screenshot capture for tickets
  - System info dialog

- **Configuration:**
  - TOML configuration file
  - Site code and API key auth
  - Server URL configuration
  - Policy-based settings

**Key Files:**
- `src/main.rs` - CLI and service entry point
- `src/metrics/mod.rs` - Metrics collection engine
- `src/service.rs` - Windows service implementation
- `src/transport/websocket.rs` - WebSocket client
- `src/transport/mod.rs` - Message serialization
- `src/commands/` - Command execution
- `src/ipc.rs` - Named pipe IPC server
- `src/tray_launcher.rs` - Tray app launcher
- `src/updater/` - Self-update system

**Dependencies (Notable):**
- `tokio` - async runtime
- `sysinfo` - system metrics
- `tokio-tungstenite` - WebSocket client
- `windows-service` - Windows service API
- `clap` - CLI argument parsing
- `serde/serde_json` - serialization

---

#### 2. **Server (Rust)**
**Location:** `server/`
**Language:** Rust (Axum web framework)
**Version:** 0.2.0

**Purpose:** Central management server, API endpoint, WebSocket gateway, database orchestrator

**Key Features:**

- **Web Framework:**
  - Axum (Tokio-based async web server)
  - REST API (JSON)
  - WebSocket endpoint for agent connections
  - Health check endpoint

- **Authentication & Authorization:**
  - JWT token-based auth (dashboard users)
  - API keys for agents (site-based)
  - Multi-tenant authorization system
  - SSO support (Microsoft Entra ID)
  - Role-based access control (RBAC)
  - Organization-level access management
  - User impersonation (dev admin only)

- **Agent Management:**
  - Agent registration
  - Agent status tracking
  - Agent-site mapping
  - Bulk operations
  - Unassigned agent listing
  - Move agents between sites
  - Trigger on-demand updates
  - Agent deletion

- **Organization & Multi-Tenancy:**
  - Organization limits (tech seats, endpoints)
  - User-organization relationships
  - Organization admin roles
  - Organization stats/usage view
  - Per-organization data isolation

- **Site Management:**
  - Site creation/update/delete
  - Site codes (human-friendly registration: "BLUE-TIGER-4829")
  - API key generation and rotation
  - Per-site settings

- **Client Management:**
  - Client creation and management
  - Client-site hierarchy
  - Client metadata

- **Policy System:**
  - Stackable policies (JSON-based configuration)
  - Policy templates
  - Policy assignments at client/site/agent level
  - Priority-based merge logic (higher priority wins)
  - Dynamic policy evaluation

- **Command Management:**
  - Send commands to agents via WebSocket
  - Command queuing
  - Command history tracking
  - Result storage (stdout, stderr, exit code)
  - Command audit logging

- **Metrics & Data Storage:**
  - Time-series metrics storage in PostgreSQL
  - Agent state snapshots
  - Extended metrics (uptime, user info, IPs)
  - Network state caching
  - Metrics retrieval with time filtering

- **Real-Time Communication:**
  - Agent connection pooling
  - Message dispatch to online agents
  - Connection state tracking
  - WebSocket message framing

- **Alerts & Thresholds:**
  - Threshold-based alert triggering
  - Alert deduplication (dedup_key)
  - Alert states (active, acknowledged, resolved)
  - Duration-based alerts (CPU > 80% for 5 min)
  - Severity levels (info, warning, critical)
  - Alert threshold state tracking
  - Alert acknowledgment and resolution

- **Agent Updates:**
  - Update manager with version scanning
  - Auto-update capability
  - Version storage and tracking
  - Update packaging
  - Download URL management
  - Background version scanner

- **API Endpoints:**

  | Category | Endpoints |
  |----------|-----------|
  | **Auth** | POST /api/auth/login, /register, GET /api/auth/me, SSO callbacks |
  | **Users** | GET /api/users, /users/:id, DELETE /users/:id, PUT /users/:id/role |
  | **Clients** | GET/POST/PUT/DELETE /api/clients, /clients/:id/sites |
  | **Sites** | GET/POST/PUT/DELETE /api/sites, POST /sites/:id/regenerate-key |
  | **Agents** | GET/POST/DELETE /api/agents, /agents/stats, /agents/unassigned, /agents/:id/state, /agents/:id/update |
  | **Metrics** | GET /api/agents/:id/metrics, /metrics/summary |
  | **Commands** | POST /api/agents/:id/command, GET /api/commands, /commands/:id |
  | **Policies** | GET/POST/PUT/DELETE /api/policies, /policies/:id/assign, /policies/:id/assignments |
  | **Alerts** | GET/POST /api/alerts, /alerts/:id/acknowledge, /alerts/:id/resolve |
  | **Organizations** | GET/PUT /api/organizations, /organizations/:id/users, /organizations/:id/limits |
  | **Legacy** | POST /api/agent/register-legacy, /agent/heartbeat, /agent/command-result |

**Key Files:**
- `src/main.rs` - Server entry point and router setup
- `src/api/` - REST API handlers
  - `agents.rs` - Agent management
  - `alerts.rs` - Alert management
  - `auth.rs` - Authentication
  - `clients.rs` - Client management
  - `commands.rs` - Command execution
  - `metrics.rs` - Metrics retrieval
  - `organizations.rs` - Organization/multi-tenant
  - `policies.rs` - Policy management
  - `sites.rs` - Site management
  - `sso.rs` - SSO integration
  - `users.rs` - User management
- `src/db/` - Database operations
- `src/ws/mod.rs` - WebSocket handler
- `src/alerts/` - Alert evaluation engine
- `src/auth/` - JWT and API key auth
- `src/authz/` - Authorization checks
- `src/policy/` - Policy evaluation
- `src/updates/` - Update manager
- `migrations/` - SQL migrations

**Database:** PostgreSQL 16

**Dependencies (Notable):**
- `axum` - web framework
- `tokio` - async runtime
- `sqlx` - database driver with compile-time query checking
- `serde/serde_json` - serialization
- `jsonwebtoken` - JWT handling
- `oauth2` - SSO support
- `tower-http` - CORS, compression, tracing

---

#### 3. **Dashboard (React + TypeScript)**
**Location:** `dashboard/`
**Language:** TypeScript/React
**Version:** 0.2.0
**Build Tool:** Vite

**Purpose:** Web-based UI for managing RMM infrastructure

**Key Features:**

- **Pages:**
  - **Login** - Email/password authentication, SSO support
  - **Register** - New user registration
  - **Dashboard** - Overview/summary view
  - **Agents** - List agents with status, metrics, actions
  - **Agent Detail** - Detailed agent view with metrics charts
  - **Clients** - Client management
  - **Sites** - Site management, site codes, API key rotation
  - **Commands** - Command execution and history
  - **Settings** - User settings, organization settings
  - **Auth Callback** - SSO redirect handler

- **Components:**
  - Reusable UI components (Button, Card, Input, Layout)
  - Lucide React icons
  - Responsive design with Tailwind CSS

- **Features:**
  - Real-time metric visualization (Recharts)
  - Agent status indicators
  - Command execution interface
  - Metrics charts and summaries
  - Authentication with JWT
  - SSO integration (Entra ID)
  - Organization management
  - Protected routes

- **API Integration:**
  - Axios HTTP client
  - React Query for data fetching and caching
  - WebSocket integration (planned for real-time updates)

- **Styling:**
  - Tailwind CSS
  - Modern, clean design
  - Responsive layout

**Key Files:**
- `src/App.tsx` - Main router
- `src/pages/` - Page components
- `src/components/` - Reusable components
- `src/hooks/useAuth.tsx` - Authentication hook
- `src/api/` - API client

**Dependencies:**
- `react` / `react-dom`
- `react-router-dom` - routing
- `@tanstack/react-query` - data fetching
- `axios` - HTTP client
- `recharts` - charting
- `tailwindcss` - styling
- `lucide-react` - icons
- `vite` - build tool

---

### Database Schema

**PostgreSQL Database**

**Core Tables:**

1. **agents** - Endpoint devices
   - id, hostname, api_key_hash, os_type, os_version, agent_version
   - last_seen, status (online/offline)
   - device_id, site_id
   - created_at, updated_at

2. **metrics** - Time-series system metrics
   - id, agent_id, timestamp
   - cpu_percent, memory_percent/bytes, disk_percent/bytes
   - network_rx/tx_bytes
   - uptime_seconds, boot_time, logged_in_user, user_idle_seconds, public_ip
   - memory_total_bytes, disk_total_bytes

3. **agent_state** - Latest agent snapshots
   - agent_id, network_interfaces (JSONB), network_state_hash
   - uptime_seconds, boot_time, logged_in_user, user_idle_seconds, public_ip
   - network_updated_at, metrics_updated_at

4. **users** - Dashboard users
   - id, email, password_hash, name, role
   - sso_provider, sso_id
   - created_at, last_login

5. **user_organizations** - Multi-tenant user mapping
   - id, user_id, client_id, role (org_admin, org_user)
   - created_at, created_by

6. **clients** - Organizations/companies
   - id, name, code, notes, is_active
   - tech_seat_limit, endpoint_limit, is_organization
   - created_at, updated_at

7. **sites** - Locations under a client
   - id, client_id, name, site_code
   - api_key_hash, address, notes, is_active
   - created_at, updated_at

8. **commands** - Executed commands
   - id, agent_id, command_type, command_text
   - status (pending/running/success/failed), exit_code
   - stdout, stderr
   - created_at, started_at, completed_at, created_by

9. **watchdog_events** - Service monitoring events
   - id, agent_id, timestamp
   - service_name, event_type, details

10. **policies** - Reusable configuration templates
    - id, name, description
    - policy_data (JSONB: metrics, thresholds, tray, updates, watchdog)
    - is_default, created_at, updated_at, created_by

11. **policy_assignments** - Policy-to-target mappings
    - id, policy_id, client_id/site_id/agent_id (exactly one)
    - priority, created_at, created_by

12. **alerts** - Threshold violation alerts
    - id, agent_id, alert_type, severity
    - title, message, metric_value, threshold_value
    - status (active/acknowledged/resolved)
    - acknowledged_at/by, resolved_at
    - dedup_key, triggered_at, last_seen_at, created_at

13. **alert_threshold_state** - Duration-based alert tracking
    - agent_id, threshold_key
    - violation_started_at, consecutive_violations, last_value, last_checked_at

14. **agent_updates** - Version tracking
    - id, agent_id, version, status
    - download_url, checksum, etc.

15. **registration_tokens** - Site enrollment tokens
    - id, site_id, token_hash, description
    - uses_remaining, expires_at, created_at, created_by

---

### WebSocket Message Protocol

**Agent → Server (AgentMessage):**
- `Auth` - Initial connection authentication
- `Metrics` - Periodic metrics submission
- `NetworkState` - Network interface updates
- `CommandResult` - Executed command results
- `WatchdogEvent` - Service status events
- `UpdateResult` - Update completion status
- `Heartbeat` - Keep-alive

**Server → Agent (ServerMessage):**
- `AuthAck` - Authentication response
- `Command` - Execute command on agent
- `ConfigUpdate` - Push configuration changes
- `Update` - Trigger agent update
- `Ack` - Message acknowledgment
- `Error` - Error response

---

### Technology Stack

| Component | Technology | Version |
|-----------|-----------|---------|
| **Agent** | Rust | 2021 edition |
| **Server** | Rust (Axum) | 0.7 |
| **Dashboard** | React + TypeScript | 19.x / 5.9 |
| **Build Tool** | Vite | 7.2 |
| **Database** | PostgreSQL | 16 |
| **Package Manager** | npm | - |
| **Web Framework** | Axum | 0.7 |
| **Async Runtime** | Tokio | 1.x |
| **Styling** | Tailwind CSS | 4.1 |
| **Icons** | Lucide React | 0.561 |
| **Charting** | Recharts | 3.6 |
| **HTTP Client** | Axios | 1.13 |
| **State Mgmt** | React Query | 5.90 |
| **Routing** | React Router | 7.10 |

---

### Deployment

**Production Deployment:**
- **Host:** Jupiter (172.16.3.20)
- **Server Port:** 3001
- **Dashboard Port:** 3000
- **Database:** PostgreSQL (port varies)
- **Reverse Proxy:** NPM (Nginx Proxy Manager) on port 7818
- **External URL:** https://rmm-api.azcomputerguru.com

**Build Server:**
- **Host:** 172.16.3.30 (Ubuntu 22.04)
- **Purpose:** Cross-platform builds
- **Agent Builds:** Linux, Windows (via mingw-w64)

**Docker Support:**
- Docker Compose configuration available (deprecated for production)
- Used for development/testing

---

### Development Phases (From Roadmap)

1. **Phase 1: Foundation (MVP)** ✓ Partially Complete
   - Agent heartbeat, metrics, Windows/Linux
   - Server API, database
   - Basic dashboard
   - Threshold alerts

2. **Phase 2: Operational** 🔄 In Progress
   - Remote commands (PowerShell/Bash)
   - Service monitoring and watchdog
   - Patch status, software inventory
   - Alert escalation
   - Basic reporting

3. **Phase 3: PSA Integration** 📋 Planned
   - GuruPSA companion product
   - Alert-to-ticket automation
   - Time tracking, billing

4. **Phase 4: Scale & Polish** 📋 Planned
   - Kubernetes deployment
   - Advanced reporting
   - Third-party integrations

5. **Phase 5: Intelligence** 📋 Planned
   - AI ticket enhancement
   - Anomaly detection
   - Predictive alerting

---

### Current State & Recent Work

**Latest Version (Jan 8, 2026):**
- Agent: 0.5.1
- Server: 0.2.0
- Dashboard: 0.2.0

**Recent Commits (Last 20):**
1. Multi-tenant authorization system (Phases 1-2)
2. Stackable policy system with alert evaluation
3. Temperature metrics collection
4. Microsoft Entra ID SSO
5. JWT authentication for commands/updates
6. On-demand agent updates
7. Tray launcher for Windows user sessions
8. Tray icon system (IPC, menu, states)
9. Legacy PowerShell agent support
10. Windows 7/2008 R2 compatibility (native-tls)

**Implemented Features:**
- Multi-client/multi-site support
- Agent registration and management
- Real-time metrics collection
- Command execution (PowerShell, Bash)
- Service watchdog monitoring
- Alert system with thresholds
- Policy-based configuration
- Multi-tenant authorization
- SSO authentication (Entra ID)
- System tray integration (Windows)
- Self-update mechanism
- Temperature monitoring

**Pending Tasks (from CLAUDE.md):**
- Build updated agent with extended metrics on build server
- Agent source updated, needs cross-platform builds (Linux/Windows/macOS)

---

### Key Architectural Decisions

1. **Rust for Agent & Server:** Type-safe, memory-safe, high-performance
2. **WebSocket-Based Communication:** Real-time bidirectional messaging
3. **Site-Based Registration:** Human-friendly site codes instead of raw API keys
4. **Stackable Policies:** Flexible, composable configuration management
5. **JWT + API Keys:** Layered authentication
6. **PostgreSQL for Everything:** Time-series, relational, JSON all in one DB
7. **React Dashboard:** Modern, responsive UI with TypeScript safety
8. **Multi-Tenant from Day One:** Organizations, users, roles built in
9. **IPC for Tray App:** Separate process model for user-facing UI

---

### Security Considerations

- JWT authentication with configurable expiry
- API key hashing (not stored in plaintext)
- Site-based API keys (all agents at a site share one key)
- Multi-tenant data isolation
- RBAC with organization roles
- SSO integration for enterprise auth
- WebSocket TLS encryption
- SHA256 checksum verification for updates
- Code signing (planned for pre-release)

---

### Monitoring & Metrics

The system monitors:
- **System Resources:** CPU, memory, disk usage
- **Network:** RX/TX bytes, local IPs, public IP
- **User Info:** Logged-in user, idle time
- **Service Status:** Service state, restart events
- **System Health:** Uptime, boot time
- **Temperature:** CPU, GPU, all sensors
- **Update Status:** Version tracking, update results

---

### Extensibility

1. **Custom Metrics:** Policy-based metric collection
2. **Plugin Architecture:** Planned for third-party modules
3. **Webhook System:** Planned for outbound events
4. **API-First Design:** All functionality accessible via REST API
5. **Policy Templates:** Reusable, composable configurations

---

### Files Summary

**Key Project Files:**

| Path | Purpose |
|------|---------|
| `.env.example` | Environment configuration template |
| `docker-compose.yml` | Docker deployment (deprecated) |
| `agent/Cargo.toml` | Agent dependencies |
| `server/Cargo.toml` | Server dependencies |
| `dashboard/package.json` | Dashboard dependencies |
| `server/migrations/` | PostgreSQL schema |
| `docs/FEATURE_ROADMAP.md` | Feature planning |
| `scripts/` | Deployment/utility scripts |
| `deploy/` | Deployment configurations |
| `assets/` | Icons, images |

---

This comprehensive overview provides a complete understanding of GuruRMM's architecture, features, current state, and direction for writing an app specification file for AutoCoder. The system is a sophisticated, production-grade RMM built on modern technologies with multi-tenant support, real-time communication, and extensive feature planning for future development.