Skip to content

WebUI

The operator + user dashboard for a Gridweave cluster — a Next.js app that's a thin client over the backend services: no database, no business logic, every action is an HTTP call. What you see is role-scoped — admins get the whole cluster, providers their hardware + earnings, users their own jobs/endpoints/wallet — but that scoping is UX; the backends do the real authorization.

How it works

Session. The root layout (app/layout.tsx) is the gate: on load it reads auth_token from localStorage and calls GET /v1/auth/me — no token, or a failed /me, redirects to /login. Only /login, /signup, and /docs render without auth. Every API call sends Authorization: Bearer <token>; a 401 clears the token and bounces to /login. No cookies, no server session.

Talking to the backends. The browser only calls same-origin relative paths; Next.js rewrites (next.config.ts) proxy each to a real service, so there's no CORS:

Call it with (lib/api.ts) Path → Service
GET / POST / PUT / DEL /api/* platform (:8100)
faucetGET / faucetPOST / … /faucet-api/* faucet (:8500)
gatewayGET / gatewayPUT /gateway-api/* gateway (:8200)
creditGET / creditPUT /credit-api/* credit (:8400)

Most pages go through the platform; a few hit faucet/gateway/credit directly. All return typed JSON or throw ApiError(status, detail).

Roles. /v1/auth/me returns your role, which Sidebar uses to pick the nav (admin / provider / user). Hiding a link is convenience, not security — navigate straight to an admin route as a user and the backend still rejects the call.

Live data. Data pages fetch on mount and setInterval-poll every few seconds through those helpers; shared UI primitives (Card, Stat, Field, Spinner, ErrorBox) live in components/.

Pages

Each is a src/app/<route>/page.tsx, gated by role in Sidebar; data pages poll live.

Public (no login): - /login — sign in by pasting your token. - /signup — self-service signup: enter a university email, the faucet emails back a token. - /docs — the SDK docs (/llms.txt), rendered for reading.

All roles: - /jobs — your jobs, with status and streamed logs. Admins and providers see the whole fleet, not just their own. - /endpoints — model endpoints: deploy, start/stop/delete, and live status. - /my-compute (Wallet) — your credit balance and transaction history. - /activity — the platform's CometBFT audit chain: every credit, job, and endpoint event, newest first.

Provider: - /provider (My Hardware) — your contributed nodes, their availability, and what you've earned.

Admin: - /health — live cluster status: nodes online, GPUs, and utilization. - /users — every user, their balances, and management actions. - /config — platform settings: GPU pricing and the revenue split. - /join-keys — create, list, and revoke the keys providers use to add nodes. - /onboard-user — manually create a user and grant them credits. - /diagnostics — the operator's console: streamed service/node logs and health timelines.

Stack & config

Next.js 15 (App Router) · React 19 · TypeScript · Tailwind 4 · Playwright (e2e). Runs on port 3000.

Variable Default Proxies
PLATFORM_API_URL http://localhost:8100 /api/*
FAUCET_API_URL http://localhost:8500 /faucet-api/*
GATEWAY_API_URL http://localhost:8200 /gateway-api/*
CREDIT_API_URL http://localhost:8400 /credit-api/*

Run & test

# Needs the backends running (platform on :8100 at minimum — see docs/platform_service):
cd webui && npm install && npm run dev        # http://localhost:3000, log in with a token
docker compose -f docker/webui/docker-compose.test.yml up --build -d   # or containerized

# Playwright e2e (starts the dev server itself):
cd webui && npx playwright install chromium && npm run test:e2e
# Python Docker integration:
pytest tests/webui/test_docker.py -v