This project is a template with some basic functionality for the ASW labs.
- Julián Fernández Herruzo UO300199@uniovi.es
- Fernando Begega Suarez UO295286@uniovi.es
- Rodrigo García López UO300548@uniovi.es
- Adrian Burguet Diego UO294819@uniovi.es
The project is divided into these main components, each in its own directory:
webapp/: Frontend application built with React, Vite, and TypeScript.gateway/: Node.js reverse proxy that routes incoming traffic to internal services.auth_service/: Authentication microservice (register/login/verify) with JWT + MongoDB.gamey/: Rust game engine and bot service.stats/: Node.js service for match history and player statistics.load-tests/: Gatling/Maven load tests and saved execution evidence.docs/: Architecture documentation sources following Arc42 template.
Each component includes the scripts/configuration needed to run and test the application.
- User Registration: The web application provides a simple form to register new users.
- GameY: A basic Game engine which only chooses a random piece.
The webapp is a single-page application (SPA) created with Vite and React.
src/App.tsx: The main component of the application.src/RegisterForm.tsx: The component that renders the user registration form.package.json: Contains scripts to run, build, and test the webapp.vite.config.ts: Configuration file for Vite.Dockerfile: Defines the Docker image for the webapp.
The gateway service is a Node.js reverse proxy built with Express and http-proxy-middleware.
gateway-service.js: Central route map for forwarding traffic towebapp,auth,gamey, andstats.package.json: Contains scripts to start the gateway.Dockerfile: Defines the Docker image for the gateway service.
The gamey component is a Rust-based game engine with bot support, built with Rust and Cargo.
src/main.rs: Entry point for the application.src/lib.rs: Library exports for the gamey engine.src/bot/: Bot implementation and registry.src/core/: Core game logic including actions, coordinates, game state, and player management.src/notation/: Game notation support (YEN, YGN).src/web/: Web interface components.Cargo.toml: Project manifest with dependencies and metadata.Dockerfile: Defines the Docker image for the gamey service.
A dedicated microservice lives under auth_service/. It provides user registration and login using
JSON Web Tokens (JWT) and persists accounts in MongoDB. This allows sessions to be
authenticated across the platform.
auth-service.js: main application file, implements/register,/login, and a protected/verifyendpoint.models/user.js: Mongoose schema for users (username + passwordHash).package.json/package-lock.json: npm configuration.Dockerfile: builds the Node.js image for the service.__tests__/auth-service.test.js: unit tests using Supertest.
The API is documented on /external/docs#/
| Path | Method | Description | Auth required |
|---|---|---|---|
/register |
POST | Create account (username+password) | no |
/login |
POST | Obtain JWT token | no |
/verify |
GET | Verify JWT token validity | yes (Bearer) |
Example request body for /register:
{ "username": "alice", "password": "P@ssw0rd" }Successful login returns:
{ "id": "<userId>", "username": "alice", "token": "<jwt>", "message": "Welcome back alice!" }You can run this project using Docker (recommended) or locally without Docker.
This is the easiest way to get the project running. You need to have Docker and Docker Compose installed.
The docker-compose.yml in this repository is configured to build first-party services (webapp, gateway, auth, gamey, stats) directly from local source code in this repo.
- Build and run the containers: From the root directory of the project, run:
docker-compose up --buildThis command will build the Docker images and start the full stack behind the gateway.
2.Access the application:
- Web application (default local setup, HTTP): http://localhost:8080
- Auth API (through gateway, default local setup): http://localhost:8080/auth/register, http://localhost:8080/auth/login, http://localhost:8080/auth/verify
- Gamey API (through gateway, default local setup): http://localhost:8080/api/v1/games
- External bot API documentation (through gateway, default local setup): http://localhost:8080/external/docs
- External bot OpenAPI contract (through gateway, default local setup): http://localhost:8080/external/docs/openapi.json
- Prometheus: http://localhost:9090
- Grafana: http://localhost:9091
The external bot endpoint accepts a GET request with these query parameters:
position(required): JSON-encoded YEN record for the current board position.bot_id(optional): explicit bot identifier. If omitted,random_botis used.
Response format:
{ "coords": { "x": 1, "y": 1, "z": 0 } }Example request:
curl -G "http://localhost:8080/external/v1/play" \
--data-urlencode 'position={"size":3,"turn":0,"players":["B","R"],"layout":"./../..."}' \
--data-urlencode 'bot_id=random_bot'The public entry point is the gateway. HTTPS is configured there, while internal traffic to webapp, auth, gamey, and stats remains inside Docker.
For local development, the Docker Compose stack now starts the gateway in plain HTTP on http://localhost:8080 unless you explicitly provide both TLS paths. This keeps Prometheus scraping and manual testing working out of the box.
Certificate placement:
- The public certificate is in
gateway/certs/server.crt - The private key is in
gateway/certs/server.key
These files are mounted into the container at /app/certs and loaded by the gateway with the default Docker Compose configuration.
HTTPS_CERT_PATH=/app/certs/server.crtHTTPS_KEY_PATH=/app/certs/server.key
For local development, self-signed certificates can be used.
If both values are left empty, the gateway falls back to HTTP and Prometheus scrapes http://gateway:8080/metrics.
Default Docker ports:
- Host
443-> gateway HTTPS listener - Host
8080-> gateway HTTP listener
Important deployment note:
- If you do not want HTTP at all, set
HTTP_REDIRECT_ENABLED=falseand do not use host port80. - If you want automatic redirect from HTTP to HTTPS, set
HTTP_REDIRECT_ENABLED=trueand map host80to the gateway HTTP listener instead of exposing that port from any other service. - Only the
gatewayshould publish public web ports.webappmust stay internal to avoid port conflicts.
Recommended VM setup without risking another port-80 collision:
$env:HTTP_REDIRECT_ENABLED="false"
$env:GATEWAY_HTTPS_HOST_PORT="443"
$env:GATEWAY_HTTP_HOST_PORT="8080"
docker-compose up --build -dIf you want http://... to redirect to https://..., use:
$env:HTTP_REDIRECT_ENABLED="true"
$env:GATEWAY_HTTPS_HOST_PORT="443"
$env:GATEWAY_HTTP_HOST_PORT="80"
docker-compose up --build -dWith that configuration there is no duplicate use of port 80, because the only container binding that host port is the gateway.
The Docker Compose environment also provisions a monitoring stack:
Prometheusscrapes/metricsfromgateway,auth,stats, andgameyGrafanais automatically provisioned with the Prometheus datasource- A starter dashboard named
Yovi Observabilityis loaded on startup
Useful URLs:
- Prometheus UI:
http://localhost:9090 - Grafana UI:
http://localhost:9091
The metrics exposed by the services include:
- HTTP traffic counters and request-duration aggregates
- Process uptime and memory gauges for Node.js services
- Gamey domain gauges and counters for active games, matchmaking, and stats reporting
For a simpler explanation of each metric and each Grafana panel, see monitoring/README.md.
The repository includes a Gatling load-test project in load-tests/.
It contains the YoviSimulation scenario and the saved execution output in load-tests/results/resultados.txt.
Run it against the local gateway:
cd load-tests
mvn gatling:test -Dyovi.baseUrl=http://localhost:8080Run it in Docker Compose against the internal gateway service:
docker compose -f docker-compose.yml -f docker-compose.load-tests.yml run --rm gatlingThe simulation accepts -Dyovi.baseUrl, -Dyovi.usersPerSec and -Dyovi.durationSeconds.
Generated Gatling reports are written under load-tests/target/gatling/.
The Docker deployment does not expose MongoDB ports on the host by default. Services use the internal Docker network names (mongo-auth:27017 and mongo-stats:27017), which avoids collisions with a local MongoDB instance.
Expose them only for debugging:
docker compose -f docker-compose.yml -f docker-compose.db-ports.yml up -d --buildIf 27017 is already busy, choose another host port:
$env:MONGO_AUTH_HOST_PORT="27018"; docker compose -f docker-compose.yml -f docker-compose.db-ports.yml up -d --buildTo run the project locally without Docker, you will need to run each component in a separate terminal.
- Node.js and npm installed.
- Rust and Cargo installed (for
gamey). - MongoDB available locally if running
auth_serviceorstatsoutside Docker.
Navigate to the auth_service directory:
cd auth_serviceInstall dependencies:
npm installRun the service:
$env:JWT_SECRET="change_this_secret"; $env:MONGO_AUTH_DB="mongodb://localhost:27017/auth"; npm startThe auth service will be available at http://localhost:3500.
Navigate to the stats directory:
cd statsInstall dependencies:
npm installRun the service:
$env:MONGO_URL="mongodb://localhost:27017"; $env:MONGO_DB_NAME="yovi_stats"; $env:STATS_INTERNAL_TOKEN="stats-internal-token"; npm startThe stats service will be available at http://localhost:3001.
Navigate to the gamey directory:
cd gameyRun the service on port 4000:
$env:STATS_SERVICE_URL="http://localhost:3001"; $env:STATS_INTERNAL_TOKEN="stats-internal-token"; cargo run -- --mode server --port 4000Navigate to the webapp directory:
cd webappInstall dependencies:
npm installRun the application:
npm run devThe web application will be available at http://localhost:5173.
Navigate to the gateway directory:
cd gatewayInstall dependencies:
npm installRun the gateway:
$env:WEBAPP_SERVICE_URL="http://localhost:5173"; $env:AUTH_SERVICE_URL="http://localhost:3500"; $env:GAMEY_SERVICE_URL="http://localhost:4000"; $env:STATS_SERVICE_URL="http://localhost:3001"; $env:HTTPS_CERT_PATH="C:\path\to\server.crt"; $env:HTTPS_KEY_PATH="C:\path\to\server.key"; $env:HTTPS_PORT="8443"; $env:PORT="8080"; $env:HTTP_REDIRECT_ENABLED="true"; npm startThe gateway will be available at https://localhost:8443. If HTTP_REDIRECT_ENABLED=true, http://localhost:8080 will redirect to HTTPS.
Each component has its own set of scripts defined in its package.json. Here are some of the most important ones:
Run these commands from webapp/ (or from repo root using npm --prefix webapp ...).
npm run dev: Starts the development server for the webapp.npm test: Runs the unit tests in watch mode.npm run test -- --run: Runs the unit tests once.npm run test -- --run src/__tests__/AppGameExitBehavior.test.tsx: Runs a specific test file.npm run test:e2e: Runs the end-to-end tests.npm run start:all: A convenience script to startwebapp,gateway, andauth_serviceconcurrently.
npm start: Starts the auth service.npm test: Runs the tests for the service.
npm start: Starts the stats service.npm test: Runs the tests for the service.
npm start: Starts the reverse proxy gateway.
cargo build: Builds the gamey application.cargo test: Runs the unit tests.cargo run: Runs the gamey application.cargo doc: Generates documentation for the GameY engine application