- align architecture, development, MCP, and scenario docs with current code - remove obsolete key descriptor document and stale keys/auth references
261 lines
5.6 KiB
Markdown
261 lines
5.6 KiB
Markdown
# Development
|
|
|
|
## Prerequisites
|
|
|
|
- Node.js 20+
|
|
- Docker + Docker Compose
|
|
|
|
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 (server)
|
|
```
|
|
|
|
Copy `.env.example` to `.env` and fill in the required values before running.
|
|
|
|
### Environment variables (server)
|
|
|
|
| Variable | Default | Description |
|
|
|---|---|---|
|
|
| `PORT` | `3000` | HTTP port |
|
|
| `KEYS_DIR` | `keys` | Directory for key material used by credential/snippet workflows |
|
|
| `DB_PATH` | `data/sessions.db` | SQLite database file |
|
|
| `SESSION_IDLE_TIMEOUT_MINUTES` | `30` | Idle timeout before open sessions are closed |
|
|
| `SESSION_DELETE_CLOSED_DAYS` | `7` | Retention period for closed sessions |
|
|
| `PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH` | _(Playwright default)_ | Path to Chromium binary. Set automatically in Docker (`/usr/bin/chromium`). |
|
|
|
|
---
|
|
|
|
## Starting the application
|
|
|
|
### Server
|
|
|
|
**Development** (watch mode, restarts on file changes):
|
|
|
|
```bash
|
|
npm -w server run start:dev
|
|
```
|
|
|
|
**Production build, then start**:
|
|
|
|
```bash
|
|
npm -w server run build
|
|
npm -w server run start:prod
|
|
```
|
|
|
|
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 these API prefixes to `localhost:13000` (or `localhost:3000` when running server locally):
|
|
|
|
- `/environments`
|
|
- `/credentials`
|
|
- `/snippets`
|
|
- `/sessions`
|
|
- `/scenarios`
|
|
|
|
**Production build**:
|
|
|
|
```bash
|
|
npm -w client run build
|
|
```
|
|
|
|
The built files are emitted to `client/dist/`.
|
|
|
|
---
|
|
|
|
## Running tests
|
|
|
|
### Server (Jest)
|
|
|
|
```bash
|
|
npm -w server run test
|
|
```
|
|
|
|
Run a single spec file:
|
|
|
|
```bash
|
|
npm -w server run test -- --no-coverage test/scenario.controller.spec.ts
|
|
```
|
|
|
|
Watch mode:
|
|
|
|
```bash
|
|
npm -w server run test:watch
|
|
```
|
|
|
|
Enable verbose NestJS log output during tests:
|
|
|
|
```bash
|
|
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
|
|
|
|
Both workspaces use [Prettier](https://prettier.io/).
|
|
|
|
**Server** — rewrites `src/**/*.ts` and `test/**/*.ts`:
|
|
|
|
```bash
|
|
npm -w server run format
|
|
```
|
|
|
|
**Client** — rewrites `src/**/*.{ts,tsx}` and `.storybook/**/*.{ts,tsx}`:
|
|
|
|
```bash
|
|
npm -w client run format
|
|
```
|
|
|
|
---
|
|
|
|
## Linting
|
|
|
|
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
|
|
npm -w server run lint # report issues
|
|
npm -w server run lint:fix # report and auto-fix
|
|
```
|
|
|
|
**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.
|
|
|
|
---
|
|
|
|
## Building the container
|
|
|
|
```bash
|
|
docker compose build
|
|
```
|
|
|
|
To rebuild without the layer cache:
|
|
|
|
```bash
|
|
docker compose build --no-cache
|
|
```
|
|
|
|
---
|
|
|
|
## Running with Docker Compose
|
|
|
|
Start (detached):
|
|
|
|
```bash
|
|
docker compose up -d
|
|
```
|
|
|
|
Build and start in one step:
|
|
|
|
```bash
|
|
docker compose up -d --build
|
|
```
|
|
|
|
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.
|
|
|
|
Stop and remove containers:
|
|
|
|
```bash
|
|
docker compose down
|
|
```
|
|
|
|
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, credentials, snippets, sessions, scenarios, and runs.
|
|
|
|
### 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, credentials, snippets, sessions, scenarios)
|
|
hooks/ useTheme (light/dark persistence)
|
|
i18n/ i18next bootstrap + locales/en.json
|
|
pages/ Environment/Credential/Snippet/Session/Scenario/Run pages
|
|
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 |
|
|
| `/#/credentials` | Credential list |
|
|
| `/#/snippets` | Snippet list |
|
|
| `/#/sessions` | Session list |
|
|
| `/#/scenarios` | Scenario list |
|
|
| `/#/runs` | Cross-scenario runs list |
|
|
|
|
### Theming
|
|
|
|
Light/dark theme is toggled by the `ThemeSwitcher` button in the sidebar footer. The selection is persisted to `localStorage` and applied as `data-theme` on `<html>` before React mounts (anti-FOUC inline script in `index.html`).
|
|
|
|
The sidebar footer also shows the app version read from the workspace root `package.json` and injected via Vite `define`.
|