@@ -25,41 +25,75 @@ Unified dashboard that brings together Configuration Management, an Interactive
2525
2626These are sufficient to embed and proxy—no need to duplicate core functionality.
2727
28- ## Architecture (MVP)
29-
30- - frontend/ (SPA)
31- - Tabs: Monitoring, Config Viewer, Playground
32- - Iframes for Grafana dashboards and Open WebUI
33- - Simple viewer for router config JSON
34- - backend/ (Go HTTP server)
35- - Serves static frontend
36- - Reverse proxy with auth/cors/csp controls:
37- - ` GET /embedded/grafana/* ` → Grafana
38- - ` GET /embedded/prometheus/* ` → Prometheus (optional link-outs)
39- - ` GET /embedded/openwebui/* ` → Open WebUI (optional)
40- - ` GET /api/router/* ` → Router Classification API (` :8080 ` )
41- - ` GET /metrics/router ` → Router ` /metrics ` (optional aggregation later)
42- - Normalizes headers for iframe embedding: strips/overrides ` X-Frame-Options ` and ` Content-Security-Policy ` frame-ancestors as needed
43- - Central point for JWT/OIDC in the future (forward or exchange tokens to upstreams)
44-
45- ## Directory layout
28+ ## Architecture
29+
30+ ### Frontend (React + TypeScript + Vite)
31+
32+ Modern SPA built with:
33+
34+ - ** React 18** with TypeScript for type safety
35+ - ** Vite 5** for fast development and optimized builds
36+ - ** React Router v6** for client-side routing
37+ - ** CSS Modules** for scoped styling with theme support (dark/light mode)
38+
39+ Pages:
40+
41+ - ** Monitoring** (` /monitoring ` ): Grafana dashboard embedding with custom path input
42+ - ** Config** (` /config ` ): Real-time configuration viewer with multiple endpoints
43+ - ** Playground** (` /playground ` ): Open WebUI interface for testing
44+
45+ Features:
46+
47+ - 🌓 Dark/Light theme toggle with localStorage persistence
48+ - 📱 Responsive design
49+ - ⚡ Fast navigation with React Router
50+ - 🎨 Modern UI inspired by vLLM website design
51+
52+ ### Backend (Go HTTP Server)
53+
54+ - Serves static frontend (Vite production build)
55+ - Reverse proxy with auth/cors/csp controls:
56+ - ` GET /embedded/grafana/* ` → Grafana
57+ - ` GET /embedded/prometheus/* ` → Prometheus (optional link-outs)
58+ - ` GET /embedded/openwebui/* ` → Open WebUI (optional)
59+ - ` GET /api/router/* ` → Router Classification API (` :8080 ` )
60+ - ` GET /metrics/router ` → Router ` /metrics ` (optional aggregation later)
61+ - ` GET /healthz ` → Health check endpoint
62+ - Normalizes headers for iframe embedding: strips/overrides ` X-Frame-Options ` and ` Content-Security-Policy ` frame-ancestors as needed
63+ - SPA routing support: serves ` index.html ` for all non-asset routes
64+ - Central point for JWT/OIDC in the future (forward or exchange tokens to upstreams)
65+
66+ ## Directory Layout
4667
4768```
4869dashboard/
49- ├── frontend/ # UI for configuration, playground, monitoring
50- │ ├─ Monitoring (iframe Grafana)
51- │ ├─ Config Viewer (fetch /api/router/config/classification)
52- │ └─ Playground (iframe Open WebUI)
53- ├── backend/ # Go proxy, auth, thin API
54- │ ├─ /embedded/grafana → Grafana
55- │ ├─ /embedded/prometheus → Prometheus
56- │ ├─ /embedded/openwebui → Open WebUI
57- │ └─ /api/router/* → Semantic Router API
70+ ├── frontend/ # React + TypeScript SPA
71+ │ ├── src/
72+ │ │ ├── components/ # Reusable components
73+ │ │ │ ├── Layout.tsx # Main layout with header/nav
74+ │ │ │ └── Layout.module.css
75+ │ │ ├── pages/ # Page components
76+ │ │ │ ├── MonitoringPage.tsx # Grafana iframe with path control
77+ │ │ │ ├── ConfigPage.tsx # Config viewer with API fetch
78+ │ │ │ ├── PlaygroundPage.tsx # Open WebUI iframe
79+ │ │ │ └── *.module.css # Scoped styles per page
80+ │ │ ├── App.tsx # Root component with routing
81+ │ │ ├── main.tsx # Entry point
82+ │ │ └── index.css # Global styles & CSS variables
83+ │ ├── public/ # Static assets (vllm.png)
84+ │ ├── package.json # Node dependencies
85+ │ ├── tsconfig.json # TypeScript configuration
86+ │ ├── vite.config.ts # Vite build configuration
87+ │ └── index.html # SPA shell
88+ ├── backend/ # Go reverse proxy server
89+ │ ├── main.go # Proxy routes & static file server
90+ │ ├── go.mod # Go module (minimal dependencies)
91+ │ └── Dockerfile # Multi-stage build (Node + Go + Alpine)
5892├── deploy/
59- │ ├── docker/ # Docker Compose setup for the dashboard
60- │ ├ ── kubernetes/ # K8s manifests (Service/Ingress/ConfigMap)
61- │ └ ── local/ # Local/dev launcher
62- └── helm-chart/ # (optional) Helm chart for dashboard
93+ │ ├── docker/ # Docker Compose overlay (deprecated)
94+ │ └ ── kubernetes/ # K8s manifests (Service/Ingress/ConfigMap)
95+ ├ ── README.md # This file
96+ └── RISKS.md # Security considerations
6397```
6498
6599## Environment-agnostic configuration
@@ -190,16 +224,24 @@ docker compose -f tools/observability/docker-compose.obs.yml up -d
190224cd src/semantic-router
191225go run cmd/main.go -config ../../config/config.yaml
192226
193- # 3. Start the Dashboard backend (local development)
227+ # 3. Install frontend dependencies
228+ cd dashboard/frontend
229+ npm install
230+
231+ # 4. Start the frontend dev server (with HMR)
232+ npm run dev
233+ # Vite will start on http://localhost:3001 with proxy to backend
234+
235+ # 5. Start the Dashboard backend (in another terminal)
194236cd dashboard/backend
195237export TARGET_GRAFANA_URL=http://localhost:3000
196238export TARGET_PROMETHEUS_URL=http://localhost:9090
197239export TARGET_ROUTER_API_URL=http://localhost:8080
198240export TARGET_ROUTER_METRICS_URL=http://localhost:9190/metrics
199- go run main.go -port=8700 -static=../frontend
241+ go run main.go -port=8700 -static=../frontend/dist
200242
201- # 4. Open your browser
202- open http://localhost:8700
243+ # For development, use the Vite dev server at http://localhost:3001
244+ # For production preview, build first: cd frontend && npm run build
203245```
204246
205247### Method 3: Rebuild Dashboard Only
@@ -227,9 +269,12 @@ docker logs -f semantic-router-dashboard
227269
228270### Dockerfile Build
229271
230- - A multi-stage build (Go builder → distroless) is defined in ` dashboard/backend/Dockerfile ` .
231- - An independent Go module ` dashboard/backend/go.mod ` isolates dependencies.
232- - Frontend static assets are packaged into the image at ` /app/frontend ` .
272+ - A ** 3-stage multi-stage build** is defined in ` dashboard/backend/Dockerfile ` :
273+ 1 . ** Node.js stage** : Builds the React frontend with Vite (` npm run build ` → ` dist/ ` )
274+ 2 . ** Go builder stage** : Compiles the backend binary
275+ 3 . ** Alpine runtime stage** : Combines backend + frontend dist in minimal image
276+ - An independent Go module ` dashboard/backend/go.mod ` isolates backend dependencies.
277+ - Frontend production build (` dist/ ` ) is packaged into the image at ` /app/frontend ` .
233278
234279### Grafana Embedding Support
235280
0 commit comments