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.


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

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

The project that was proposed was implementing the "Game Y" (similar to the best-known board game "Hex"), all while mantaining a professional workflow simulating real life situations, covering all the aspects that could happen, these include:

  • Backend development

  • Frontend development

  • Management of the APIs

  • Overcome difficulties with new software

  • Quality control

If all of these are followed correctly the resulting project should go according to the theory.

1.1. Requirements Overview

  • The game will be available as a web application.

  • Players can register, log in, play matches, and have their results stored and accessible from their profile.

  • The game includes an AI opponent whose behavior depends on the selected difficulty, ranging from easy to hard.

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 Scenario

1

Usability

A new player can register, log in, select a difficulty, and start a match against the bot in under 30 seconds without reading documentation.

2

Performance

For typical board sizes, bot move computation stays below 500 ms on "Hard" to keep gameplay fluid; worst cases must degrade gracefully (e.g., show a "thinking" state rather than freezing).

3

Maintainability

A new bot strategy or feature can be implemented and integrated in ⇐ 1 work day without breaking the existing frontend or any published API contract.

4

Security

Only authenticated users can submit results to their own profile; the system must prevent score spoofing attempts (e.g., forged results or manipulated game states).

5

Reliability

Game results are reliably persisted: at least 99% of save operations complete without data loss, and failures are reported explicitly (no silent loss).

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.

Role/Name Contact Expectations

Project Sponsor (Micrati)

Company (Micrati)

Expects a working, publicly accessible web game with a clear architecture, documented APIs, and a deliverable aligned with the assignment scope and timeline.

Project Supervisor (Teacher)

Teaching Staff

Expects a professional development workflow, clean and documented code, and fulfillment of all functional requirements (bot + web application).

Development Team (Team)

Team members

Expect to learn new technologies (API management, frontend/backend), gain experience in professional workflows, and achieve a high grade.

End Users (Players)

Web

Expect a functional and entertaining game, a challenging bot difficulty, and the ability to save their progress reliably.

API Consumers (Bot developers / external clients)

Public API

Expect a stable and well-documented API contract, with clear error messages and examples.

Quality Assurance (Team / reviewers)

Team members

Expect the code to be testable and the game to be free of critical bugs before deployment.

2. Architecture Constraints

2.1. Technical Constraints

Constraint Background and/or Motivation

Web-based Access

The game must be accessible via a standard web browser (Chrome, Firefox, etc.) without requiring local installation.

Public Deployment

The application must be deployed and publicly accessible via the Web (academic delivery constraint).

Backend/Frontend Separation

The logic (APIs/services) and the presentation (UI) must be decoupled to keep clear client/server boundaries and enable independent development.

Bot Implementation

The system must include an algorithmic bot with selectable difficulty and/or multiple strategies (exact number of difficulty levels is not fixed).

Persistence

A database or persistent storage must be used to save player profiles and game history.

YEN notation (JSON messages)

Game state must be exchanged as JSON using YEN notation to ensure interoperability between modules.

2.2. Organizational Constraints

Constraint Background and/or Motivation

Team Structure

Work is divided among students acting as a full-stack development team, requiring clear communication and task management.

Deadline

The project must be completed and documented within the academic semester timeframe.

Technology adoption (learning curve)

The project requires using technologies that are new to the team (e.g., Docker, TypeScript, Rust), which may affect planning and delivery.

2.3. Conventions

Constraint Background and/or Motivation

arc42 Documentation

The software architecture must be documented using the arc42 template.

Version Control

Use of Git (e.g., GitHub or GitLab) is mandatory to track progress and manage collaborative code changes.

YEN notation

Use YEN notation in JSON messages whenever a game state is exchanged.

Contents

Any requirement that constraints software architects in their freedom of design and implementation decisions or decision about the development process. These constraints sometimes go beyond individual systems and are valid for whole organizations and companies.

Motivation

Architects should know exactly where they are free in their design decisions and where they must adhere to constraints. Constraints must always be dealt with; they may be negotiable, though.

Form

Simple tables of constraints with explanations. If needed you can subdivide them into technical constraints, organizational and political constraints and conventions (e.g. programming or versioning guidelines, documentation or naming conventions)

Further Information

See Architecture Constraints in the arc42 documentation.

3. Context and Scope

Contents

Context and scope - as the name suggests - delimits your system (i.e. your scope) from all its communication partners (neighboring systems and users, i.e. the context of your system). It thereby specifies the external interfaces.

If necessary, differentiate the business context (domain specific inputs and outputs) from the technical context (channels, protocols, hardware).

Motivation

The domain interfaces and technical interfaces to communication partners are among your system’s most critical aspects. Make sure that you completely understand them.

Form

Various options:

  • Context diagrams

  • Lists of communication partners and their interfaces.

Further Information

See Context and Scope in the arc42 documentation.

3.1. Business Context

Contents

Specification of all communication partners (users, IT-systems, …​) with explanations of domain specific inputs and outputs or interfaces.

Motivation

All stakeholders should understand which data are exchanged with the environment of the system.

Form

All kinds of diagrams that show the system as a black box and specify the domain interfaces to communication partners. Alternatively (or additionally) you can use a table.

The business context defines the external actors and how they interact with the YOVI system. The system exposes two public API surfaces (user management and game interaction) and delegates core game validation / bot move selection to the internal Rust engine.

Table 1. Communication Partners
Communication Partner Inputs Outputs

Human Player (Web client)

Registration/login, game actions (moves), game configuration

UI feedback, game state, personal profile and history

External Client (Public User API consumer)

Register/login, profile/history requests (JWT-based)

JWT tokens, user/profile/history data

External Client (Public Game API consumer)

Game requests (create/join room, play), board state in YEN/JSON when required

Game state updates, bot next move (when playing vs AI), error responses

Operator (Project team / admin role)

Service status queries (health) and basic operational requests

Service status information and basic diagnostics

3.1.1. Domain Interfaces

  • Web UI: React-based interface for end-user interaction.

  • Public User API: REST endpoints for registration/login and user profile/history.

  • Public Game API: REST endpoints to interact with the game (including playing against the bot using JSON/YEN).

3.2. Technical Context

Contents

Technical interfaces (channels and transmission media) linking your system to its environment. In addition a mapping of domain specific input/output to the channels, i.e. an explanation which I/O uses which channel.

Motivation

Many stakeholders make architectural decision based on the technical interfaces between the system and its context. Especially infrastructure or hardware designers decide these technical interfaces.

Form

E.g. UML deployment diagram describing channels to neighboring systems, together with a mapping table showing the relationships between channels and input/output.

The technical context describes the protocols and communication channels between services and external clients.

3.2.1. Technical Interfaces and Channels

Table 2. Technical Interfaces and Channels
Interface Channel / Protocol Description

Frontend ↔ Webapp-backend

HTTP / REST

The React application (Vite) communicates with the Node.js backend using REST endpoints.

Frontend ↔ Webapp-backend (realtime)

WebSocket

Realtime channel used for gameplay/multiplayer events (when enabled).

Webapp-backend ↔ gamey (Rust engine)

HTTP / JSON (YEN)

The Node.js service delegates game validation and bot move computation to the Rust engine.

Webapp-backend ↔ users

HTTP / REST

Webapp-backend calls the users service for authentication/authorization and user-related operations.

External clients ↔ users

HTTP / REST

Public user management API (register/login/profile/history).

Users ↔ MariaDB

MariaDB protocol

Persistence of user data and credentials.

3.2.2. Mapping of Inputs/Outputs to Channels

  1. Access Management: Login/registration requests are handled by the Users service, which returns a JWT on success.

  2. Move Processing: Game flow uses REST and/or WebSockets from client to Webapp-backend; bot move/validation is delegated to gamey via HTTP using JSON/YEN.

  3. Persistence: User data and history are persisted in MariaDB via the Users service; additional persistence responsibilities are TBD (if introduced later).

4. Solution Strategy

Contents

A short summary and explanation of the fundamental decisions and solution strategies, that shape system architecture. It includes

  • technology decisions

  • decisions about the top-level decomposition of the system, e.g. usage of an architectural pattern or design pattern

  • decisions on how to achieve key quality goals

  • relevant organizational decisions, e.g. selecting a development process or delegating certain tasks to third parties.

Motivation

These decisions form the cornerstones for your architecture. They are the foundation for many other detailed decisions or implementation rules.

Form

Keep the explanations of such key decisions short.

Motivate what was decided and why it was decided that way, based upon problem statement, quality goals and key constraints. Refer to details in the following sections.

Further Information

See Solution Strategy in the arc42 documentation.

The architecture of the YOVI system follows a modular client/server approach that separates the user interface from backend services and the core game engine. This strategy supports maintainability and interoperability by keeping clear boundaries between UI, user management, and game logic. The system exposes public APIs for user management and game interaction, while the Rust game engine remains internal and focused on validation and bot move computation.

4.1. Technology decisions

The web client is implemented in TypeScript to enable fast development of an interactive UI using modern web frameworks. Backend services are implemented as HTTP APIs, and the game engine is implemented in Rust for performance and memory safety when running validation and search-based bot strategies. Inter-service communication uses JSON and the YEN notation as the game-state contract.

4.2. Quality Goal Realization

Correctness and reliability are improved by enforcing game rules and validating YEN/JSON game states in the Rust engine. Usability is addressed through a simple web-based flow (register/login/start game) and a clear UI. Performance is addressed by using a compiled Rust engine for the computationally intensive bot logic and by keeping service calls bounded (timeouts) to avoid hanging requests. Maintainability is supported by the separation into services (webapp-backend, users, gamey) and stable API contracts between them. Security is handled through JWT-based authentication and role-based authorization (player/admin) for protected operations.

4.3. Organizational decisions

The system is developed by a four-member team with shared responsibilities across the stack. Version control and issue tracking support collaborative work and code quality through reviews and automated checks.

5. Building Block View

Content

The building block view shows the static decomposition of the system into building blocks (modules, components, subsystems, classes, interfaces, packages, libraries, frameworks, layers, partitions, tiers, functions, macros, operations, data structures, …​) as well as their dependencies (relationships, associations, …​)

This view is mandatory for every architecture documentation. In analogy to a house this is the floor plan.

Motivation

Maintain an overview of your source code by making its structure understandable through abstraction.

This allows you to communicate with your stakeholder on an abstract level without disclosing implementation details.

Form

The building block view is a hierarchical collection of black boxes and white boxes (see figure below) and their descriptions.

Hierarchy of building blocks

Level 1 is the white box description of the overall system together with black box descriptions of all contained building blocks.

Level 2 zooms into some building blocks of level 1. Thus it contains the white box description of selected building blocks of level 1, together with black box descriptions of their internal building blocks.

Level 3 zooms into selected building blocks of level 2, and so on.

Further Information

See Building Block View in the arc42 documentation.

5.1. Whitebox Overall System

overview diagram

Here you describe the decomposition of the overall system using the following white box template. It contains

  • an overview diagram

  • a motivation for the decomposition

  • black box descriptions of the contained building blocks. For these we offer you alternatives:

    • use one table for a short and pragmatic overview of all contained building blocks and their interfaces

    • use a list of black box descriptions of the building blocks according to the black box template (see below). Depending on your choice of tool this list could be sub-chapters (in text files), sub-pages (in a Wiki) or nested elements (in a modeling tool).

  • (optional:) important interfaces, that are not explained in the black box templates of a building block, but are very important for understanding the white box. Since there are so many ways to specify interfaces why do not provide a specific template for them. In the worst case you have to specify and describe syntax, semantics, protocols, error handling, restrictions, versions, qualities, necessary compatibilities and many things more. In the best case you will get away with examples or simple signatures.

Rationale

We applied functional decomposition to separate responsibilities within the YOVI system and keep clear client/server boundaries.

Contained Blackboxes
Building Block Description

Web Frontend

Browser-based TypeScript application. Renders the Y game board, handles user interaction, and communicates with the public APIs via REST (and WebSockets when realtime gameplay is enabled).

webapp-backend (Game API / BFF)

Node/TypeScript service exposing the public Game API (match flow, play actions, game-related statistics). Orchestrates calls to gamey using JSON/YEN and calls users when authentication/profile data is required.

users service (User API / Auth)

Service exposing the public User API (register/login/profile). Issues and verifies JWTs, applies basic authorization (roles), and is the only component that accesses MariaDB.

gamey (Rust engine)

Rust service responsible for validating game states and computing the next move. Uses YEN notation for board representation and exposes a minimal JSON-based web service interface to webapp-backend.

Database (MariaDB)

Persistent storage for user accounts and credentials/roles. Accessed exclusively by the users service.

Player (external)

Human user interacting through the Web Frontend to play matches and manage their account.

External client (external)

Any third-party client consuming the public APIs (User API and/or Game API) over HTTP, e.g., automated gameplay clients.

5.2. Level 2

level2 diagram

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. Level 2 - webapp-backend (Game API / BFF)

Building Block Description

Routes

Single entry point for the public APIs exposed by webapp-backend. Delegates game requests to MatchService and forwards authentication/profile operations to the users service.

MatchService

Encapsulates game workflow logic: creating matches/rooms, updating board states, and coordinating validation and next-move computations. Calls users only for authentication/profile data when required.

RustClient

HTTP client responsible for invoking the gamey service. Sends board state in JSON/YEN format to request validation or next-move suggestions.

5.2.2. Level 2 - users service (User API / Auth)

Building Block Description

Routes

Handles HTTP requests entering the User API. Delegates to UserService.

UserService

Business logic for authentication and user operations (issue/verify JWTs, profile management, role checks). Coordinates persistence via UserRepository.

UserRepository

Persistence component managing user accounts and credentials/roles (create, read, update, delete). Accessed exclusively via UserService.

5.2.3. Level 2 - gamey (Rust engine)

Building Block Description

Axum API

Minimal internal HTTP interface invoked by webapp-backend for validation and choose-move requests.

YENAdapter

Parses and serializes YEN/JSON game states and converts them to/from internal board representation.

Validator + Bot

Enforces game rules and computes next moves.

6. Runtime View

The runtime view describes the behaviour and interactions of the system’s building blocks through selected scenarios. It captures how the TypeScript services (game, users) and the Rust engine (gamey) cooperate to fulfil the requirements.

6.1. Human vs Computer Match

This scenario references the high-level requirement: Classic version of Game Y, player-vs-machine mode. It covers the complete server-side round trip that occurs when a human player makes a move in a PvE game session.

6.1.1. Quality Context

Source

Human Player

Stimulus

Selects a position on the board via the Web Frontend

Artifact

System (game service + gamey Rust engine)

Environment

Normal operation, active PvE game session

Response

The move is validated, the bot responds, the state is persisted, and the full updated board is returned to the frontend in a single round trip

Response Measure

The UI reflects the new state (human move + bot move) in under 500 ms for medium difficulty (fast_bot)

6.1.2. Interaction sequence

Human vs Computer Match Sequence

1. The User selects a cell on the board via the Web Frontend.

2. The Frontend sends POST /game/api/games/{id}/move to the game service with { row, col, player }.

3. The game service validates the move: it checks that the game is active, the player’s turn is correct, and the target cell is unoccupied. A 409 Conflict is returned immediately if any check fails.

4. The game service applies the human player’s move to the in-memory board state.

5. In PvE mode, the game service encodes the updated board in YEN notation and calls gamey (POST /ybot/choose/{botId}) to obtain the bot’s response. The bot identifier is determined by the session’s configured difficulty level: random_bot (easy), fast_bot (medium), or smart_bot (hard).

6. gamey computes the next move using the selected strategy within its time budget and returns the chosen cell coordinate.

7. The game service applies the bot’s move to the board state and evaluates the win condition.

8. The game service persists the updated board state, current turn, winner (if any), and both move records to MariaDB.

9. If the game has ended, the game service posts the match result to the users service (via USERS_SERVICE_URL) so that it is recorded in the match_records table.

10. The game service returns the complete, updated GameState JSON — containing the post-bot-move board, status, winner, and timer — to the Frontend in a single HTTP response.

11. The Frontend renders the new board state and displays the game result or continues awaiting the next player input.

6.2. User Registration and History Consultation

This scenario references the high-level requirement: Users will be able to register and consult their participation history. It describes how a user creates an account and later views their match statistics.

6.2.1. Quality Context

Source

Human Player

Stimulus

Provides registration details via the Web Frontend; later requests their match history

Artifact

System (users service)

Environment

Normal operation

Response

The user account is created and a session is established; history is retrieved from persistent storage and rendered

Response Measure

Both operations complete and the UI reflects the new state in under 500 ms

6.2.2. Interaction sequence

registration
Figure 1. User registration
history
Figure 2. History consultation

1. The User provides registration credentials (username, e-mail, password) via the Web Frontend.

2. The Frontend sends POST /users/api/auth/register to the users service.

3. The users service validates the input, hashes the password with bcrypt, and writes the new account to the users table in MariaDB.

4. The users service returns the created user object and a JWT to the Frontend, which stores the token for subsequent authenticated requests.

5. When the registered User later requests their match history, the Frontend sends an authenticated request to the users service.

6. The users service queries the match_records table in MariaDB for all records belonging to the authenticated user.

7. The users service returns the raw match records (opponent, result, duration, timestamp) to the Frontend.

8. The Frontend computes summary metrics (win rate, total games, etc.) and renders the history view.

6.3. Computer Strategy Execution

This scenario references the high-level requirement: The game against the computer must implement more than one strategy, and the user shall be able to select which strategy to use. It describes how the game service and gamey cooperate to produce the bot’s response move.

6.3.1. Quality Context

Source

game service (triggered by a human player’s move in a PvE session)

Stimulus

The human move has been applied; the game service must obtain the bot’s response

Artifact

gamey Rust engine

Environment

Normal operation

Response

gamey selects a legal move using the strategy configured for this session and returns the chosen cell

Response Measure

p95 ≤ 500 ms for fast_bot (medium); p95 ≤ 3 000 ms for smart_bot (hard), with "thinking" indicator shown in the UI

6.3.2. Interaction sequence

Computer Strategy Execution Sequence

1. After applying the human move, the game service encodes the current board state in YEN notation ({ size, turn, players, layout }).

2. The game service sends POST /ybot/choose/{botId} to gamey, where botId is one of: random_bot (easy), fast_bot (medium, 500 ms budget), or smart_bot (hard, up to 3 000 ms budget).

3. gamey deserialises the YEN payload via its YENAdapter and invokes the corresponding strategy algorithm. fast_bot and smart_bot use minimax with alpha-beta pruning and iterative deepening; random_bot selects a uniformly random legal cell.

4. gamey returns the chosen move as a barycentric coordinate string ("x,y,z") to the game service.

5. The game service applies the bot’s move and continues with win detection and state persistence (see Human vs Computer Match, steps 7–11).

6.4. External Bot Interaction

This scenario references the high-level requirement: The API will enable a bot to play against the application. A 'play' method will be exposed, requiring at least one 'position' parameter indicating the board state in YEN notation. It describes how a third-party bot interacts with the system through the interop service.

6.4.1. Quality Context

Source

External Bot

Stimulus

Invokes POST /games/play on the interop service, supplying a position in YEN notation and optionally a bot_id or strategy

Artifact

interop service + gamey Rust engine

Environment

Normal operation

Response

The system validates the YEN position, computes the bot’s next move via gamey, and returns it together with the updated board layout

Response Measure

The interop service returns the response in YEN notation within the configured timeout (2 s for random_bot; up to 3 s for minimax strategies)

6.4.2. Interaction sequence

External Bot Interaction Sequence

1. The External Bot calls POST /games/play on the interop service with the request body { position: YEN, bot_id?, strategy? }.

2. The interop service validates the position field (structure, size, layout consistency). A 400 INVALID_POSITION error is returned immediately if the YEN object is malformed.

3. The interop service resolves the target bot: bot_id takes priority over strategy; if neither is supplied, random_bot is used as the default.

4. The interop service forwards the YEN board state to gamey to compute the bot’s move.

5. gamey calculates the next move using the resolved strategy and returns the chosen cell coordinate.

6. The interop service constructs the response { move: "x,y,z", position: updatedLayout, bot_id } and returns it to the External Bot. The position field in the response contains the updated YEN layout string after the bot’s move has been applied.

7. Deployment View

The deployment view describes the physical environment in which the YOVI system executes and the automation processes that manage its lifecycle.

7.1. Infrastructure Level 1: Cloud Environment

The system is deployed on Microsoft Azure using the "Azure for Students" subscription. A virtual machine with the following profile was provisioned, balancing performance against cost:

  • Location: France Central

  • Operating System: Linux Ubuntu

  • Hardware Profile: Standard B2ats v2 (2 vCPUs, 1 GiB memory)

7.2. Infrastructure Level 2: Execution Environment (Docker)

The system follows a "Cattle not Pets" approach, using Docker containers coordinated by Docker Compose to ensure consistency between development and production environments.

Container Technology Port Responsibility

webapp

Nginx + React 18 (TypeScript, Vite)

80 / 443

Serves the React SPA as static files and acts as the Nginx reverse proxy, routing /users/ to the users service, /game/ to the game service, and proxying Grafana and Prometheus paths.

users

TypeScript / Node.js 22 (Express, TypeORM)

3000

Authentication, user profiles, match history, and ranking. Manages the users and match_records tables.

game

TypeScript / Node.js 22 (Express, TypeORM)

5000

Game session management, move validation, bot orchestration, and timer enforcement. Manages the games and game_moves tables. Delegates bot move computation to gamey.

gamey

Rust (Axum)

4000 (internal only)

Bot AI engine. Computes the next move for a given YEN board position using the configured strategy (random_bot, fast_bot, smart_bot). Never directly reachable from the browser.

mariadb

MariaDB 11.4

3306 (internal only)

Persistent storage for all application data. Both users and game share the same users_db database instance.

prometheus

Prometheus

9090

Metrics collection. Scrapes the /metrics endpoint exposed by the users service.

grafana

Grafana

9091 (host) → 3000 (container)

Metrics visualisation dashboards, pre-provisioned via the users/monitoring/grafana directory.

7.3. Network and Connectivity

The Virtual Machine is configured with a public IP and specific inbound port rules:

  • Port 80 / 443: Public HTTPS access, handled by Nginx inside the webapp container. Nginx proxies all API traffic to the internal services:

    • /users/users service on port 3000

    • /game/game service on port 5000

    • /grafana → Grafana on port 3000 (container-internal)

    • /prometheus → Prometheus on port 9090

  • Port 9090: Direct access to Prometheus metrics (restricted in production).

  • Port 9091: Direct access to Grafana dashboards (restricted in production).

  • Port 22: SSH access, restricted to the CI/CD deployment pipeline.

  • Ports 3000, 4000, 5000, 3306: Internal to the Docker network (monitor-net); not publicly routed.

7.4. Deployment Pipeline (CI/CD)

The system uses GitHub Actions for continuous delivery. The pipeline is triggered automatically when a new release is created or a version tag is pushed to the repository.

CI/CD Pipeline
  1. Automation: Workflow configuration is stored as YAML files in .github/workflows.

  2. Build and Test: Docker images are built for all services; unit, integration, and SonarCloud quality-gate checks are executed.

  3. Artifact Management: Docker images are pushed to the GitHub Container Registry (GHCR) under the ghcr.io/arquisoft/yovi_en2b-* namespace.

  4. Deployment: GitHub Actions SSHs into the Azure VM and executes docker compose pull && docker compose up -d to update all running containers with the latest images.

  5. Secrets Management: Sensitive values (SSH keys, DB passwords, JWT secret, MariaDB credentials) are stored as GitHub Actions Secrets and injected as environment variables at runtime; they are never committed to the repository or baked into images.

7.4.1. Documentation Deployment

Following the "Documentation as Code" principle, the arc42 documentation is automatically built and published.

  1. Automation: A dedicated GitHub Action tracks changes in the docs/ directory.

  2. Build Process: The action runs npm install and npm run build, generating an HTML version from the AsciiDoc source files using Asciidoctor with diagram support.

  3. Publication: The build artefact is pushed to the gh-pages branch via the gh-pages npm package and served via GitHub Pages.

8. Cross-cutting Concepts

Content

This section describes overall, principal regulations and solution ideas that are relevant in multiple parts (= cross-cutting) of your system. Such concepts are often related to multiple building blocks. They can include many different topics, such as

  • models, especially domain models

  • architecture or design patterns

  • rules for using specific technology

  • principal, often technical decisions of an overarching (= cross-cutting) nature

  • implementation rules

Motivation

Concepts form the basis for conceptual integrity (consistency, homogeneity) of the architecture. Thus, they are an important contribution to achieve inner qualities of your system.

Some of these concepts cannot be assigned to individual building blocks, e.g. security or safety.

Form

The form can be varied:

  • concept papers with any kind of structure

  • cross-cutting model excerpts or scenarios using notations of the architecture views

  • sample implementations, especially for technical concepts

  • reference to typical usage of standard frameworks (e.g. using Hibernate for object/relational mapping)

Structure

A potential (but not mandatory) structure for this section could be:

  • Domain concepts

  • User Experience concepts (UX)

  • Safety and security concepts

  • Architecture and design patterns

  • "Under-the-hood"

  • development concepts

  • operational concepts

Note: it might be difficult to assign individual concepts to one specific topic on this list.

Possible topics for crosscutting concepts
Further Information

See Concepts in the arc42 documentation.

8.1. YEN — Game State Format

Purpose

A shared format for representing a Game Y board at a specific point in time. Used as the data contract between the game service and gamey.

Format

The game state is encoded as JSON following YEN notation.

Example:
{
  "size": 4,
  "turn": "R",
  "players": [ "B", "R" ],
  "layout": "B/.B/RB./B..R"
}
Rules
  • size: integer greater than 0.

  • turn: must be one of the player IDs listed in players.

  • players: list of player identifiers (currently "B" and "R").

  • layout: board encoded as a string; / separates rows, . marks an empty cell.

  • Invalid states are rejected with a 4xx error.

Compatibility
  • One version of the API is published. Any breaking change must be reflected in the documentation and contract tests.

8.2. REST Conventions

Scope
  • Browser → users service (authentication, stats, ranking)

  • Browser → game service (game sessions and moves)

  • game service → gamey (bot move requests, internal only)

Conventions
  • JSON is the default payload format.

  • HTTP status codes: 2xx for success, 4xx for client errors, 5xx for server errors.

  • Calls from game to gamey must use finite timeouts.

  • Non-idempotent operations are not retried automatically.

  • Recommended headers: Content-Type: application/json, Accept: application/json.

8.3. Authentication

Scope

All endpoints exposed by users (registration, login, profile) and game (game sessions and moves).

How it works
  • users issues JWTs signed with HS256. Clients send them as Authorization: Bearer <token>.

  • game and users share the same secret key and verify tokens locally — no inter-service call is made per request.

  • game endpoints use optional authentication: requests without a token are accepted as guest sessions; requests with an invalid or expired token are rejected with 401.

Authorization
  • Role-based: player and admin. A user can only read or modify their own data by default.

8.4. Service Routing and Orchestration

How requests flow
  • Nginx is the single public entry point. It routes requests by path prefix: /users/ → users service, /game/ → game service, / → SPA static files.

  • The game service is the only component that calls gamey. The browser never reaches the bot engine directly, and its port is not exposed through Nginx.

  • This keeps game logic and bot calls on the server side, preventing clients from interfering with game state.

8.5. Development Workflow

Rules
  • Short-lived branches merged into master via Pull Request.

  • Each PR requires at least one human approval and a passing CI run before merging.

  • PRs are merged using squash merge to keep a linear history.

  • No feature flags — changes go straight to master once approved.

8.6. User Experience (UX)

Goals
  • Players should be able to start a game with as little friction as possible.

  • The UI must give clear feedback at every step, especially when waiting for the bot.

Key principles
  • Guest-first access — Players can start a game without registering. An account is only required to save match history and appear in the ranking. This lowers the barrier to try the game.

  • Server-authoritative rendering — The board state shown to the player always comes from the server. The UI does not maintain its own copy of the game logic; it only renders what the game service returns. This keeps the frontend simple and prevents the display from going out of sync.

  • Visible bot feedback — When the bot is computing a move (which can take up to 3 seconds on large boards), the UI shows a "thinking…" indicator. The player cannot interact with the board during this time. This avoids confusion about whether the game is frozen.

  • Accessible components — UI primitives are built with Radix UI, which provides keyboard navigation and screen-reader support out of the box.

8.7. Configuration and Secrets

Rules
  • All environment-specific configuration is injected via environment variables (Docker Compose locally, GitHub Secrets in CI).

  • Sensitive values (JWT key, database password) are never committed to the repository and never baked into container images. Local development uses a gitignored .env file.

  • Secrets must never appear in logs.

9. Architecture Decisions

Contents

Important, expensive, large scale or risky architecture decisions including rationales. With "decisions" we mean selecting one alternative based on given criteria.

Please use your judgement to decide whether an architectural decision should be documented here in this central section or whether you better document it locally (e.g. within the white box template of one building block).

Avoid redundancy. Refer to section 4, where you already captured the most important decisions of your architecture.

Motivation

Stakeholders of your system should be able to comprehend and retrace your decisions.

Form

Various options:

  • ADR (Documenting Architecture Decisions) for every important decision

  • List or table, ordered by importance and consequences or:

  • more detailed in form of separate sections per decision

Further Information

See Architecture Decisions in the arc42 documentation. There you will find links and examples about ADR.

9.1. ADR-001: Dedicated game service owns all session state

Field Description

Status

APPROVED

Context

Game session state (board, turns, moves, timers) must live on the server to prevent cheating and keep the browser thin. We needed to decide which component owns this state.

Decision

A dedicated game service owns all game session state. It validates moves, calls gamey for bot moves, and writes match results to the users service when a game ends. The browser only renders what the server returns.

Consequences

Clear ownership of game logic; the browser cannot modify game state directly. Adding game features means touching the game service, not the frontend.

9.2. ADR-002: Nginx as single public entry point with path-based routing

Field Description

Status

APPROVED

Context

The system has two backend services and a frontend SPA. Clients need a single address to reach all of them.

Decision

Nginx routes requests by path prefix: /users/ → users service, /game/ → game service, / → SPA static files. The bot engine port (4000) is never exposed through Nginx.

Consequences

One public entry point with simple routing rules. The bot engine stays internal. Adding a new service requires a new Nginx route.

9.3. ADR-003: Shared JWT secret with local token verification

Field Description

Status

APPROVED

Context

Both game and users need to verify user identity. Calling users on every authenticated request adds latency and a runtime dependency.

Decision

game and users share the same JWT_SECRET and verify tokens locally using the same algorithm (HS256). No inter-service call is made per request.

Consequences

No extra round-trip for authentication. The shared secret must be identical across both services and kept confidential.

9.4. ADR-004: One MariaDB instance with strict table ownership per service

Field Description

Status

APPROVED

Context

Both services need persistent storage. Running two separate database instances adds operational overhead for an academic project.

Decision

Both services connect to the same MariaDB instance (users_db). Table ownership is strict: users and match_records belong to the users service; games and game_moves belong to the game service. Neither service queries the other’s tables directly.

Consequences

One database container to manage. The services remain logically independent as long as table boundaries are respected.

9.5. ADR-005: Stateless bot engine (gamey)

Field Description

Status

APPROVED

Context

The bot only needs the current board position to compute a move. Storing session state in the Rust service would complicate deployment and testing.

Decision

gamey is stateless. Each request carries the full board state in YEN format; the engine computes one move and discards the state.

Consequences

Simple deployment and testing for the Rust service. The game service is responsible for sending the full board on every bot request.

9.6. ADR-006: HS256 for JWT signing

Field Description

Status

APPROVED

Context

users issues tokens and game verifies them. A signing algorithm must be chosen.

Decision

Use HMAC-SHA256 (HS256) with a shared secret for JWT signing and verification.

Consequences

Simple setup and fast verification. Asymmetric keys are not needed since both services are internal and controlled by the same team.

9.7. ADR-007: Secrets and configuration via environment variables

Field Description

Status

APPROVED

Context

Sensitive values (JWT key, database password) must not be stored in the repository or baked into container images.

Decision

All sensitive configuration is injected at runtime via environment variables. Locally, a gitignored .env file is used. In CI and production, values come from GitHub Secrets.

Consequences

Secrets never enter version control. Developers must copy .env.example to get started locally.

10. Quality Requirements

Content

This section contains all quality requirements as quality tree with scenarios. The most important ones have already been described in section 1.2. (quality goals)

Here you can also capture quality requirements with lesser priority, which will not create high risks when they are not fully achieved.

Motivation

Since quality requirements will have a lot of influence on architectural decisions you should know for every stakeholder what is really important to them, concrete and measurable.

Further Information

See Quality Requirements in the arc42 documentation.

10.1. Quality Tree

Content

The quality tree (as defined in ATAM – Architecture Tradeoff Analysis Method) with quality/evaluation scenarios as leafs.

Motivation

The tree structure with priorities provides an overview for a sometimes large number of quality requirements.

Form

The quality tree is a high-level overview of the quality goals and requirements:

  • tree-like refinement of the term "quality". Use "quality" or "usefulness" as a root

  • a mind map with quality categories as main branches

In any case the tree should include links to the scenarios of the following section.

quality tree horizontal

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.

This section makes quality requirements concrete through a quality tree and measurable scenarios, referencing the quality goals defined in section 1.2 Quality Goals where applicable. The quality-attribute taxonomy follows ISO/IEC 25010. Scenarios make quality requirements precise by stating stimulus, response, and measurable criteria.

ID Type Stimulus Response Measure / Acceptance criteria

QS-01 (Fast start)

Usage

A new player accesses the application for the first time.

They can register, log in, and start a game against the bot.

Completes the flow in < 30 s without needing instructions (quality goal 1).

QS-02 (Playable UI)

Usage

A player starts a game and makes a move.

The UI reflects the new state without noticeable delay.

Main interaction (render + confirmation) does not exceed 500 ms on the client (TBD: to be measured).

QS-03 (API latency — no bot)

Usage

A standard request to the Node.js backend (e.g., login, profile) that does not involve the bot engine.

The system responds with the result.

p95 ⇐ 50 ms for ~10 concurrent users (internal target).

QS-04 (Bot engine health check)

Usage

The game service calls the bot engine health-check endpoint.

It receives a status response and can disable bot features if the engine is down.

p95 ⇐ 50 ms.

QS-05 (Bot move latency by board size)

Usage

A player requests the next bot move (random strategy or minimax with alpha-beta pruning).

The service returns a valid move.

  • "Hard" difficulty (board size 4–12): p95 ⇐ 500 ms (quality goal 2).

  • "Hard" difficulty (board size 13–16): p95 ⇐ 3000 ms; the UI shows a "thinking…" indicator without blocking the session.

  • Note: thresholds will be validated with real measurements.

QS-06 (Add bot strategy in 1 day)

Change

A new bot strategy or difficulty level is added to the Rust module.

The feature is integrated without breaking the frontend or API contracts.

Effort ⇐ 1 work day; the /v1/ybot/choose/{bot_id} endpoint contract remains compatible (quality goal 3).

QS-07 (Extend board size)

Change

Board-size support is extended within the allowed range.

The change does not require rewriting the UI or the persistence layer.

Changes are localized and tests are updated; the YEN format is not broken.

QS-08 (Persist match result)

Usage

A game ends and the result is saved to the database.

The result is persisted and appears in the user’s history.

99% of save operations succeed (quality goal 4); on failure, an explicit error is returned and no match is falsely confirmed as saved.

QS-09 (Recovery after restart)

Usage

The server restarts unexpectedly.

The system comes back online and retains previously persisted data.

Service recovers after restart (TBD: ⇐ 5 min); live sessions in progress may be lost, but finished match records are kept.

QS-10 (Authenticated score submission)

Usage

An unauthenticated client tries to submit a match result or access private data.

The backend rejects the request.

Only authenticated users can submit results linked to their own account (quality goal 5).

QS-11 (Score spoofing)

Usage

An authenticated user attempts to submit a result without having played, or sends a manipulated game state to obtain an illegitimate score.

The game service validates the state server-side and rejects the operation.

Both spoofing scenarios are prevented (quality goal 5).

QS-12 (Abuse / rate limiting)

Usage

A client attempts brute force or spam against the users service endpoints.

The system limits and logs the requests.

Rate limiting is enabled (TBD: thresholds per IP/user) and security events are logged.

QS-13 (Documented external API)

Usage

A third party builds a bot using the public interoperability API.

They can integrate without reverse engineering the system.

The API is fully documented (OpenAPI/Swagger with examples) as required by the assignment.

QS-14 (Observability)

Usage

An error occurs during a match or latency increases.

The team can diagnose the issue using metrics and logs.

Basic metrics (p95 latencies, error rate, bot engine health) are available; logs include a correlation ID (TBD implementation).

QS-15 (Architecture documentation quality)

Change

The team reviews the architecture and its decisions.

They can trace decisions and quality attributes without ambiguity.

Complete arc42 documentation with relevant ADRs recorded per evaluation criteria.

11. Risks and Technical Debts

Contents

A list of identified technical risks or technical debts, ordered by priority

Motivation

"Risk management is project management for grown-ups" (Tim Lister, Atlantic Systems Guild.)

This should be your motto for systematic detection and evaluation of risks and technical debts in the architecture, which will be needed by management stakeholders (e.g. project managers, product owners) as part of the overall risk analysis and measurement planning.

Form

List of risks and/or technical debts, probably including suggested measures to minimize, mitigate or avoid risks or reduce technical debts.

Further Information

See Risks and Technical Debt in the arc42 documentation.

This section lists identified technical risks and technical debts, ordered by priority.

11.1. Technical Risks

ID Priority Impact Mitigation

R-01 (Minimax does not scale beyond board size 11)

HIGH

The current minimax implementation (alpha-beta pruning + iterative deepening) cannot handle boards of size 11+ within acceptable time limits, which restricts the variable board size requirement.

  • Option A: Cap maximum board size at 10 for "Hard" difficulty.

  • Option B: Optimize the algorithm (transposition tables, better move ordering) or reduce search depth for larger boards.

  • Option C: Add a time-limit cutoff and return the best move found so far; show a "thinking…" indicator to the user.

R-02 (Bot engine failure blocks PvE games)

HIGH

If gamey becomes unavailable, players cannot continue games against the bot. Note: win detection runs in the game service (Node.js), so it is not affected by this failure.

  • Implement graceful degradation: switch to a local two-player mode with a clear message ("Bot unavailable; switching to local multiplayer").

  • Add health-check monitoring to detect and alert when gamey is down.

R-03 (WebSocket integration is unproven)

HIGH

The team has not yet implemented WebSocket support for real-time online multiplayer. Lack of experience increases the risk of bugs or incomplete implementation.

  • Prototype WebSocket basics early (by sprint N, TBD).

  • Allocate extra time for debugging connection and state-sync issues.

  • If not ready in time, online multiplayer can be deferred; player-vs-bot and local multiplayer remain functional.

R-04 (Limited observability in production)

HIGH

Without structured logs and metrics, diagnosing problems on the deployed server is difficult and slow.

  • Add structured logging with a correlation ID (request tracing across Node and Rust).

  • Expose basic metrics (error rate, p95 latencies, bot engine health) via Prometheus and Grafana.

  • Address this before final deployment.

R-05 (Team inexperience with the stack)

MEDIUM

The team is relatively new to some parts of the stack (React, Node.js, Rust), which may slow development and increase the bug rate.

  • The academic schedule allows time for learning.

  • Code reviews and pair programming help spread knowledge across the team.

  • SonarQube enforces quality standards and catches common mistakes early (see TD-01).

R-06 (Scope creep from optional features)

MEDIUM

The assignment includes many optional features (game variants, i18n, mobile, undo, hints, etc.). Taking on too many risks overcommitment.

  • Lock scope early: prioritize one or two optional features aligned with grading criteria (e.g., leaderboard).

  • Do not start optional features until the core requirements (player-vs-bot, API, user management) are stable and tested.

R-07 (Documentation has open TBD sections)

MEDIUM

Some documentation sections still contain TBD placeholders, which may affect the final evaluation.

  • Schedule a documentation review before final delivery.

  • Assign an owner to each open TBD to ensure it gets closed.

11.2. Technical Debt

ID Debt Impact / Plan

TD-01 (SonarQube slows development)

Quality gates are enabled and catch issues early, but they add overhead to the development workflow.

  • Impact: Reduced short-term velocity, higher long-term code quality.

  • Plan: Accept the trade-off. SonarQube prevents worse debt from accumulating (poor code, security issues). Thresholds can be adjusted if they become unreasonably strict for the project scope.

TD-02 (interop service not connected in docker-compose)

The interop service (required by the assignment for bot interoperability) is implemented and tested but not wired into docker-compose.yml. It cannot be reached in the current deployment.

  • Impact: The interoperability requirement is not met in production until this is enabled.

  • Plan: Add the interop service to docker-compose.yml before final delivery. The required configuration is documented in section 5.

TD-03 (pvp-online mode not implemented)

The online multiplayer mode (pvp-online) is defined in the type system and reserved in the game service, but the matching logic and real-time synchronization are not implemented.

  • Impact: Online multiplayer is unavailable. Player-vs-bot and local multiplayer are not affected.

  • Plan: Implement once WebSocket infrastructure is in place (linked to R-03). Treat as a separate delivery.

12. Glossary

Contents

The most important domain and technical terms that your stakeholders use when discussing the system.

You can also see the glossary as source for translations if you work in multi-language teams.

Motivation

You should clearly define your terms, so that all stakeholders

  • have an identical understanding of these terms

  • do not use synonyms and homonyms

Form

A table with columns <Term> and <Definition>.

Further Information

See Glossary in the arc42 documentation.

Term Definition

YOVI

System name: a web-based platform to play Game Y through a browser and public APIs.

Game Y

The board game implemented by the system: players compete to connect three sides of a triangular board.

Micrati

Company behind the project in the assignment context (project sponsor).

SPA (Single-Page Application)

Web application that loads once and updates the UI dynamically by calling backend APIs.

Web Frontend

Browser-based TypeScript SPA that renders the board and interacts with backend services via HTTP.

users (service)

Service responsible for authentication and user management. Exposes the public User API (register, login, profile, stats, ranking) and persists user data in MariaDB.

game (service)

Service responsible for all game session logic. It validates moves, manages board state, calls gamey for bot moves, and writes match results to the users service when a game ends.

gamey (Rust engine)

Internal Rust service that computes bot moves. Accepts a board position in YEN format and returns one move. Invoked only by the game service — never directly by the browser.

interop (service)

Standalone service that exposes a public API allowing external bots or clients to play against the bot engine. Required by the assignment for interoperability with other teams. Implemented but not yet connected in docker-compose.yml.

User API

Public HTTP API for user management (register, login, profile, history) provided by the users service.

Game API

Public HTTP API for game interaction (create session, play moves, surrender) provided by the game service.

YEN

Notation for representing a Game Y board state: includes board size, current player turn, player identifiers, and the board layout.

YEN/JSON game state

A JSON payload encoding a game state in YEN format. Invalid states are rejected by the engine.

JSON

Default payload format used in all API and service-to-service communication.

REST

HTTP-based request/response style used across all services in the system.

WebSocket

Bidirectional communication channel planned for real-time online multiplayer.

JWT (JSON Web Token)

Token format used for authentication. Clients send it in the Authorization: Bearer <token> header.

HS256

HMAC-SHA256 algorithm used to sign and verify JWTs using a shared secret key.

Authentication

The process of verifying who a user is. Handled by the users service via JWT issuance; verified locally by both users and game.

Authorization

The process of deciding what a user is allowed to do. Implemented as role-based checks (player / admin).

MariaDB

Relational database used by both the users and game services to persist data (user accounts, match records, game sessions, and move history).

ADR (Architecture Decision Record)

Short document describing an important architectural decision, its context, and its consequences.

arc42

Software architecture documentation template used to structure this documentation (sections 1–12).

M1

First project milestone, focused on delivering end-to-end functionality.

Error envelope

Standard JSON structure for error responses, using errorCode, message, and requestId fields.

requestId

Identifier included in error responses to help correlate client-visible failures with server-side logs.