React 18 + TypeScript + Vite frontend for the customer dashboard. This is where users log in, view their provisioned resources, upgrade their plan, and manage their team. It talks directly to the agent-facing API at api.instanode.dev.
The dashboard is a single-page app that calls the agent API at api.instanode.dev for every operation: auth, claim, billing, team management, resource CRUD, and stacks. There is no intermediate backend — the browser holds a bearer token (localStorage.instanode.token) and includes it on every request.
In dev, Vite proxies /api, /auth, /claim, /db, /cache, /nosql, /queue, /storage, /webhook, /.well-known to AGENT_API_URL (default http://api.instanode.dev). In prod, the dashboard ships as a static bundle on GitHub Pages and issues cross-origin fetches directly to https://api.instanode.dev (set via the VITE_API_URL build env).
cd dashboard
npm install
npm run dev # Vite dev server at http://localhost:5173To point the dev proxy at a local k8s cluster (the Service is ClusterIP — NodePort
retired 2026-05-11 — so port-forward svc/instant-api first):
kubectl port-forward -n instant svc/instant-api 8080:8080 &
AGENT_API_URL=http://localhost:8080 npm run devTo run unit tests:
npm testsrc/
├── hooks/
│ ├── useAuth.ts # Bearer-token session management
│ └── useResources.ts # Fetches and caches the resource list
├── pages/
│ ├── LoginPage.tsx # Email magic link / PAT entry point
│ ├── DashboardPage.tsx # Main resource list view
│ ├── ClaimPage.tsx # Anonymous → account conversion (arrives via /start?t=jwt)
│ ├── BillingPage.tsx # Plan status + upgrade flow
│ ├── SettingsPage.tsx # Team name, member management
│ ├── ResourceDetailPage.tsx # Per-resource view + rotate credentials
│ └── DeployPage.tsx # Container deploy entrypoint
└── components/
├── Layout/ # Sidebar + top nav shell
├── ResourceCard/ # Resource summary card used in DashboardPage
├── StatusBadge/ # Active / expired / migrating badge
├── UpgradeBanner/ # Shown when approaching free-tier limits
└── UsageBar/ # Storage usage visualization
- User pastes a PAT or completes the email magic-link flow on
LoginPage. - The bearer token is stored in
localStorage.instanode.tokenand attached asAuthorization: Bearer <token>on every subsequent request. useAuth.tscallsGET /auth/meon mount to hydrate session state.- On 401, the client clears the token, stores the current path under
instanode.return_to, and redirects to/login.
When an anonymous user hits a resource limit, the agent API embeds an upgrade URL in the response:
https://instanode.dev/start?t=<signed-jwt>
That URL hits GET /start on the agent API, which validates the JWT and issues a 302 redirect to:
http://localhost:5173/claim?t=<jwt>
ClaimPage.tsx picks up the t parameter, lets the user choose a login method, and calls POST /claim on the agent API to atomically convert the anonymous session into a full account. The JWT in the claim is single-use — a second call returns 409 Conflict, preventing double-conversion.
107 tests covering auth guards, the upgrade journey, and resource interactions.
# Requires: Vite dev server running (npm run dev) + agent API port-forwarded
# (Service is ClusterIP; NodePort retired):
# kubectl port-forward -n instant svc/instant-api 8080:8080
E2E_API_URL=http://localhost:8080 npx playwright test --project=chromium
# Run a single spec
npx playwright test e2e/auth-guards.spec.ts --project=chromium
# Headed mode for debugging
npx playwright test --headed --project=chromiumNote on VITE_NO_PROXY=1: E2E tests set this flag to disable the Vite dev proxy. All API calls in tests go through page.route() mocks or directly via the request fixture against E2E_API_URL. Without this flag, Vite rewrites API URLs and tests break against the real cluster.
| Variable | Purpose | Default |
|---|---|---|
AGENT_API_URL |
Upstream the Vite dev proxy points at | http://api.instanode.dev |
VITE_API_URL |
Build-time override for the production bundle | https://api.instanode.dev |
VITE_NO_PROXY |
Disables Vite proxy (set to 1 in E2E) |
unset |
E2E_API_URL |
Agent API base URL used by Playwright tests (port-forward svc/instant-api first) |
http://localhost:8080 |
- RotateCredentials: the UI calls
POST /api/v1/resources/:id/rotate-credentialson the agent API. Rotation is implemented for Postgres, Redis, and MongoDB. - Razorpay Checkout: the "Upgrade to Pro" button calls
POST /api/v1/billing/checkouton the agent API and redirects to the returned Razorpay short URL. When Razorpay isn't configured (503), the button falls back toinstanode.dev/pricing.