- Step-by-step backend setup: venv, secret key generation (openssl + Fernet), .env configuration with annotated minimum values - VS Code launch.json snippets for backend (debugpy/uvicorn) and frontend (Chrome with source maps) - Vite proxy detail (/api → :8000, /ws → ws://:8000) - Backend pytest commands alongside existing frontend test section - Playwright headed/UI mode instructions for E2E debugging - Updated unit test count to 173; removed stale E2E count - CLAUDE.md quick start trimmed to point at README for full setup
8.4 KiB
Languard Server Manager
A multi-game server management platform with a Python/FastAPI backend and React/TypeScript frontend. Currently supports Arma 3 with an extensible adapter system for adding more games.
Tech Stack
Backend
- Python 3.12+ / FastAPI — async REST API
- SQLite with WAL mode — zero-config database
- SQLAlchemy — raw SQL via
text()queries (no ORM) - BattlEye RCon — UDP protocol v2 for remote admin
- APScheduler — background cleanup jobs
- psutil — process monitoring and resource metrics
- JWT (python-jose) + bcrypt — authentication
- Fernet (cryptography) — sensitive config field encryption
Frontend
- React 19 / TypeScript 6 / Vite 8
- TanStack Query v5 — server state management
- Zustand 5 — client state (auth, UI)
- Tailwind CSS — dark neumorphic design system
- Playwright — E2E testing
- Vitest + React Testing Library — unit tests (173 tests)
Quick Start
1 — Backend setup
cd backend
# Create and activate a virtual environment
python -m venv venv
source venv/bin/activate # macOS / Linux
# venv\Scripts\activate # Windows (cmd)
# venv\Scripts\Activate.ps1 # Windows (PowerShell)
pip install -r requirements.txt
Generate required secrets (one-time):
# Secret key (JWT signing)
openssl rand -hex 32
# Fernet encryption key (sensitive config fields at rest)
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
Copy .env.example to .env and fill in the two keys:
cp .env.example .env # then open .env in your editor
# .env — minimum required values
LANGUARD_SECRET_KEY=<output of openssl command>
LANGUARD_ENCRYPTION_KEY=<output of Fernet command>
LANGUARD_ARMA3_DEFAULT_EXE=C:/path/to/arma3server_x64.exe
Start the backend (development — auto-reload on file changes):
uvicorn main:app --host 0.0.0.0 --port 8000 --reload
First run prints a randomly-generated admin password to the console. Log in and change it immediately via Settings → Change Password (or PUT /api/auth/password).
- API root:
http://localhost:8000 - Interactive docs:
http://localhost:8000/docs
Debug in VS Code: add this launch.json configuration:
{
"name": "Backend — uvicorn",
"type": "debugpy",
"request": "launch",
"module": "uvicorn",
"args": ["main:app", "--host", "0.0.0.0", "--port", "8000"],
"cwd": "${workspaceFolder}/backend",
"env": { "PYTHONDONTWRITEBYTECODE": "1" },
"jinja": true,
"justMyCode": false
}
2 — Frontend setup
cd frontend
npm install
npm run dev
The Vite dev server starts at http://localhost:5173 and automatically proxies:
/api/*→http://localhost:8000(REST)/ws/*→ws://localhost:8000(WebSocket)
Debug in VS Code: install the JavaScript Debugger extension (bundled by default), then add:
{
"name": "Frontend — Vite (Chrome)",
"type": "chrome",
"request": "launch",
"url": "http://localhost:5173",
"webRoot": "${workspaceFolder}/frontend/src",
"sourceMapPathOverrides": {
"/@fs/*": "${workspaceFolder}/frontend/*"
}
}
Start the Vite dev server first (npm run dev), then launch this config to attach Chrome DevTools with source-map support.
Running Tests
Backend
cd backend
source venv/bin/activate # (if not already active)
pytest # all tests
pytest tests/adapters/arma3/ -v # adapter tests only
pytest --tb=short -q # quiet output
Frontend unit tests
cd frontend
npm test # single run (CI-friendly)
npm run test:watch # watch mode during development
npx vitest run --coverage # with coverage report
Frontend E2E tests (Playwright)
Start the backend and the Vite dev server first, then:
cd frontend
npm run test:e2e # all E2E tests (headless)
npm run test:e2e:ui # Playwright UI mode (interactive, great for debugging)
npx playwright test --headed # watch tests run in an actual browser
Integration tests (require a live backend) live in tests-e2e/integration/. All other tests use API mocks and run without a backend.
Project Structure
languard-servers-manager/
├── backend/
│ ├── main.py # FastAPI app factory, lifespan, middleware
│ ├── config.py # Pydantic Settings (env vars)
│ ├── database.py # SQLAlchemy engine, migration runner
│ ├── dependencies.py # FastAPI deps: auth, admin, server, adapter
│ ├── adapters/ # Game adapter system
│ │ ├── protocols.py # Protocol definitions (7 capabilities)
│ │ ├── registry.py # GameAdapterRegistry singleton
│ │ ├── exceptions.py # Typed adapter exceptions
│ │ └── arma3/ # Arma 3 adapter (7/7 capabilities)
│ ├── core/
│ │ ├── auth/ # JWT auth, user CRUD
│ │ ├── servers/ # Server service, routers, process manager
│ │ ├── games/ # Game type discovery
│ │ ├── system/ # Health and status endpoints
│ │ ├── websocket/ # WS manager, broadcast thread
│ │ ├── threads/ # Background thread registry
│ │ ├── dal/ # Data access layer (repositories)
│ │ ├── jobs/ # APScheduler cleanup jobs
│ │ ├── utils/ # Crypto, file utils, port checker
│ │ └── migrations/ # SQL migration scripts
│ └── requirements.txt
├── frontend/
│ ├── src/
│ │ ├── App.tsx # Router + auth guard
│ │ ├── pages/ # LoginPage, DashboardPage, ServerDetailPage, CreateServerPage, SettingsPage
│ │ ├── components/ # Sidebar, ServerCard, ConfigEditor, PlayerTable, BanTable, MissionList, ModList, LogViewer, StatusLed
│ │ ├── hooks/ # useServers, useServerDetail, useAuth, useGames, useWebSocket
│ │ ├── store/ # auth.store, ui.store (Zustand)
│ │ ├── lib/ # api.ts (Axios client)
│ │ └── __tests__/ # Vitest unit tests (173 tests)
│ ├── tests-e2e/ # Playwright E2E tests
│ └── playwright.config.ts
├── API.md # REST + WebSocket API reference
├── ARCHITECTURE.md # System architecture overview
├── DATABASE.md # Database schema reference
├── FRONTEND.md # Frontend architecture and components
├── MODULES.md # Module-by-module reference
└── THREADING.md # Background threading model
Environment Variables
| Variable | Default | Description |
|---|---|---|
LANGUARD_SECRET_KEY |
(required) | JWT signing key |
LANGUARD_ENCRYPTION_KEY |
(required) | Fernet key for sensitive config fields |
LANGUARD_DB_PATH |
./languard.db |
SQLite database path |
LANGUARD_SERVERS_DIR |
./servers |
Base directory for server data |
LANGUARD_HOST |
0.0.0.0 |
Listen host |
LANGUARD_PORT |
8000 |
Listen port |
LANGUARD_CORS_ORIGINS |
["http://localhost:5173"] |
CORS allowed origins |
LANGUARD_LOG_RETENTION_DAYS |
7 |
Log cleanup retention |
LANGUARD_METRICS_RETENTION_DAYS |
30 |
Metrics cleanup retention |
LANGUARD_PLAYER_HISTORY_RETENTION_DAYS |
90 |
Player history retention |
LANGUARD_JWT_EXPIRE_HOURS |
24 |
JWT token expiry |
LANGUARD_ARMA3_DEFAULT_EXE |
(required for Arma 3) | Default Arma 3 executable path |
Documentation
- ARCHITECTURE.md — System design, component diagram, security model
- API.md — Complete REST + WebSocket API reference
- DATABASE.md — Schema, tables, indexes, migration system
- FRONTEND.md — React component tree, state management, design system
- MODULES.md — File-by-file module reference
- THREADING.md — Background thread model and concurrency