docs: update architecture and development docs to cover client workspace

- add client workspace section to architecture diagram and description
- split development.md commands into server and client per-workspace
- document client tech stack, directory layout, routing, and theming
- add Client overview section with Storybook test instructions
This commit is contained in:
2026-04-09 10:32:49 +03:00
parent 32beec2229
commit f83141b484
2 changed files with 144 additions and 23 deletions
+17 -1
View File
@@ -1,11 +1,19 @@
# Architecture
```
┌─────────────────────────────────────────┐
│ Browser (React SPA — client/) │
│ │
│ EnvironmentsPage KeysPage │
│ SessionsPage ScenariosPage │
└───────────────────┬─────────────────────┘
│ HTTP REST (:13000)
MCP client (AI agent / VS Code Copilot)
│ HTTP /mcp (Streamable MCP)
┌──────────────────────────────────────┐
│ NestJS app (src/)
│ NestJS app (server/src/)
│ │
│ McpService ← all MCP tools │
│ │
@@ -32,3 +40,11 @@ MCP client (AI agent / VS Code Copilot)
- **CodeExecutorService** — compiles and runs user-supplied Playwright JS inside a sandboxed `async` function with `page`, `context`, and `helpers` in scope.
- **ScenarioService** — CRUD for scenarios, steps, runs, and run logs; import/export.
- **ScenarioSchedulerService** — polls for pending step runs every second and executes them. All steps in the same run share **one browser instance** (see [scenario.md](scenario.md)).
## Client (`client/`)
A React 19 + TypeScript SPA served separately by Vite during development. In Docker Compose the same build artefacts are served statically alongside the API.
The client calls the server REST endpoints directly — there is no separate BFF layer. Routing uses HashRouter so the Vite proxy and server-side routes are never ambiguous.
See [development.md](development.md) for the full client tech stack and directory layout.
+127 -22
View File
@@ -5,16 +5,23 @@
- Node.js 20+
- Docker + Docker Compose
Install dependencies:
The repository is a **npm workspace monorepo** with two packages:
| Workspace | Directory | Description |
|---|---|---|
| `server` | `server/` | NestJS API + MCP server |
| `client` | `client/` | React 19 + Vite admin UI |
Install all dependencies from the repo root:
```bash
npm install
npx playwright install chromium # first time only
npx playwright install chromium # first time only (server)
```
Copy `.env.example` to `.env` and fill in the required values before running.
### Environment variables
### Environment variables (server)
| Variable | Default | Description |
|---|---|---|
@@ -27,74 +34,122 @@ Copy `.env.example` to `.env` and fill in the required values before running.
## Starting the application
### Server
**Development** (watch mode, restarts on file changes):
```bash
npm run start:dev
npm -w server run start:dev
```
**Production build, then start**:
```bash
npm run build
npm run start:prod
npm -w server run build
npm -w server run start:prod
```
The application listens on port **3000** by default.
The server listens on port **3000** by default.
### Client
**Development** (Vite dev server with HMR):
```bash
npm -w client run dev
```
The Vite dev server runs on **http://localhost:5173** and proxies all API paths (`/environments`, `/sessions`, `/scenarios`, `/keys`, `/login`, `/mcp`) to the server at `localhost:3000`.
**Production build**:
```bash
npm -w client run build
```
The built files are emitted to `client/dist/`.
---
## Running tests
### Server (Jest)
```bash
npm run test
npm -w server run test
```
Run a single spec file:
```bash
npm run test -- --no-coverage test/scenario.controller.spec.ts
npm -w server run test -- --no-coverage test/scenario.controller.spec.ts
```
Watch mode:
```bash
npm run test:watch
npm -w server run test:watch
```
Enable verbose NestJS log output during tests:
```bash
npm run test:debug
npm -w server run test:debug
```
### Client (Vitest + Storybook)
Storybook interaction tests (runs all `*.stories.tsx` files):
```bash
npm -w client run test:storybook
```
Launch Storybook dev server (with live preview):
```bash
npm -w client run storybook
```
---
## Formatting code
[Prettier](https://prettier.io/) is used to format all TypeScript source and test files:
Both workspaces use [Prettier](https://prettier.io/).
**Server** — rewrites `src/**/*.ts` and `test/**/*.ts`:
```bash
npm run format
npm -w server run format
```
This rewrites `src/**/*.ts` and `test/**/*.ts` in place.
**Client** rewrites `src/**/*.{ts,tsx}` and `.storybook/**/*.{ts,tsx}`:
```bash
npm -w client run format
```
---
## Linting
[ESLint](https://eslint.org/) with `typescript-eslint` and `eslint-config-prettier` is used:
Both workspaces use [ESLint](https://eslint.org/) with `typescript-eslint`. The client also includes `eslint-plugin-react-hooks` and `eslint-plugin-react-refresh`.
**Server:**
```bash
# report issues
npm run lint
# report and auto-fix where possible
npm run lint:fix
npm -w server run lint # report issues
npm -w server run lint:fix # report and auto-fix
```
The project targets zero errors. Run lint before committing.
**Client:**
```bash
npm -w client run lint # report issues
npm -w client run lint:fix # report and auto-fix
```
Both workspaces target zero errors. Run lint before committing.
---
@@ -126,7 +181,7 @@ Build and start in one step:
docker compose up -d --build
```
The application is exposed at **http://localhost:13000**.
The server API is exposed at **http://localhost:13000**.
SQLite data is persisted in `./data/` and key files are mounted from `./keys/` — both directories are volume-mounted into the container.
@@ -141,3 +196,53 @@ View logs:
```bash
docker compose logs -f
```
---
## Client overview
The client (`client/`) is a React 19 + TypeScript SPA built with Vite. It provides a browser UI for managing environments, sessions, keys, and scenarios.
### Tech stack
| Library | Purpose |
|---|---|
| React 19 + TypeScript | UI framework |
| Vite 6 | Dev server and bundler |
| react-router-dom (HashRouter) | Client-side routing |
| i18next + react-i18next | Internationalisation |
| lucide-react | Icon library |
| moment | Relative timestamp formatting |
| ESLint 10 + Prettier | Linting and formatting |
| Storybook 10 + Vitest | Component development and testing |
### Directory layout
```
client/
src/
api/ API client modules (environments, keys, sessions, scenarios)
hooks/ useTheme (light/dark persistence)
i18n/ i18next bootstrap + locales/en.json
pages/ EnvironmentsPage, KeysPage, SessionsPage, ScenariosPage
ui/ Reusable component library
Badge, Breadcrumbs, Button, Card, Input, Select,
SidePanel, Table, ThemeSwitcher, Timestamp
.storybook/
stories/ *.stories.tsx for all ui/ components
```
### Routing
Hash-based routing (`/#/path`) avoids conflicts with the Vite dev-server proxy. Default route redirects to `/#/scenarios`.
| Route | Page |
|---|---|
| `/#/environments` | Environment list |
| `/#/keys` | Key list |
| `/#/sessions` | Session list |
| `/#/scenarios` | Scenario list |
### Theming
Light/dark theme is toggled by the `ThemeSwitcher` button in the sidebar header. The selection is persisted to `localStorage` and applied as `data-theme` on `<html>` before React mounts (anti-FOUC inline script in `index.html`).