Files
liqa/docs/development.md
ars9 1627733701 docs: refresh architecture and runtime documentation
- align architecture, development, MCP, and scenario docs with current code

- remove obsolete key descriptor document and stale keys/auth references
2026-04-10 20:40:20 +03:00

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`.