Dashboard
Primary control plane for managing your agent infrastructure. Built with Svelte frontend and Rust backend.
Overview
The Dashboard provides a web-based interface for deploying, monitoring, and managing agents. It’s the main entry point for most users.
Features
- Agent CRUD operations
- Real-time metrics visualization
- Configuration management
- Log streaming
- User management
- Billing overview
Architecture
┌─────────────────────────────────────────┐
│ Svelte Frontend (Port 3000) │
│ SvelteKit • TypeScript • Tailwind │
└─────────────────────────────────────────┘
↓ REST API
┌─────────────────────────────────────────┐
│ Rust Backend (Port 8000) │
│ Axum • Tokio • SQLx • Serde │
└─────────────────────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ PostgreSQL Database │
└─────────────────────────────────────────┘
Running
Development
cd neuais.com/hub.neuais.com/dashboard.neuais.com
# Start backend
cd backend
cargo run
# Start frontend (new terminal)
cd frontend
npm run dev
Access at: http://localhost:3000
Production
# Build backend
cd backend
cargo build --release
# Build frontend
cd frontend
npm run build
# Run
./backend/target/release/dashboard-backend &
cd frontend && npm run preview
API Endpoints
Authentication
POST /api/auth/login
POST /api/auth/logout
GET /api/auth/me
Agents
GET /api/agents
POST /api/agents
GET /api/agents/{id}
PUT /api/agents/{id}
DELETE /api/agents/{id}
POST /api/agents/{id}/start
POST /api/agents/{id}/stop
POST /api/agents/{id}/restart
GET /api/agents/{id}/logs
GET /api/agents/{id}/metrics
Users
GET /api/users
POST /api/users
GET /api/users/{id}
PUT /api/users/{id}
DELETE /api/users/{id}
Billing
GET /api/billing/usage
GET /api/billing/invoices
GET /api/billing/payment-methods
Frontend Structure
frontend/
├── src/
│ ├── routes/
│ │ ├── +page.svelte # Home
│ │ ├── agents/
│ │ │ ├── +page.svelte # Agent list
│ │ │ └── [id]/
│ │ │ └── +page.svelte # Agent details
│ │ ├── users/
│ │ └── billing/
│ ├── lib/
│ │ ├── components/
│ │ │ ├── AgentCard.svelte
│ │ │ ├── MetricsChart.svelte
│ │ │ └── LogViewer.svelte
│ │ ├── stores/
│ │ └── api/
│ └── app.html
├── static/
└── package.json
Backend Structure
backend/
├── src/
│ ├── main.rs # Entry point
│ ├── routes/
│ │ ├── agents.rs
│ │ ├── auth.rs
│ │ ├── users.rs
│ │ └── billing.rs
│ ├── models/
│ │ ├── agent.rs
│ │ ├── user.rs
│ │ └── billing.rs
│ ├── db/
│ │ ├── mod.rs
│ │ └── migrations/
│ └── middleware/
│ ├── auth.rs
│ └── cors.rs
└── Cargo.toml
Configuration
backend/config.toml:
[server]
host = "0.0.0.0"
port = 8000
[database]
url = "postgresql://user:pass@localhost/neuais"
max_connections = 10
[auth]
jwt_secret = "your-secret-key"
token_expiry = "24h"
[cors]
allowed_origins = ["http://localhost:3000"]
Database Schema
CREATE TABLE agents (
id UUID PRIMARY KEY,
name VARCHAR(255) NOT NULL,
status VARCHAR(50) NOT NULL,
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL
);
CREATE TABLE users (
id UUID PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
role VARCHAR(50) NOT NULL,
created_at TIMESTAMP NOT NULL
);
CREATE TABLE agent_metrics (
id SERIAL PRIMARY KEY,
agent_id UUID REFERENCES agents(id),
cpu_usage FLOAT,
memory_usage BIGINT,
timestamp TIMESTAMP NOT NULL
);
Components
AgentCard
<script lang="ts">
export let agent: Agent;
</script>
<div class="card">
<h3>{agent.name}</h3>
<p>Status: {agent.status}</p>
<p>CPU: {agent.metrics.cpu}%</p>
<p>Memory: {agent.metrics.memory}MB</p>
</div>
MetricsChart
<script lang="ts">
import { onMount } from 'svelte';
export let agentId: string;
let metrics = [];
onMount(async () => {
const res = await fetch(`/api/agents/${agentId}/metrics`);
metrics = await res.json();
});
</script>
<canvas bind:this={canvas}></canvas>
Authentication
Login Flow
- User submits credentials
- Backend validates against database
- Backend generates JWT token
- Frontend stores token in localStorage
- Frontend includes token in all API requests
Example
// Login
const response = await fetch('/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password })
});
const { token } = await response.json();
localStorage.setItem('token', token);
// Authenticated request
fetch('/api/agents', {
headers: {
'Authorization': `Bearer ${token}`
}
});
Real-Time Updates
WebSocket Connection
const ws = new WebSocket('ws://localhost:8000/ws');
ws.onmessage = (event) => {
const update = JSON.parse(event.data);
if (update.type === 'agent_status') {
updateAgentStatus(update.agent_id, update.status);
}
};
Deployment
Docker
# Backend
FROM rust:1.75 as builder
WORKDIR /app
COPY backend/ .
RUN cargo build --release
FROM debian:bookworm-slim
COPY --from=builder /app/target/release/dashboard-backend /usr/local/bin/
CMD ["dashboard-backend"]
# Frontend
FROM node:20 as builder
WORKDIR /app
COPY frontend/ .
RUN npm install && npm run build
FROM node:20-slim
COPY --from=builder /app/build /app
CMD ["node", "/app"]
Fly.io
fly.toml:
app = "neuais-dashboard"
[build]
dockerfile = "Dockerfile"
[[services]]
internal_port = 8000
protocol = "tcp"
[[services.ports]]
port = 80
handlers = ["http"]
[[services.ports]]
port = 443
handlers = ["tls", "http"]
Deploy:
fly deploy
Troubleshooting
Backend won’t start
Check database connection:
psql postgresql://user:pass@localhost/neuais
Frontend build fails
Clear node_modules:
rm -rf node_modules package-lock.json
npm install
CORS errors
Update allowed_origins in config.toml
WebSocket disconnects
Check firewall rules and load balancer settings
Next Steps
- Admin Portal - System administration
- Observatory - 3D visualization
- CLI Tool - Command-line interface