About arc42

arc42, the template for documentation of software and system architecture.

Template Version 8.2 EN. (based upon AsciiDoc version), January 2023

Created, maintained and © by Dr. Peter Hruschka, Dr. Gernot Starke and contributors. See https://arc42.org.


Note

This version of the template contains some help and explanations. It is used for familiarization with arc42 and the understanding of the concepts. For documentation of your own system you use better the plain version.

1. Introduction and Goals

Software development company Micrati has decided to shift its focus to the development of a video game based on the classical board game Y. The new game will be named YOVI.

YOVI is a two-player strategy game in which each player is assigned a color. The board consists of hexagonal tiles arranged in a triangular shape. Players take turns placing a piece of their assigned color on an empty tile. The objective of the game is to connect the three sides of the triangular board with a continuous path of pieces of the same color.

The main goal of the project is to deliver a deployed, accessible, and scalable web-based system that allows users to play Y against the computer with multiple strategies and configurable difficulty levels, while also exposing a documented API for bot interaction.

Describes the relevant requirements and the driving forces that software architects and development team must consider. These include

  • underlying business goals,

  • essential features,

  • essential functional requirements,

  • quality goals for the architecture and

  • relevant stakeholders and their expectations

1.1. Requirements Overview

The system will be composed of two main subsystems:

  • A Web Application implemented in TypeScript that allows users to:

    • Play games through a graphical interface.

    • Register and manage their accounts.

    • Access statistics and match history.

    • Interact through a public API that enables bot integration.

  • A Game Engine module implemented in Rust responsible for:

    • Determining whether a match has been won.

    • Suggesting the next move based on different strategies.

    • Providing a basic web service interface to be invoked by the Web Application.

Communication between both subsystems will be performed through JSON messages using the YEN (Y Notation) format to represent game states.

1.1.1. Functional Requirements

The system must fulfill the following functional requirements:

  • The system shall provide a web-based frontend that allows users to play the classical version of the Y game.

  • The system shall allow a human player to play against the computer.

  • The board size shall be configurable.

  • The system shall implement more than one computer strategy. Each strategy may include different difficulty levels, which can be selected by the user.

  • The system shall allow users to register and authenticate.

  • The system shall store and display user statistics, including:

    • Number of games played.

    • Number of games won and lost.

    • Additional performance metrics if necessary.

  • The system shall provide a public REST API that allows:

    • Access to user information.

    • Access to match information.

    • Management of matches.

    • Interaction from external bots.

  • The API shall include a method play that:

    • Receives at least a parameter position in YEN notation.

    • Returns the next move in YEN notation.

    • Optionally allows the selection of strategy and difficulty.

  • The system shall be deployed and accessible via the Web.

Contents

Short description of the functional requirements, driving forces, extract (or abstract) of requirements. Link to (hopefully existing) requirements documents (with version number and information where to find it).

Motivation

From the point of view of the end users a system is created or modified to improve support of a business activity and/or improve the quality.

Form

Short textual description, probably in tabular use-case format. If requirements documents exist this overview should refer to these documents.

Keep these excerpts as short as possible. Balance readability of this document with potential redundancy w.r.t to requirements documents.

Further Information

See Introduction and Goals in the arc42 documentation.

1.2. Quality Goals

Priority Quality Goal Concrete Description

1

Performance

The system shall return a move suggestion from the Rust engine in less than 1 second for standard board sizes under normal load conditions (up to 50 concurrent users).

2

Scalability

The system shall support at least 50 concurrent authenticated users playing matches simultaneously without service degradation (response times above 2 seconds or request failures).

3

Availability

The deployed system shall achieve at least 99% uptime measured on a monthly basis, excluding scheduled maintenance.

4

Modifiability

It shall be possible to add a new computer strategy without modifying the Web frontend and without changing existing strategy implementations (Open/Closed Principle). Integration of a new strategy should require changes only within the Rust engine module.

5

Usability

A new user shall be able to register and start a game in less than 5 minutes without external documentation. The interface shall clearly indicate: current turn, selected strategy, board size, and game result.

6

Interoperability

The public REST API shall follow standard HTTP conventions and JSON format, and it shall be fully documented (e.g., OpenAPI). External bots shall be able to interact with the play endpoint without accessing internal implementation details.

Contents

The top three (max five) quality goals for the architecture whose fulfillment is of highest importance to the major stakeholders. We really mean quality goals for the architecture. Don’t confuse them with project goals. They are not necessarily identical.

Consider this overview of potential topics (based upon the ISO 25010 standard):

Categories of Quality Requirements
Motivation

You should know the quality goals of your most important stakeholders, since they will influence fundamental architectural decisions. Make sure to be very concrete about these qualities, avoid buzzwords. If you as an architect do not know how the quality of your work will be judged…​

Form

A table with quality goals and concrete scenarios, ordered by priorities

1.3. Stakeholders

Contents

Explicit overview of stakeholders of the system, i.e. all person, roles or organizations that

  • should know the architecture

  • have to be convinced of the architecture

  • have to work with the architecture or with code

  • need the documentation of the architecture for their work

  • have to come up with decisions about the system or its development

Motivation

You should know all parties involved in development of the system or affected by the system. Otherwise, you may get nasty surprises later in the development process. These stakeholders determine the extent and the level of detail of your work and its results.

Form

Table with role names, person names, and their expectations with respect to the architecture and its documentation.

Stakeholder Interest

Players

Want to play the game easily, select strategies, and track their statistics.

Developers

Need a maintainable and well-documented architecture, witch will ensure easy modifications in the future.

Project Team

Needs proper documentation, testing, and a simple architecture for the project, to simplify the development and maintenance.

Micrati

Expects a functional, high-quality, and innovative product, which boosts profits for the company.

Teachers

Need a good documentation and a functional project to grade students.

2. Architecture Constraints

2.1. Technical Constraints

Constraint Description

Frontend

The web application must be built with React, Vite, and TypeScript.

Game Engine Language

The core of the game must be implemented in Rust.

Data Exchange

Communication between the web application and the Rust module must use JSON messages following the YEN notation.

Bot Support

The system must provide an external API for bots to interact with the game.

Deployment

The application must be accessible via web browser.

Git and github

The project will have a version control through Git. The repository will be public in GitHub.

Tools for documentation

The project will use AsciiDoc for text and PlantUML for diagrams.

2.2. Organizational Constraints

Constraint Description

Team

The project is developed by a team of four students, as assigned by the course teacher.

Deadline

The project must be delivered on the established deadlines.

Issues

The GitHub Issues tab will be used for management tasks.

Meetings

During weekly labs, the team will hold progress reviews to evaluate the previous tasks completion and define the next ones.

Pull requests

We use Pull Request workflow for all changes. This ensures the code is reviewed by another team member, helping us to maintain consistency and fix issues before merging.

2.3. Conventions

Constraint Description

Documentation Standard

Documentation must follow the Arc42 template.

Language

The documentation and the final application will be developed in English.

Usability

The interface should be easy to use and accessible, making sure everyone has a smooth experience while playing.

Coding

We focus on code quality by using meaningful names, modular components, and clear documentation.

3. Context and Scope

This section describes the system as a black box, showing its interactions with external actors and systems. It also presents the technical interfaces used between the main subsystems.

3.1. Business Context

YOVI is a software platform designed to allow users to play the game Y through a web application, while also enabling automated interaction through an external API consumed by bots. The system provides gameplay functionality, user management, statistics tracking, and game validation through a dedicated game engine.

From a business perspective, the system offers:

  • A web interface for playing the classic version of the game Y.

  • User registration and management.

  • Game history and statistics visualization.

  • An external API for automated clients (bots).

  • Game validation and move suggestion functionalities.

3.1.1. External Actors

Actor / External System Interaction with YOVI

Web User

Plays matches, selects strategies, and consults statistics.

External Bot

Uses the public API to play games automatically.

Game Engine

Checks win conditions and suggests next moves.

Web Deployment Platform

Provides public access to the system.

Context diagram

3.2. Technical Context

At a technical level, YOVI is composed of several subsystems that communicate using web protocols and JSON messages, including the YEN notation for representing game states.

3.2.1. Main Technical Containers

Web Application (TypeScript)

Responsibilities:

  • User interface.

  • User interaction and gameplay visualization.

  • Access to backend services.

Backend API

Responsibilities:

  • Application orchestration.

  • User and game management.

  • Exposure of the external API for bots.

  • Communication with the game engine.

Game Engine (Rust)

Responsibilities:

  • Game state validation.

  • Win detection.

  • Move suggestion according to selected strategies.

Database (if present in the final architecture)

Responsibilities:

  • Persistent storage of users.

  • Game history.

  • Statistics.

3.2.2. Technical Interfaces

From To Channel Data Format

Browser

Frontend Web App

HTTP

HTML/CSS/JavaScript

Frontend

Backend API

REST

JSON

External Bots

Backend API

REST

JSON

Backend API

Game Engine (Rust)

HTTP REST

JSON (YEN)

Backend API

Database

Database Driver

JSON

3.2.3. Technical Context Diagram

Technical Context diagram

3.3. Scope

YOVI is responsible for:

  • Managing user accounts and authentication.

  • Handling game sessions and history.

  • Validating game states.

  • Detecting win conditions.

  • Providing move suggestions for players.

  • Exposing a public API for automated bots.

YOVI is not responsible for:

  • Payment processing or external financial transactions.

  • Cross-game matchmaking platforms.

  • Third-party authentication providers (OAuth, SSO).

  • External infrastructure management (servers, cloud services).

3.4. Mapping Input / Output

3.4.1. Inputs

  • User interactions through the web interface.

  • API requests from external bots.

  • Board states encoded using YEN notation.

3.4.2. Outputs

  • Updated game state.

  • Match results (win / ongoing).

  • User statistics.

  • Suggested moves returned by the game engine.

3.5. Use Cases

The users can use the application only once the have created an account using a username, email and password. Once in the app they can play the YGame, see their match history and edit their profile.

Use Case Diagram

4. Solution Strategy

4.1. Technologies used

4.1.1. Frontend

We use React with TypeScript for the web UI of the Game Y app. This framework for JavaScript is very popular and highly used in the software market. It was also the framework provided with the app demo by the teachers. TypeScript adds static typing on top of JavaScript, which helps catch errors at compile time and improves code maintainability. Finally, we use Vite, a modern build tool that provides fast hot module replacement (HMR) during development and optimized production builds.

4.1.2. Backend

The backend is implemented in Rust, a systems programming language focused on performance and memory safety. The language has a growing community and huge support by enterprises. Linux Kernel is being partially upgraded with modules in Rust, combining with classic C modules.

4.1.3. Supporting services

Auxiliary services are built with Node.js and Express, handling cross-cutting concerns such as user authentication and profile management that are kept separate from the core game logic in Rust. Express provides a minimal and flexible routing layer that makes these REST endpoints straightforward to maintain and extend independently of the main backend.

For data persistence, two complementary solutions are used. MongoDB stores structured application data such as user profiles and match history, offering a flexible document model that adapts well to evolving data requirements. Firebase covers real-time needs and authentication: its Authentication service manages identity providers and session tokens, while its real-time capabilities are leveraged where low-latency data synchronization between clients is needed.

To handle deployment setup and enable an easy share of the app, we use Docker. Each component of the game is stored in a docker container that interacts with the other ones.

Server wise, we use Azure to deploy the app in a virtual machine accessible by a public url

4.1.4. Version control

Git is used for source control, with GitHub as the remote repository and collaboration platform. GitHub also hosts the project’s issue tracker and pull request workflow, supporting code review and continuous integration. Summaries of the weekly meetings between development team are posted in GitHub wiki.

4.1.5. Documentation

Architecture and technical documentation is written in AsciiDoc, a lightweight markup language well suited for structured, version-controlled documentation. Diagrams are authored with PlantUML, which allows architecture and sequence diagrams to be described as plain text and rendered automatically, keeping them in sync with the rest of the documentation inside the repository. Arc 42 template is used to enhance documentation structure and cohesion.

4.1.6. Communication

The language used for all project communication — including documentation, commit messages, pull request descriptions, and code comments — is English.

5. Building Block View

5.1. Whitebox Overall System

Overview Diagram Level 1

Motivation

The system is divided into a React-based web application and a Rust-based game engine to clearly separate user interface concerns from core game logic.

The Web App is responsible for rendering the UI and managing user interactions, while persistence is handled via the backend service.

The Game Engine encapsulates the game rules and bot logic, allowing for high performance and reusability.

This separation improves maintainability, scalability, and enables independent development of UI and game logic.

Contained Building Blocks
Name Responsibility

Web App (React / Vite / TypeScript)

Provides the user interface, handles user interactions, and communicates with the backend service via REST APIs.

Users Service (Node.js / Express)

Acts as the backend API, managing user data, authentication, and coordinating communication between the frontend, database, and game engine.

Game Engine (Rust)

Implements core game logic, rules, and bot behavior, processing game-related computations.

Database

Stores persistent data such as user accounts, game state, and scores.

5.1.1. Webapp

Here you describe <black box 1> according the the following black box template:

  • Purpose/Responsibility

  • Interface(s), when they are not extracted as separate paragraphs. This interfaces may include qualities and performance characteristics.

  • (Optional) Quality-/Performance characteristics of the black box, e.g.availability, run time behavior, …​.

  • (Optional) directory/file location

  • (Optional) Fulfilled requirements (if you need traceability to requirements).

  • (Optional) Open issues/problems/risks

Purpose/Responsibility

Provides the user interface of the system. It handles user interactions, renders the game board, and communicates with the backend service to retrieve and update data.

Interface(s)

REST API calls to the Users Service:

POST /login – user authentication

GET /user – retrieve user data

POST /ybot/choose – send player actions and return the bots´ moves

Receives JSON responses containing user and game state data and sends YEN.

Quality/Performance Characteristics

The application features a responsive user interface with low-latency interactions, ensuring a smooth user experience. It is designed to be compatible across multiple browsers, providing consistent behavior regardless of the platform.

Additionally, it achieves fast rendering performance by leveraging modern frontend tooling such as Vite.

Directory/File Location: /webapp

Fulfilled Requirements

The system supports user interaction and provides clear gameplay visualization, allowing users to engage with the application effectively.

It also includes functionality to display the current game state and results in a way that is easy to understand.

Open Issues/Problems/Risks

There are potential performance limitations when handling complex UI updates, which could affect responsiveness under heavier workloads.

Additionally, the system relies on backend availability, meaning any downtime or instability on the backend could impact overall functionality.

5.1.2. Users Service (Node.js / Express)

Purpose/Responsibility

Acts as the central backend service. It manages user-related functionality, handles authentication, and coordinates communication between the frontend, database, and game engine.

Interface(s)

REST API exposed to Web App:

Authentication endpoints (/login, /register)

Internal communication:

Database queries (CRUD operations)

Quality/Performance Characteristics

The service is designed to be stateless, enabling better scalability and easier distribution across multiple instances and it efficiently handles concurrent requests, supporting multiple users without significant degradation in performance.

Directory/File Location: /users

Fulfilled Requirements

The system provides user management and authentication capabilities, ensuring users can be created, managed, and securely access the application.

Open Issues/Problems/Risks

There is a potential single point of failure if the service is not properly replicated, which could impact availability and when under high load conditions, the system may experience performance bottlenecks that affect responsiveness.

5.1.3. Game Engine (Rust)

Purpose/Responsibility

Implements the core game logic, including rules, state transitions, bot behavior, processing game actions and computing the resulting game state.

Interface(s)

Receives requests from Webapp:

Input: current game state + player move

Output: updated game state and bot actions

Quality/Performance Characteristics

This component is built for high performance and low-level efficiency, enabling fast execution of operations.

It provides deterministic and reliable computation, which is essential for consistent behavior. Its design makes it well-suited for handling complex game logic and AI functionality.

Directory/File Location: /gamey

Fulfilled Requirements

The system enforces game rules accurately, supports bot and AI decision-making processes, and manages game state updates effectively to ensure smooth gameplay.

Open Issues/Problems/Risks

Integrating this component with the Node.js service introduces complexity, particularly in maintaining seamless communication between different technologies.

Additionally, debugging can be more challenging due to crossing language boundaries, which may slow down issue resolution.

5.1.4. Database

Purpose/Responsibility

Provides persistent storage for the system, including user data, game states, and scores.

Interface(s)

This component is accessed by the Users Service through database queries, enabling interaction with stored data. It supports full CRUD operations, allowing the creation and updating of user data as well as the storage and retrieval of game state information.

Quality/Performance Characteristics

The system ensures data consistency and reliability, which are critical for maintaining accurate records. Its scalability depends on the chosen database technology, allowing it to grow with demand. However, overall performance is closely tied to how well queries are optimized.

Directory/File Location External system (not part of source directories)

Fulfilled Requirements

It provides persistent storage for both user and game data, and enables retrieval of both historical and current game information as needed.

Open Issues/Problems/Risks

The system may encounter performance bottlenecks when handling large datasets, particularly if queries are not optimized. It also requires robust backup solutions and data integrity strategies to prevent data loss and ensure reliability.

5.2. Level 2

Here you can specify the inner structure of (some) building blocks from level 1 as white boxes.

You have to decide which building blocks of your system are important enough to justify such a detailed description. Please prefer relevance over completeness. Specify important, surprising, risky, complex or volatile building blocks. Leave out normal, simple, boring or standardized parts of your system

5.2.1. White Box Web App – Game Board Component

…​describes the internal structure of building block 1.

Diagram

GameBoard Diagram Level 2

Purpose/Responsibility

Renders the visual game board, updates state based on player actions, and communicates moves to the Users Service.

Interface(s)

This component receives the game state from Gamey in JSON format and communicates player moves back through the backend API, enabling continuous interaction between the frontend and the game logic.

Quality/Performance Characteristics

It delivers a responsive user interface with low-latency updates, ensuring smooth gameplay. The use of React state management allows for reactive updates, keeping the UI in sync with the latest game state.

Directory/File Location: webapp/src/components/GameBoard.tsx

Fulfilled Requirements

The component provides a visual representation of the game board and effectively handles player interactions, allowing users to engage directly with the game.

Open Issues/Problems/Risks

Rendering complexity may increase significantly for larger boards, which could negatively impact performance and responsiveness.

5.2.2. White Box Gamey – Bots

Diagram

Bots Diagram Level 2

Purpose/Responsibility

Implements AI decision-making for the game, generating moves based on the current game state.

Interface(s)

Input: current game state

Output: selected move

Exposed via the Backend API

Quality/Performance Characteristics

It is designed for efficient computation of AI-driven moves, ensuring minimal delay during gameplay. Additionally, its deterministic behavior supports consistent results, which is particularly useful for testing and debugging.

Directory/File Location: gamey/src/bot/

Fulfilled Requirements

The component automates bot moves within the game, contributing to gameplay progression and providing a level of challenge for players.

Open Issues/Problems/Risks

Scaling to support multiple bots simultaneously may lead to increased processing time, potentially affecting overall system performance.

6. Runtime View

6.1. Single Player Game Initialization

Diagram

Game Initialization Sequence with Difficulty

Description

The user opens the Web App and starts a game. The Web App sends the JWT to the Users Service, which verifies it using Firebase Authentication. Firebase validates the token and returns the user identity, which is forwarded back to the Web App.

The user selects a difficulty level, and the Web App sends a request to Gamey to create a new game.

Gamey validates the JWT again through the Users Service (which delegates verification to Firebase). Once validated, Gamey creates the game, assigns a bot based on difficulty, and initializes it.

The Bot prepares its internal state and confirms readiness. Finally, Gamey returns the initial game state and the Web App renders the board.

6.2. Player Move and Bot Response

Diagram

Player move sequence (Web App → Gamey → ybot)

Description

The user performs a move in the Web App. The request is sent to Gamey along with the JWT.

Gamey validates the token via the Users Service, which in turn uses Firebase Authentication. Once validated, Gamey processes the move, updates the board, and forwards the state to the Bot.

The Bot computes its move and returns it. Gamey applies the bot move, checks for win conditions, and persists the updated state.

The updated board is returned to the Web App and rendered to the user.

6.3. View Match History

Diagram

Match history sequence (Web App → Users Module)

Description

The user requests their match history from the Web App. The Web App sends the request to the Users Service with the JWT.

The Users Service validates the token using Firebase Authentication and extracts the user_id. It then queries the database for matches associated with that user.

The results are returned to the Web App, which displays them to the user.

7. Deployment View

7.1. Infrastructure Level 1

Infrastructure Level 1 Diagram
Motivation

The system is deployed on a single Azure virtual machine, using Docker Compose to orchestrate all six services. This decision simplifies deployment and management for a small team while maintaining service isolation through containers. MongoDB runs as a container with a persistent volume so game and user data survives container restarts. Authentication is delegated to Firebase (Google Cloud) to avoid managing credentials manually. Monitoring is handled by a Prometheus + Grafana stack deployed alongside the application services.

Quality and/or Performance Features
  • Availability: The Azure server runs 24/7. Docker Compose restarts containers automatically on failure. MongoDB data is persisted in a named Docker volume (mongo_data), so data is not lost on redeployment.

  • Observability: The users service exposes Prometheus-format metrics via express-prom-bundle at /metrics. Prometheus scrapes these metrics and Grafana provides dashboards for visualization, provisioned automatically via configuration files.

  • Security: Communication between the browser and the backend uses JWT tokens signed by Firebase. Sensitive variables (Firebase keys, MongoDB URL) are managed as GitHub Actions secrets and injected at deploy time via appleboy/ssh-action. The mongo container is not exposed externally — only accessible within the monitor-net internal network.

  • Scalability: The microservices architecture allows each service to be scaled independently if needed in the future.

Mapping of Building Blocks to Infrastructure
Software Component Docker Container Exposed Port

React Frontend (Vite + Nginx)

webapp

80

Users and Games API (Node.js + Express)

users

3000

Game Engine and Bots (Rust + Axum)

gamey

4000

Database (MongoDB 7)

mongo

internal only

Metrics collection

prometheus

9090

Metrics visualization

grafana

9091

7.2. Infrastructure Level 2

7.2.1. Azure Virtual Machine

The VM runs Ubuntu 24.04 LTS. Docker Engine and Docker Compose are installed directly on the machine. SSH access for deployments is restricted via public/private key pair, with the private key stored as a GitHub Actions secret (DEPLOY_KEY). All containers share the internal monitor-net bridge network, which allows inter-service communication by container name (e.g. users connects to MongoDB as mongodb://mongo:27017/yovi and reaches the game engine at http://gamey:4000). The mongo container is the only service not exposed externally. A named volume mongo_data persists database contents across deployments.

7.2.2. CI/CD Pipeline (GitHub Actions)

GitHub Actions CI/CD Pipeline

The pipeline is triggered when a release is published on GitHub. Unit tests for Node.js services (webapp and users) run in parallel via a matrix strategy, and Rust tests run concurrently. E2E tests run after all unit tests pass, with a real MongoDB 7 instance spun up as a GitHub Actions service and Firebase credentials injected as environment variables. Docker images are built and pushed to GitHub Container Registry (ghcr.io/arquisoft/yovi_es3b-*). The three Docker images are built in parallel after E2E tests pass. Finally, the server fetches the latest docker-compose.yml from the master branch and pulls the new images.

The webapp image is built with all VITE_* variables injected as build arguments (API URL, Gamey URL, and Firebase configuration), since Vite embeds environment variables at build time and they cannot be changed at runtime.

Firebase Admin credentials (FIREBASE_PROJECT_ID, FIREBASE_CLIENT_EMAIL, FIREBASE_PRIVATE_KEY) are transferred to the remote server via the envs parameter of appleboy/ssh-action so the users container can verify Firebase tokens at runtime.

7.2.3. Monitoring Stack

Prometheus is configured via users/monitoring/prometheus/ and scrapes metrics from the users service at /metrics. Grafana reads from Prometheus and is provisioned automatically via users/monitoring/grafana/provisioning/. Both services are part of the monitor-net network. Grafana is accessible on port 9091 of the Azure VM (internally mapped from Grafana’s default port 3000).

8. Cross-cutting Concepts

8.1. Domain Concepts

The system’s domain revolves around the board game Y, encompassing gameplay mechanics, user interactions, and data persistence. Core concepts include the game board, represented as a graph structure, and moves, which describe the placement of a piece by either a player or the AI. The win condition is defined as connecting all three sides with the player’s moves, and difficulty levels dictate the complexity of AI behavior.

The domain model includes users identified by their Firebase UID, game sessions which store information such as ID, state, difficulty, and result, individual moves that record position, player, and coordinates, and game history, which keeps a list of sessions per user along with relevant details.

Key domain processes involve starting a game session with a chosen AI difficulty, executing player moves on the board, allowing the bot to respond with its own moves, checking for a win condition after each move, and storing the results in the user’s game history. The authenticated flow begins with the user logging into the application, playing a complete game, saving the results at the end, and retrieving their history to review previously played sessions.

8.2. Safety & Security

Security is a primary cross-cutting concern and is largely handled via Firebase, complemented by backend enforcement. Authentication is managed through Firebase Authentication using JWTs, supporting email and password and allowing for future extension to OAuth providers. Backend authorization validates Firebase ID tokens on every protected request, ensuring that only authenticated users can interact with the system, and no passwords are stored on the backend.

Validation and integrity are enforced in the backend by checking game moves to prevent illegal actions, verifying request payloads, and ensuring that no tampering occurs that could compromise the state of the system.

8.3. Architecture & Design Patterns

The system follows a client-server architecture with a stateless backend implemented in Rust. Several design patterns are applied to enhance modularity and maintainability, including a layered architecture, the strategy pattern to manage AI difficulty levels, a middleware pattern for JWT authentication, and a component-based architecture in React for the frontend.

React handles the UI and user interaction, Rust implements the game logic, Node.js manages user data persistence, and Firebase provides authentication services. This division ensures that each layer focuses on its responsibilities while maintaining clean interfaces between them.

8.4. Under-the-hood (Technical Concepts)

The database stores game history and user references based on Firebase UID. The system communicates through a REST API using JSON over HTTP, and all authenticated requests include a Firebase ID token. Business rules are enforced in the backend, ensuring that only legal moves are allowed, the correct turn order is maintained, and win condition logic is accurately evaluated. Rust allows efficient handling of multiple concurrent game sessions and provides performance benefits through lightweight state management and optimized AI computations for each difficulty level.

8.5. User Interface & Experience

The UI is built with React using modular components for the game board, history, and authentication. Users experience instant feedback on moves, clear win and loss states, and smooth transitions between screens. Ergonomics are prioritized with simple game controls and minimal interactions required to start playing. Global state management includes maintaining the authentication session through Firebase, allowing consistent user experience across components.

8.6. Development Concepts

The system’s build and configuration processes are streamlined with React’s build pipeline and Rust builds managed via Cargo. Testing is performed at multiple levels, including unit tests for game logic and UI components, as well as integration tests for API endpoints and authentication. The modular design of both frontend and backend allows the addition of new game modes or features without impacting existing functionality.

8.7. Operation & Administration

The frontend is deployed as a static hosting application on Azure, providing fast load times and easy scalability. The backend runs as a cloud service on an Azure VM, optionally containerized using Docker for portability. Backend logs track requests and errors, while Firebase provides authentication monitoring. API requests and errors are traced to facilitate debugging and operational insight.

The stateless backend architecture allows horizontal scaling, and Firebase automatically handles authentication scaling. Frontend and backend components can scale independently, optimizing resource usage and ensuring resilience to partial failures, such as when authentication services experience issues but gameplay continues uninterrupted. Key design decisions highlight the rationale behind technology choices: Firebase simplifies authentication management, Rust ensures high-performance and memory-safe game logic, React enables interactive and reusable UI components, and the stateless backend promotes scalability, simplicity, and overall system resilience.

9. Architecture Decisions

This section documents the important, high-impact architectural decisions that influence the design and development of Yovi_es3b. The decisions are documented using the ADR format, organized by importance and consequences. Each decision includes the status, context, alternatives, justification, and consequences.


9.1. ADR 1: Rust for the Gamey Engine

Status

Accepted

Context

The gamey engine requires high-performance game logic and bot calculations. The system needs memory safety guarantees without sacrificing performance.

Alternatives

Java, Python, C/C++

Justification

Performance: Rust delivers compiled performance comparable to C/C++ without runtime overhead. Memory Safety: Rust’s ownership system guarantees memory safety at compile time, eliminating entire classes of bugs (null pointer dereferences, buffer overflows). Concurrency: Rust’s type system ensures thread safety without needing a garbage collector, ideal for game loop processing.

Consequences

- High learning curve for developers unfamiliar with Rust’s. - A little longer compile times compared to interpreted languages.


9.2. ADR 2: Node.js & Express for the Users Service

Status

Accepted

Context

The users service handles I/O-intensive operations including REST API endpoints, database queries, and user management.

Alternatives

Java/Spring Boot

Justification

Non-blocking I/O: Node.js is very good at handling concurrent I/O operations with minimal overhead, ideal for managing multiple database queries and API requests. JavaScript Ecosystem: Rich ecosystem of libraries for REST API development, database drivers, and middleware. Development Speed: Rapid prototyping and iteration due to dynamic typing and extensive npm package availability. Operational Consistency: TypeScript is used for type safety, bringing consistency with the webapp frontend.

Consequences

- Less suitable for CPU-intensive operations. - Memory consumption can be higher than compiled languages for equivalent workloads.


9.3. ADR 3: React & TypeScript for the Webapp Frontend

Status

Accepted

Context

The webapp requires a dynamic, interactive user interface with component reusability and type safety. The frontend must communicate without any problems with backend services.

Alternatives

Angular, Svelte

Justification

Component-Based Architecture: React enables building modular, reusable UI components that simplify maintenance and testing. Type Safety: TypeScript reduces runtime errors and improves IDE support, enhancing developer productivity. Ecosystem & Tooling: very good ecosystem with extensive third-party libraries and a strong community support.

Consequences

- Adds build complexity compared to normal JavaScript. - Requires discipline in state management as the application scales.


9.4. ADR 4: Vite as the Frontend Build Tool

Status

Accepted

Context

The React webapp requires a modern build tool that provides fast development experience and optimized production builds.

Alternatives

Webpack

Justification

Production Optimization: Automatic code splitting and tree-shaking produce optimized bundles. Configuration Simplicity: Minimal configuration required, while remaining extensible for advanced use cases. Modern Tooling: use modern build techniques without the legacy constraints of older tools.

Consequences

- Smaller ecosystem compared to Webpack, we think is sufficient for the project’s scale. - Requires Node.js version compatibility.


9.5. ADR 5: MongoDB with Mongoose for Persistence

Status

Accepted

Context

To develop the project, a database was required to store users' data and game state. The database needed to store user profiles and authentication data and persist game state information between sessions.

Alternatives

Firebase, SQLite

Justification

Integration with Node.js: MongoDB works naturally with JSON-like documents Flexible schema design: The project may evolve during development, and MongoDB allows schema changes without complex migrations. Document-oriented model: User data and game state can be stored as structured documents, which simplifying development. Docker-friendly deployment: MongoDB has official Docker images, which simplifies integration into the existing docker-compose setup.

Consequences

- Faster development due to schema flexibility - Reduced complexity when mapping backend objects to database documents - Easy integration with the existing JavaScript stack - Simple local and production deployment using Docker - Good scalability options if the application grows - Lack of strict relational constraints - More responsibility at the application level to enforce relationships - Complex relational queries would be harder to implement compared to relational databases. - Transactions are supported, but a relational database would be be more mature in highly complex transactional scenarios


9.6. ADR 6: Docker & Docker Compose for Orchestration

Status

Accepted

Context

Yovi_es3b consists of multiple independent services (webapp, users, gamey, MongoDB) requiring consistent deployment across development, testing, and production environments.

Alternatives

Kubernetes, Platform-as-a-Service (PaaS)

Justification

Reproducibility: Docker ensures identical environments across developer machines and production servers. Ease of Use: Docker Compose provides simple, declarative orchestration for the project’s current scale without Kubernetes complexity. Isolation: Each service runs in its own container with isolated dependencies, preventing version conflicts. Rapid Onboarding: New developers can run docker-compose up and have the entire system running within seconds.

Consequences

- Docker Compose is not suitable for production a large scale project. - Requires Docker to be installed on all development machines.


9.7. ADR 7: GitHub Actions

Status

Accepted

Context

Yovi_es3b requires automated testing, code quality checks, and build validation on every code push to maintain code integrity and catch issues early.

Alternatives

Jenkins

Justification

Native Integration: Seamless integration with GitHub repositories without external infrastructure. Simplicity: Declarative YAML-based workflow configuration is intuitive and maintainable.

Consequences

- Limited flexibility compared to self-hosted CI solutions for complex multi-platform builds. - Secrets management through GitHub requires careful configuration.


9.8. ADR 8: Code Quality Monitoring (SonarCloud & CodeScene)

Status

Accepted

Context

Maintaining code quality and reach 80% test coverage is important in our project.

Alternatives

Manual code reviews, SonarQube

Justification

Comprehensive Analysis: SonarCloud detects bugs and security vulnerabilities across multiple languages. Coverage Tracking: Provides clear visibility into test coverage trends over time. GitHub Integration: Both tools integrate directly with pull requests, providing instant feedback to developers.

Consequences

- Introduces tooling dependencies and potential false positives in static analysis. - Increased CI/CD pipeline execution time due to analysis steps.

10. Quality Requirements

10.1. Quality Tree

QualityUsability#scenario-U1U1 - The UI adapts clearly to different board sizes#scenario-U2U2 - A new user can start a game in under 2 minutes#scenario-U3U3 - Game history is accessible in at most 3 clicksReliability#scenario-R1R1 - The system saves match results even if connection drops#scenario-R2R2 - User login works 99.9% of the time#scenario-R3R3 - The bot always makes a valid move within the rulesPerformance#scenario-P1P1 - The board renders in under 1 second for any supported size#scenario-P2P2 - The bot responds in under 2 seconds on any difficulty level#scenario-P3P3 - Match history loads in under 3 secondsSecurity#scenario-S1S1 - Passwords are stored encrypted (e.g. bcrypt)#scenario-S2S2 - A user can only access their own match history#scenario-S3S3 - Sessions expire after a period of inactivityMaintainability#scenario-M1M1 - Adding a new bot difficulty requires no changes outside the bot module#scenario-M2M2 - Board size logic is configurable without code changes#scenario-M3M3 - The codebase follows a consistent layered architecturePortability#scenario-Po1Po1 - The game runs on modern browsers without installation#scenario-Po2Po2 - The backend can be deployed on any standard cloud provider

10.2. Quality Scenarios

Contents

Concretization of (sometimes vague or implicit) quality requirements using (quality) scenarios.

These scenarios describe what should happen when a stimulus arrives at the system.

For architects, two kinds of scenarios are important:

  • Usage scenarios (also called application scenarios or use case scenarios) describe the system’s runtime reaction to a certain stimulus. This also includes scenarios that describe the system’s efficiency or performance. Example: The system reacts to a user’s request within one second.

  • Change scenarios describe a modification of the system or of its immediate environment. Example: Additional functionality is implemented or requirements for a quality attribute change.

Motivation

Scenarios make quality requirements concrete and allow to more easily measure or decide whether they are fulfilled.

Especially when you want to assess your architecture using methods like ATAM you need to describe your quality goals (from section 1.2) more precisely down to a level of scenarios that can be discussed and evaluated.

Form

Tabular or free form text.

Table 1. U1 – UI adapts to different board sizes

Source

Player

Stimulus

Starts a game with a non-default board size

Environment

Any modern browser, any screen resolution

Response

The board and all UI elements render correctly without overflow or distortion

Measure

No layout breakage for any supported board size

Table 2. U2 – New user starts a game quickly

Source

First-time user

Stimulus

Visits the app for the first time

Environment

Normal runtime conditions

Response

The user can register, configure and start a game

Measure

The entire flow takes under 2 minutes

Table 3. U3 – Game history is easy to reach

Source

Logged-in player

Stimulus

Wants to check their past matches

Environment

Normal runtime conditions

Response

The history screen is displayed

Measure

Reachable in at most 3 clicks from any screen

Table 4. R1 – Match results are saved despite connection drops

Source

System / Network

Stimulus

Connection drops while a match is finishing

Environment

Unstable network conditions

Response

Match result is persisted once connection is restored

Measure

No match data is lost due to temporary disconnection

Table 5. R2 – Login availability

Source

Registered player

Stimulus

Attempts to log in

Environment

Normal and peak load conditions

Response

Login succeeds with correct credentials

Measure

System available for login 99.9% of the time

Table 6. R3 – Bot always plays a valid move

Source

Game engine

Stimulus

It is the bot’s turn

Environment

Any board size, any difficulty, any game state

Response

The bot selects and plays a legal move

Measure

Zero illegal moves produced across all difficulty levels

Table 7. P1 – Board renders quickly

Source

Player

Stimulus

Starts or joins a game

Environment

Normal load, any supported board size

Response

The board is fully rendered and interactive

Measure

Render time under 1 second

Table 8. P2 – Bot responds without delay

Source

Game engine

Stimulus

Player completes their turn

Environment

Any difficulty level

Response

The bot calculates and plays its move

Measure

Response time under 2 seconds

Table 9. P3 – Match history loads fast

Source

Logged-in player

Stimulus

Opens their match history

Environment

Any number of past matches stored

Response

History list is displayed

Measure

Load time under 3 seconds

Table 10. S1 – Passwords are stored securely

Source

New or existing user

Stimulus

Registers or changes their password

Environment

Normal runtime conditions

Response

Password is hashed before storage

Measure

No plain-text passwords stored (e.g. bcrypt with salt)

Table 11. S2 – Users can only see their own history

Source

Logged-in player

Stimulus

Requests match history

Environment

Multi-user environment

Response

Only that user’s own matches are returned

Measure

No match data from other users is ever exposed

Table 12. S3 – Sessions expire after inactivity

Source

System

Stimulus

User is inactive for a configured period

Environment

Any logged-in session

Response

Session is invalidated and user must log in again

Measure

Session expires within the configured timeout window

Table 13. M1 – New bot difficulty is easy to add

Source

Developer

Stimulus

Adds a new bot difficulty level

Environment

Development environment

Response

New bot is integrated without modifying other modules

Measure

Zero changes required outside the bot module

Table 14. M2 – Board size is configurable

Source

Developer / Operator

Stimulus

Changes the supported board size range

Environment

Development or configuration environment

Response

New size is supported across the application

Measure

No code changes required, only configuration

Table 15. M3 – Consistent layered architecture

Source

Developer

Stimulus

Reviews or extends the codebase

Environment

Development environment

Response

Code structure follows the defined layers consistently

Measure

No cross-layer violations found in architecture review

Table 16. Po1 – Runs in modern browsers

Source

Player

Stimulus

Opens the app in a modern browser

Environment

Chrome, Firefox, Edge, Safari (latest versions)

Response

App loads and functions correctly

Measure

All core features work without any installation

Table 17. Po2 – Backend deployable on standard cloud

Source

Operator

Stimulus

Deploys the backend to a cloud provider

Environment

Any standard cloud platform (AWS, GCP, Azure, etc.)

Response

Backend starts and operates correctly

Measure

No provider-specific dependencies required

11. Risks and Technical Debts

This section serves as a list of identified technical risks and technical debts, ordered by priority with associated mitigation measures.


11.1. Identified Risks

ID Risk Description Impact Probability Mitigation Measures

R1

Learning Rust

Rust is a language with complex syntax and strict memory management requirements. Developing without prior experience can cause significant delays in early sprints and bad code quality.

Medium

High

See tutorials. Use LLms to explain code. Implement algorithms with progressive difficulty levels.

R2

Complexity of used technologies (Rust + TypeScript + JavaScript)

The project uses Rust as the primary language alongside TypeScript and JavaScript, with very different paradigms and ecosystems. This significantly increases development complexity and maintainability.

High

Medium

Implement continuous training in Rust and TypeScript. Establish clear integration patterns between backend (Rust) and frontend (TypeScript/JavaScript) components. Good documentation.

R3

Azure subscription

The student Azure plan provides only €100 in credits. Once spent, development, testing, and deployment activities may be interrupted.

Medium

Medium

Make automations to power off the server when is not being used. Try to look for alternatives of azure.

R4

External Library Dependencies (crates and npm)

The project depends on external packages that may contain security vulnerabilities, become unmaintained, or introduce incompatible changes, affecting system stability and security.

Medium

Low

Perform periodic audits using cargo-audit. Keep dependencies updated cautiously. Review major version changes before upgrading.

R5

Team Communication and Coordination

Lack of communication between the members of the team working on different layers (Rust backend, TypeScript frontend) can lead to misunderstandings, duplicated work, and integration errors.

High

Low

Establish clear communication channels. Make pull request. Maintain updated documentation of interfaces and API contracts. Hold weekly meetings between teammates.

R6

Team Member Abandonment

Unexpected departure of a team member could leave tasks undone and cause loss of knowledge.

Medium

Low

All members of the team have to known everything, clear documentation.


11.2. Technical Debt

ID Technical Debt Description Impact Planned Actions

D1

Insufficiently Documented Code

Lack of clear documentation in some parts of the project makes code comprehension difficult and increases risk of errors during maintenance and refactoring.

Medium

Establish documentation standards. Make some code reviews focused on documentation quality. Maintain updated documentation.

D2

Initial Implementation Without Optimization

Current implementation prioritize functionality over performance.

Medium

Plan continuous improvement iterations. Conduct performance profiling. Optimize algorithms.

D3

Not 100% Test Coverage

Rust’s complexity can lead to insufficient initial testing, leaving code without exhaustive validation.

Medium

Implement more unit tests in Rust. Establish code coverage metrics.

D4

Technical Debt From Strict Deadlines

Strict delivery deadlines forced compromises that work but are unsustainable long-term.

Medium

Try to get time in each deliverable for refactoring. Identify and prioritize critical debt areas. Perform gradual refactoring without affecting functionality.

D5

Integration Between Backend (Rust) and Frontend (TypeScript)

The code does not follow the best architectural or structural practices, generating unnecessary coupling.

Medium

Define clear API contracts. Document data schemas. Conduct code reviews focused on layer interfaces.

12. App Testing

The development of the app included multiple testing strategies to ensure the quality and reliability of the system. The testing process encompassed unit tests, end-to-end tests and load tests.

12.1. Unit Testing

Unit tests were implemented for individual components and functions across the codebase. These tests focused on verifying the correctness of isolated units of code, such as utility functions, game UI components and backend services.

The main technique used was mocking. A mock is an object that mimics the behavior of real objects in controlled ways. By using mocks, we were able to isolate the code under test and simulate various scenarios without relying on external dependencies. Mocked examples are internationalized text utlities, users API responses or game engine responses.

We used different frameworks or utilities for testing:

  • Webapp: Vitest and React Testing Library

  • Users-service: Vitest and Supertest

  • Gamey-service: Rust’s built-in testing framework (cargo test)

12.2. End-to-end test

The main goal in this test is to verify the interaction between the different services of the app. Frontend needs to comunicate with both API users service and gamey service. We used Playwright and Cucumber for this purpose. Playwright allows us to automate browser interactions, while Cucumber provides a BDD (Behavior-Driven Development) framework to write test scenarios in a human-readable format.

12.2.1. Example: Access history menu: user with 4 games

Overview of an e2e test case

12.3. Load test

Although the app is tested locally, we also have to ensure that it can handle a real world scenario. In this case we tested the performance of the app while 50 users were accessing the system at the same time. By doing so we try to detect bugs or problems under load, detect bottlenecks or demostrate the quality goals specify in the documentations.

12.3.1. Gatling

Gatling is a powerful open-source load testing tool that allows us to simulate a large number of users accessing the system concurrently. We created scenarios that mimic real user behavior, such as logging in. It works as an interceptor between the frontend and the backend, allowing us to measure response times, throughput and error rates under load. The script of the test is written in Scala and it is executed via JVM.

12.3.2. Results

We decided to test the response time to a request to get info from a user and to Firebase login. The test was done with 50 users in 25 seconds.

Statistics of the load test

We can conclude the response times are acceptable, with an average response time of 0.427 seconds for the user info request and 0.123 seconds for the Firebase login. The error rates were negligible, indicating that the system can handle the load without significant issues. Some delay was expected, as the system is allocated in India Central region from Azure, and the test was executed from Spain.

We can also analyze the variability in the times for the same request. If we look at the users data request, we can see that the response times are quite consistent, with a low standard deviation. This indicates that the system is performing reliably under load, with minimal fluctuations in response times.

Statistics of the load test

13. Glossary

The most important domain and technical terms that stakeholders should know the meaning.

Term Definition

JSON

A text-based data format for structuring information using key-value pairs and arrays. Essential for backend-to-frontend communication and integration with the game engine’s API responses.

API

A set of standardized protocols and endpoints that enable different software components to exchange data and trigger actions. In Yovi, the API serves as the communication bridge between the user interface, microservices, and the core game logic.

Bots

Autonomous software agents programmed to play the game without human intervention. Bots leverage the project’s public API to make moves, evaluate board states, and compete against human players.

Microservice REST

An architectural pattern that decomposes the application into modular, independently deployable services communicating via HTTP/REST conventions. Each Yovi service (users, gamey, webapp) operates autonomously while coordinating through REST endpoints.

Frontend

The user-facing layer of the application built with React and Vite. Handles game visualization, player input, real-time board updates, and provides an interactive interface for gameplay and user authentication.

Backend

A collection of microservices that manage game logic execution, player session lifecycle, move validation, and state persistence. Coordinates between the database, game engine, and frontend to deliver a cohesive user experience.

Game Engine

The computational core responsible for enforcing game rules, validating moves, calculating game trees, and determining outcomes. Implemented in Rust for performance and safety, it exposes its functionality through standardized APIs.

Docker

Container technology that packages the application with all dependencies into isolated, reproducible environments. Enables seamless deployment across development, testing, and production while maintaining environment consistency.

Arc42

A mature architecture documentation framework that structures technical documentation into 12 logical sections. Provides stakeholders with a comprehensive view of design decisions, system interactions, and technical trade-offs.

Microservices

A distributed system design where independent services specialize in specific business capabilities and communicate via well-defined contracts. Yovi adopts this pattern to enable parallel development, independent scaling, and technology diversity (Rust backend, TypeScript frontend).

GitHub

A version control and collaboration platform built on Git. Serves as the central repository for source code, issue tracking, pull request reviews, and team coordination throughout the development lifecycle.

LLM (Large Language Model)

An AI system trained on vast text datasets capable of understanding context and generating human-like responses. Can assist with code generation, documentation, and architectural decision-making during development.

PlantUML

A text-based diagram generation tool that converts structured descriptions into visual representations. Useful for creating sequence diagrams, component diagrams, and architecture visualizations during documentation phases.

YEN Notation

A JSON-compatible serialization protocol that captures a complete snapshot of game state including the board configuration, current turn, active players, and game metadata. Facilitates state persistence and inter-service communication.