gameplane / docs
DEVELOP

Web Dashboard Development

Extend the strict TypeScript dashboard without breaking query, routing, API, cluster, or design contracts.

Local Developmentv0.217 MIN
Cluster scope in caches and requests

Every cache and request that varies by cluster must include or clear cluster scope to prevent cross-cluster stale data.

Application architecture

React and Vite use explicit routing, query caches, reusable components, Monaco, and terminal primitives.

RoutesLive in `web/src/routes` and are registered in the explicit router tree (`web/src/router/tree.tsx`).
Shared request and domain typesLive under `web/src/types.ts` (CRD mirrors and UI types) and `web/src/api/types.ts` (API-specific types); domain logic lives in `web/src/lib`.
TanStack QueryOwns server state; Monaco and xterm handle dense tools (file editors, server console, log viewers).

API and state contracts

The shared request layer owns credentials, CSRF, errors, cluster selection, and streaming reconnect behavior.

api<T> injects credentials and CSRFAll callers use a single function signature for credentials, CSRF on mutations, and uniform `APIError` — no fetch-directly antipattern.
Multipart and raw file requestsAdd `csrfHeaders()` explicitly — uploads and plain-text writes bypass the JSON wrapper but must still pass the CSRF token.
SSE/WebSocket clients reconnect with visible statusStatus callbacks surface "reconnecting…" to the UI; a socket is bound to the open server's cluster and namespace, reconnects keep that target, and leaving the server view closes its streams. Inventory selection and list filters never retarget an open server operation, and unsupported remote operations fail instead of reaching a same-named local server (v0.3.0).

Develop and verify

Use strict build, lint, Vitest/MSW, and the appropriate Playwright mode; UI changes cite Pencil node IDs.

WEB CHECK

01   01 cd web && npm ci && npm run dev
02   02 npm test && npm run lint && npm run build
03   03 npm run test:e2e:mock # live: make test-web-e2e-live

Build and type checking

  • npm run build — TypeScript strict compile (tsc -b) followed by Vite bundling. Fails on type errors; never bypass with @ts-ignore or any without explicit justification.
  • npm run lint — ESLint checks; must pass before commit.
  • npm test — Vitest unit suite with MSW mocking of the API layer; runs in parallel by default.

E2E testing

  • npm run test:e2e:mock — Playwright against a local dev server and mocked API responses (fast, ~2 min).
  • npm run test:e2e:live — Playwright against the live e2e Kind cluster (slower, ~10 min; requires make e2e-up and the Go e2e suite, which writes the admin password to test/e2e/.tmp/; or run make test-web-e2e-live).
  • npm run screenshots — Capture UI screenshots for design comparison (mock mode).

Dev server

Run make web-dev from the repo root to start the Vite dev server with a proxy to the in-cluster API (requires make dev-up first). The dev server hot-reloads on save; CSS changes apply instantly, component changes reload with state preserved.

Design and PRs

UI changes must be designed first in design.pen (Pencil MCP, never edit directly) before writing React code. When submitting a PR with visual changes:

  • Export the touched design nodes to design-export/json/<id>.json and design-export/screenshots/<id>.png (automated during design export).
  • Cite the Pencil node ID in your PR description (e.g., “Implements design node ZwM1N (Web Dashboard Development…)”).
  • Reference the screenshot in the PR for visual comparison.

This ensures the design source remains canonical and reviewers can compare intent to implementation without re-opening the design tool.