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.
1. Introduction and Goals
1.1. Requirements Overview
The YOVI_EN1B project represents an evolving multi service platform developed for the Software Architecture course at the University of Oviedo. It serves as a fundamental benchmark for the construction of scalable, maintainable, and observable distributed systems, with a specific focus on turn based game logic.
The following context diagram illustrates the primary boundaries of the system and its interactions with external actors and infrastructure:
The functional scope encompasses several critical architectural domains:
-
User Identity Management: A centralized system for registration and authentication, providing secure access to the platform ecosystem. This component ensures the integrity of user credentials and session management.
-
Hexagonal Game Logic Engine: A high performance application core, implemented in Rust, that governs spatial operations on a triangular board consisting of hexagonal cells. This includes move validation based on spatial adjacency, distributed state synchronization, and win condition detection via specialized graph traversal algorithms such as Depth First Search.
-
State Persistence and Resilience: Integration with MongoDB to ensure that all game sessions are preserved. This mechanism enables the system to survive service interruptions and allows participants to resume active sessions without loss of progress. It is a critical component for maintaining system availability and reliability.
-
Operational Intelligence: A comprehensive monitoring infrastructure using Prometheus and Grafana to provide real time visibility into system health and performance metrics. This allows for automated alerting and detailed analysis of system behavior under load.
1.2. Quality Goals
The architecture of YOVI_EN1B is governed by a technical quality tree rooted in the ISO 25010 standard. These high priority requirements ensure the technical integrity and operational success of the platform:
| Priority | Goal | Architectural Attribute | Operational Scenario |
|---|---|---|---|
1 |
Maintainability |
Modularity |
The system architecture facilitates the replacement of individual components, such as the user service, without necessitating modifications to the web application or the game engine core. This decoupling ensures long term project sustainability. |
2 |
Reliability |
Fault Tolerance |
The persistence layer ensures that in the event of a service restart, the complete game state is recovered from the database within two seconds, ensuring zero data loss for active sessions. |
3 |
Performance |
Efficiency |
The core game logic executes spatial analysis and win condition detection in under two milliseconds. This performance target must be maintained even as the triangular grid size increases, ensuring immediate system response times. |
4 |
Security |
Data Integrity |
The platform enforces strict validation of all incoming requests to prevent unauthorized actions. Every transaction is recorded to maintain a full audit trail for accountability and evaluation purposes. |
5 |
Usability |
Accessibility |
The user interface provides immediate clarity regarding system state and gameplay progression. It adheres to modern standards to ensure that the complex hexagonal grid remains intuitive for all users. |
1.3. Stakeholders
The following individuals have a significant interest in the architectural success and technical implementation of the YOVI_EN1B system:
| Role or Name | Contact | Job Definition |
|---|---|---|
Jose Emilio Labra Gayo |
University of Oviedo |
Investor 1 |
Pablo Gonzalez |
University of Oviedo |
Investor 2 |
Diego Martín Fernández |
University of Oviedo |
Investor 3 |
Celia Melendi Lavandera |
University of Oviedo |
Investor 4 |
bilalyazicioglu |
University of Oviedo |
GameY(Rust) Developer |
UO300896 |
University of Oviedo |
Database Engineer |
Th0be |
University of Oviedo |
Frontend Developer |
nacho50900 |
University of Oviedo |
Backend Developer |
2. Architecture Constraints
2.1. Technical Constraints
| Constraint ID | Constraint | Impact | Rationale |
|---|---|---|---|
TC-01 |
Mandatory Tech Stack |
Web application must use TypeScript; core game logic (move validation/generation) must be in Rust. |
Requirement defined by the ASW course to practice polyglot development and language interoperability. |
TC-02 |
Communication Protocol |
Subsystems must communicate via JSON messages. |
Standardizes data exchange between the TypeScript frontend and the Rust backend service. |
TC-03 |
Game Representation (YEN) |
All game states and moves must be represented using the YEN notation. |
Ensures consistency in how the Game Y board is serialized and stored across the system. |
TC-04 |
Architecture Decomposition |
System must be split into at least two subsystems: Web Application and Rust-based web service. |
Encourages modularity and demonstrates the ability to integrate different architectural components. |
TC-05 |
External API |
The system must expose a documented API for third-party bots. |
Facilitates extensibility and allows the game to be played by automated agents. |
TC-06 |
Public Deployment |
The application must be accessible via a public URL. |
Demonstrates the ability to manage cloud deployment and production environments. |
2.2. Organizational Constraints
| Constraint ID | Constraint | Impact | Rationale |
|---|---|---|---|
OC-01 |
Version Control |
All source code and documentation must be hosted in the assigned GitHub repository (Arquisoft/yovi_en1b). |
Enables collaborative development and allows instructors to track progress and contributions. |
OC-02 |
Automated CI/CD |
Deployment and testing must be automated using CI/CD pipelines (e.g., GitHub Actions). |
Ensures software quality and rapid feedback loops throughout the development lifecycle. |
OC-03 |
Documentation Standards |
Use of the arc42 template and ADRs (Architectural Decision Records) is mandatory. |
Provides a standardized structure for architectural documentation and history of key decisions. |
2.3. Conventions
| Constraint ID | Constraint | Impact | Rationale |
|---|---|---|---|
C-01 |
Testing Requirements |
Mandatory inclusion of Unit, Integration, E2E, and Load tests. |
Critical for verifying system reliability and performance under stress. |
C-02 |
AI Strategy Options |
The AI must offer at least two different strategies or difficulty levels. |
Enhances user experience and demonstrates implementation of different algorithmic approaches. |
C-03 |
Language |
All documentation and code comments should be in English. |
Standard practice in software engineering. |
3. Context and Scope
This section delimits the GameY system from all its external communication partners. It defines the boundaries and the interfaces between our system and its environment, both from a business/domain perspective and a technical perspective.
3.1. Business Context
The business context focuses on the external entities (actors) that interact with the GameY system from a functional point of view, ignoring technical details.
Explanation of external domain interfaces:
| Communication Partner | Inputs (to the System) | Outputs (from the System) |
|---|---|---|
User / Player |
Username for registration (RegisterForm), game actions. |
Welcome messages, UI rendering. |
3.2. Technical Context
This section describes the technical interfaces, channels, and transmission media linking the GameY system to its environment. Based on the docker-compose configuration, the project is divided into a frontend application (webapp), a backend for user handling (users), and a game engine (gamey).
Mapping Input/Output to Channels:
| Communication Partner | I/O | Channel / Protocol |
|---|---|---|
User (Client Device) |
UI interactions, form submissions (e.g., sending username). |
HTTP for fetching the SPA from the webapp service (Port 80). Once loaded, the browser communicates via HTTP POST with the users service API (/createuser on Port 3000) and the gamey engine (Port 4000). |
4. Solution Strategy
The GameY project follows a layered structured divided into UI, game logic and backend user handling
4.1. Technology decisions
-
The UI will be develop using React, due to one of the members already knowing it; Vite and TypeScript due to constraints
-
The logic will consist of a Rust application due to constraints
-
The users will be handle by a MongoDB database because we believe it is a very powerful database and would be great to know for our careers.
-
Github will be used as the cloud platform to work due to constraints
-
Docker will be used to deploy the application due to constraints
4.2. Quality goals
-
Maintainability of the code is achieved through the architectural pattern chosen to split different sections of the project
-
Reliability again is achieved through the layered structure, as the persistence layer with the database ensures it
-
Security will be handled through strict user validation during the login
-
Usability will be achieved through the clear implementation of the user interface and a variety of options to choose from when playing
5. Building Block View
This section describes the decomposition of the GameY system into its principal building blocks, showing their internal structure and relationships. The system is detailed across two levels: Level 1 shows the overall system components, and Level 2 zooms into the internal structure of each specific component.
5.1. Whitebox Overall System (Level 1)
Here we describe the decomposition of the overall GameY system.
Overview Diagram
Motivation
The system is decomposed into three main building blocks to separate concerns: * The user interface (frontend) is isolated to provide a responsive SPA (Single Page Application). * The user handling is separated into its own microservice to independently manage registrations and user logic. * The game logic is encapsulated in a high-performance Rust engine, ensuring fast execution for bot AI and game state validation.
Contained Building Blocks
| Name | Responsibility |
|---|---|
webapp |
Frontend web application. Renders the user interface, handles form submissions (like RegisterForm), and communicates with backend services to display data. |
users |
Backend REST API service. Currently responsible for handling user registration requests and returning welcome messages. |
gamey |
Core game engine and bot service. Responsible for managing the game state, board coordinates, valid actions, notations, and bot logic. |
5.2. Level 2
This level zooms into the internal structure of the three main building blocks defined in Level 1.
5.2.1. Whitebox: webapp
Overview Diagram
Contained Building Blocks
| Name | Responsibility |
|---|---|
App.tsx |
The root React component that serves as the entry point for the frontend application. |
RegisterForm.tsx |
A specific UI component that renders the registration form, captures user input (username), and sends the HTTP POST request to the users service API. |
5.2.2. Whitebox: users
Overview Diagram
Contained Building Blocks
| Name | Responsibility |
|---|---|
users-service.js |
The main Express server file. It defines the API endpoints, specifically the /createuser route. It currently simulates a database delay (1000ms) and processes the JSON response sent back to the client. |
5.2.3. Whitebox: gamey
Overview Diagram
Contained Building Blocks
| Name | Responsibility |
|---|---|
main.rs / lib.rs |
Entry point and library exports for the Rust application. It initializes the engine (e.g., HTTP server mode on Port 4000). |
web |
Manages the web interface components and server routing. |
core |
Contains the core game logic, including actions, coordinates, game state, and player management. |
bot |
Implements the bot registry and automated player logic. |
notation |
Provides parsers and support for game notation formats (YEN, YGN). |
6. Runtime View
Here are the main runtime scenarios that demonstrate how YOVI’s components interact during gameplay.
The system consists of three components:
-
Frontend (FE) — React + Vite, runs on port 80
-
Users Service (USERS) — Node.js + Express + MongoDB, runs on port 3000
-
Gamey Logic (GAMEY) — Rust game engine, runs on port 4000
6.1. Scenario 1: User Registration and Login
Notable aspects:
-
Passwords are never stored in plain text — bcrypt with salt rounds 10
-
JWT token expires after 24 hours and must be sent as
Authorization: Bearer <token>on all protected requests -
Username uniqueness is enforced at DB level (unique index)
6.2. Scenario 2: Player vs Player Game
Notable aspects:
-
Starting turn (B or R) is randomly assigned using
crypto.randomInt— cryptographically secure -
Player field in each move is inferred from
current_turn— frontend does not send it -
yen_stateper move is computed by Gamey’s/computeendpoint, not by the frontend or backend -
Gamey returns a
winnerfield after every/computecall — see Scenario 4 for win detection details -
DRAW result (user quit) does not update statistics
6.3. Scenario 3: Player vs Bot Game
Notable aspects:
-
The backend acts as a proxy between the frontend and Gamey — the frontend never calls Gamey directly
-
POST /compute— Gamey receives{ yen_state_prev, coordinates }and returns{ yen_state, winner } -
POST /play— Gamey receives{ yen_state, strategy, difficulty_level, board_size }and returns{ coordinates, yen_state, winner } -
Both endpoints return a
winnerfield — see Scenario 4 for win detection details -
Bot move is saved automatically in the DB by the Users Service — frontend does not need to call
POST /games/:id/movefor the bot -
If it is the first move,
yen_state_prev/yen_stateis sent asnulland Gamey generates the initial board state fromboard_size
6.4. Scenario 4: Win Detection
Notable aspects:
-
Win detection is fully handled by Gamey — the Users Service only reacts to the
winnerfield -
The backend calls
autoFinishIfWinnerafter every move (both player and bot) — ifwinneris not null, the game is finished and statistics updated automatically -
winner: "B"→ human player wins → result isWIN;winner: "R"→ bot wins → result isLOSS -
Duration is calculated automatically from
game.created_atwhen auto-finishing
6.5. Scenario 5: Game Replay
Notable aspects:
-
Each move stores its resulting
yen_state, so the frontend can reconstruct the board at any point in time -
History endpoint excludes the moves array for a lighter response — full moves are fetched separately via
GET /games/:id/moves
7. Deployment View
7.1. Infrastructure Level 1
- Motivation
-
Game Y uses Docker Compose to orchestrate four independent containers: the
webapp(React frontend), theusersservice (Node.js/Express user management API), thegameyservice (Rust game engine), and amongodbcontainer for persistent storage. This separation ensures that each service can be developed, built, and scaled independently. MongoDB is the chosen database because its document-oriented model fits naturally with the variable structure of game states and move histories, and it integrates well with the Node.js ecosystem.
Only the users service connects to MongoDB. This is a deliberate architectural decision: gamey manages active game state in memory during a match (which is sufficient for its role as a pure game engine), and once a game ends the result is sent to the users service, which is responsible for all persistence — player accounts, statistics, and game history. This avoids two services competing to write to the same database and keeps data ownership clear.
- Quality and/or Performance Features
-
-
Isolation: Each service runs in its own Docker container, preventing dependency conflicts and simplifying upgrades.
-
Portability:
docker-compose up --buildreproduces the full environment on any machine with Docker installed. -
Independent scaling: The
gameyandusersservices can be scaled individually based on load without affecting the frontend. -
Clear interface boundaries: Services communicate only via HTTP REST, making the contracts explicit and testable.
-
Development efficiency: Docker Compose orchestrates the full local setup with a single command; no manual service wiring is required.
-
- Mapping of Building Blocks to Infrastructure
| Building Block | Container | Technology | Exposed Port | Connects to |
|---|---|---|---|---|
User Interface |
Webapp Container |
React + TypeScript + Vite |
80 |
Users (3000), Gamey (4000) |
User Management & Persistence |
Users Container |
Node.js + Express |
3000 |
MongoDB (27017) |
Game Logic & Bot |
Gamey Container |
Rust (Cargo) |
4000 |
— |
Persistent Storage |
MongoDB Container |
MongoDB 7 |
27017 (internal) |
— |
7.1.1. Container Descriptions
Webapp Container — Serves the React single-page application to the browser. It is the only container directly accessible from outside the Docker network. It talks to the users service for everything related to the player (registration, login, stats, history) and to the gamey service for all game actions (creating a game, submitting a move, querying board state).
Users Container — Manages player accounts, authentication, statistics, and game history. It is the only service that connects to MongoDB, acting as the single gateway for all persistent data. When a game finishes, the result is reported here so it can be stored and reflected in player stats.
Gamey Container — A pure game engine written in Rust. It handles game creation, move validation, win condition checking, and bot moves entirely in memory. It has no database connection; active game state lives in memory for the duration of a match. Once the game ends, the result is communicated back to the frontend, which then reports it to the users service.
MongoDB Container — Provides persistent NoSQL storage exclusively for the users service. It runs as a Docker container within the same Compose network, so it is not directly accessible from outside.
7.2. Infrastructure Level 2
7.2.1. Gamey Container
The Gamey container runs the Rust application that implements the full game logic for Game Y. Its internal components are:
-
Web Interface: Exposes HTTP endpoints on port 4000 that the React frontend calls to create games, submit moves, and query game state.
-
Game Engine (core): Contains the core data model — coordinates, board state, player management, and action dispatch. This is the authoritative source for game rules. Win condition checking is performed internally within the engine after every move, using a graph traversal (DFS/BFS) over the hexagonal grid to detect whether a player’s connected chain touches all three sides of the triangular board (see section 6 for the runtime scenario).
-
Bot Registry: Maintains a set of registered bot strategies. When a player chooses to play against the computer, the bot registry selects the appropriate bot and returns its move to the game engine.
-
Notation Parser: Supports YEN (Yovi Extended Notation) and YGN (Yovi Game Notation) for encoding and decoding move sequences. This enables game export, replay, and interoperability.
7.2.2. Users Container
The Users container is a lightweight Node.js/Express service. It exposes a REST endpoint (POST /createuser) that the React frontend calls during user registration. In the current implementation, user records are kept in-memory within the process; no external database is required. This service is designed to be replaced or extended with a persistent store in later development phases.
7.2.3. Webapp Container
The Webapp container serves the React single-page application compiled by Vite. It is served via a static file server on port 80. All game interactions are handled client-side in the browser, with REST calls made to the users service (port 3000) and the gamey service (port 4000). There is no server-side rendering; the container’s only role is to deliver the compiled JavaScript and assets to the browser.
7.2.4. MongoDB Container
The MongoDB container is exclusively used by the users service. It holds two collections:
-
players: User accounts, hashed credentials, and per-player statistics (wins, losses, games played).
-
game_history: Archived completed games including the full sequence of moves, the result, and the participants. This allows the frontend to display match history and enables future replay functionality.
gamey does not connect to MongoDB. Active game state is kept in memory within the Rust process for the duration of a match, which is sufficient for its role as a game engine. When a game concludes, the frontend reports the result to the users service, which writes it to game_history.
The MongoDB port (27017) is only exposed internally within the Docker Compose network and is not reachable from outside the host machine.
The docker-compose entry for this container is:
mongodb:
image: mongo:7
volumes:
- mongo_data:/data/db
The named volume mongo_data ensures that data persists across container restarts. Note that the port is intentionally not published to the host — only the users container needs to reach it, and it can do so through the internal Docker network.
8. Cross-cutting Concepts
8.1. <Concept 1>
<explanation>
8.2. <Concept 2>
<explanation>
…
8.3. <Concept n>
<explanation>
9. Architecture Decisions
10. Quality Requirements
10.1. Quality Tree
10.2. Quality Scenarios
11. Risks and Technical Debts
12. Glossary
| Term | Definition |
|---|---|
<Term-1> |
<definition-1> |
<Term-2> |
<definition-2> |
