About arc42
arc42, the template for documentation of software and system architecture.
Template Version 8.2 EN. (based upon AsciiDoc version), Febrero 2026
Created, maintained and © by Dr. Peter Hruschka, Dr. Gernot Starke and contributors. See https://arc42.org.
1. Introducción y Objetivos
El proyecto yovi_es1b es una iniciativa llevada a cabo en la Universidad de Oviedo, dentro del marco de la asignatura de Ingeniería del Software. El propósito es desarrollar, integrar y desplegar una versión digital del juego de estrategia abstracta "Juego Y" (Game of Y).
El equipo comprometido con este desarrollo está formado por:
-
Diego Abeijon Rodriguez
-
Hugo Tejedor Arcoitza
-
Nahiara Sanchez Garcia
-
Eva Menéndez Hernández
-
Moisés Montes Iglesias
En la aplicación, los usuarios podrán jugar al "Juego Y" en dos modalidades principales: enfrentamiento contra otro jugador (local) o contra un Bot (IA), haciendo uso de un núcleo lógico preexistente.
1.1. Visión General de los Requisitos
La funcionalidad principal se basa en la integración de componentes y la correcta ejecución del juego.
-
Modos de Juego: Soporte para partidas Humano vs Humano y Humano vs Bot.
-
Integración del Núcleo: La aplicación utiliza una librería externa (Kernel) para la validación de movimientos y detección de victoria, asegurando que las reglas oficiales se cumplen estrictamente.
-
Interfaz de Usuario: Visualización clara del tablero triangular, permitiendo interactuar con las celdas para colocar fichas de manera intuitiva.
-
Despliegue y Ejecución: El sistema está configurado para iniciarse correctamente en los entornos de laboratorio, gestionando las dependencias necesarias automáticamente.
-
Ciclo de la Partida: Gestión completa del flujo de juego: inicio, turnos alternos, detección de fin de partida y opción de reinicio.
1.2. Objetivos de Calidad
Los objetivos de calidad se centran en la arquitectura de integración y la facilidad de puesta en marcha del software.
| Prioridad | Meta de Calidad | Escenario |
|---|---|---|
1 |
Desplegabilidad (Deployability) |
El proyecto debe poder clonarse y ejecutarse en los equipos del laboratorio con una configuración mínima, evitando errores de rutas o dependencias faltantes. |
2 |
Interoperabilidad |
La interfaz gráfica debe comunicarse con el núcleo lógico (backend/kernel) sin errores de formato, respetando la API proporcionada. |
3 |
Usabilidad |
Un jugador nuevo debe poder identificar fácilmente de quién es el turno, dónde puede colocar una ficha y si ha ganado o perdido, sin consultar un manual. |
4 |
Mantenibilidad |
La arquitectura debe separar claramente el código de la vista del código de la lógica, facilitando futuras actualizaciones del núcleo o cambios en la interfaz. |
1.3. Stakeholders
Personas y roles involucrados en el desarrollo y evaluación del sistema.
| Rol/Nombre | Contacto | Expectativas |
|---|---|---|
Equipo de desarrollo |
Diego Abeijon, Hugo Tejedor, Nahiara Sanchez, Eva Menéndez, Moisés Montes |
Integrar correctamente el sistema, documentar la arquitectura (arc42) y superar la evaluación de la asignatura mediante un despliegue exitoso. |
Usuarios Finales |
Jugadores del Juego Y |
Una experiencia de juego fluida, poder jugar contra la máquina o un amigo sin que la aplicación se cierre inesperadamente. |
Evaluadores (Profesores) |
Jose Emilio Labra Gayo, Pablo González, Irene Cid Rico, Diego Martín Fernández |
Verificar que el despliegue es reproducible, que se respeta la arquitectura propuesta y que la documentación refleja fielmente el sistema construido. |
2. Restricciones Arquitectónicas
En este apartado se describen los límites que condicionan las decisiones de diseño e implementación del equipo de desarrollo. Estos factores son innegociables y deben ser respatados por todo el equipo durante el desarrollo.
2.1. Restricciones Técnicas
| Restricción | Explicación |
|---|---|
Multilenguaje |
Obligación de usar TypeScript para la aplicación Web (Frontend/API) y Rust para el módulo de lógica de juego. |
Comunicación JSON/YEN |
El intercambio de datos entre los subsistemas debe realizarse exclusivamente mediante mensajes JSON, siguiendo la notación YEN. |
Contenerización |
El sistema debe administrarse mediante Docker, asegurando el funcionamiento en entornos aislados de ambos subsistemas (Web y Rust). |
Despliegue Web |
La aplicación debe ser accesible públicamente a través de una URL, es decir, debe estar desplegada en la nube. |
Interfaz de servicios |
El módulo Rust debe exponer una interfaz de servicio web básica para ser invocado por la aplicación principal. |
2.2. Restricciones Organizativas
| Restricción | Explicación |
|---|---|
Curva de aprendizaje |
El equipo debe adquirir competencias en Rust, Node.js y React de forma simultánea al desarrollo, ya que son tecnologías que no han empleado con anterioridad. |
Plazos |
Entrega sujeta al calendario establecido por la empresa de desarrollo de juegos Micrati. |
Criterios de Calidad |
Es obligatorio cumplir con niveles mínimos de cobertura de pruebas (Unitarias, Integración, E2E y Carga). |
2.3. Convenciones y Normas
| Restricción | Explicación |
|---|---|
Estándar arc42 |
La documentación técnica debe seguir la estructura y apartados del modelo arc42. |
Notación de Coordenadas |
El tablero de juego debe representarse mediante coordenadas baricéntricas (x, y, z) o índices secuenciales. |
Gestión de Git |
Uso obligatorio de issues, pull request con revisión de código y registro de decisiones arquitectónicas (ADR). |
Observabilidad |
El sistema debe incluir mecanismos de monitorización y disponibilidad. |
Wiki y Gestión de Equipo |
Se mantendrá una wiki en GitHub con las actas de las reuniones semanales realizadas por el equipo de desarrollo. Además, se incluirán apartados para desarrollar las decisiones tomadas y otros aspectos relevantes del desarrollo. |
3. Contexto y Alcance
3.1. Contexto de Negocio
El sistema YOVI es una plataforma de juegos basada en el "Juego Y" que permite la competición entre humanos y agentes automáticos (bots).
| Socio de comunicación | Entradas | Salidas |
|---|---|---|
Usuario (Jugador) |
Registro de cuenta, selección de variantes de juego (Classic, Master Y, etc.), elección de estrategia/dificultad y ejecución de movimientos. |
Visualización del tablero, historial de participación, estadísticas de victorias/derrotas y posición en el ranking. |
Bots Externos |
Peticiones a través del método |
Respuesta con el próximo movimiento calculado por el sistema en notación YEN. |
Administrador |
Configuración de parámetros del sistema y monitorización de métricas. |
Información sobre disponibilidad del sistema y registros de actividad. |
3.2. Contexto Técnico
La arquitectura se basa en la interoperabilidad entre un ecosistema web y un motor de lógica de alto rendimiento, comunicados mediante mensajes JSON.
| Interfaz | Canal / Protocolo | Descripción |
|---|---|---|
Web Frontend |
HTTPS / TypeScript |
Interfaz pública para usuarios humanos, con soporte para diversos tamaños de tablero. |
External API |
REST / JSON |
API documentada para que bots externos interactúen con el sistema y accedan a datos de juego. |
Game Logic Service |
HTTP / JSON (YEN) |
Servicio interno desarrollado en Rust que valida estados de partida y genera sugerencias de movimientos. |
Mapeo de Entradas/Salidas:
* Gestión de Juego: El frontend TypeScript delega la verificación de victorias y la generación de jugadas de la máquina al módulo Rust.
* Notación YEN: Todos los componentes técnicos utilizan el formato JSON YEN para representar el layout del tablero y el estado de los players.
4. Estrategia de Solución
4.1. Introducción
El proyecto yovi_es1b ha sido diseñado empleando una arquitectura modular y distribuida, en el que tenemos diferenciado la UI o interfaz de usuario, la lógica de negocio y el motor del juego, además de una aplicación web. Esta separación, va a permitir un desarrollo incremental, facilitando mantenimiento y escalabilidad del sistema. Las decisiones se han tomado teniendo en cuenta los objetivos de calidad que se mencionarán más adelante.
4.2. Decisiones arquitectónicas claves
-
Webapp: Aplicación frontend
-
Users Service: Servicio backend para gestión de usuarios
-
GameY: Motor de juego y servicio de bots implementado en Rust Esta separación de responsabilidades reduce el acoplamiento, mejora mantenibilidad, y permite escalar o sustituir componentes sin que genere problemas en otras partes del sistema.
-
Frontend: React + Vite + TypeScript. Utilizados ya que son un buen soporte de herramientas y permite interfaces interactivas y fáciles de mantener
-
Backend: Node.js + Express. Son simples y útiles para APIs REST sencillas
-
Motor de juego: Rust + Cargo. Buen rendimiento, muy seguro y una buena gestión de concurrencia. Estas son características importantes para un motor de juego.
-
Uso de contenedores: Docker y Docker Compose. Simplifican instalación, ejecución y pruebas del sistema
-
Mantenibilidad: Empleamos código separado en módulos, separación de responsabilidades y uso de pruebas automáticas
-
Escalabilidad: Nuestros servicios se pueden ir actualizando y mejorando de forma independiente
-
Portabilidad: El uso de Docker, nos permite ejecutar el sistema en varios entornos
-
Calidad del código: SonarCloud y CodeScene ayudan a mantener el código limpio, seguro y fácil de mantener, asegurando que sigan estándares de calidad. Son herramientas que se utilizan para vigilar el código de forma automática mientras se desarrolla.
-
Utilizamos GitHub como flujo de trabajo, que nos permite integrar de forma continua los nuevos cambios que hemos realizado y un despliegue automático
-
El desarrollo del proyecto es de forma incremental, trabajando desde la misma base y desde la cual, partimos cada uno con la parte que se nos sea asignada
-
La asignación se realiza distribuyendo el trabajo en componentes, y cada grupo formado internamente, se encarga del componente que se le asigne
-
Empleamos arc42, junto a AsciiDoc y PlantUML para que la documentación se genere de forma automátrica, incluyendo diagramas. Así el código y la documentación se mantienen sincronizadas, y el despliegue automático de GitHub Pages, facilita la disponibilidad y portabilidad de la documentación
5. Vista de Bloques de Construcción
5.1. Caja Blanca del Sistema General
- Motivation
-
La aplicación YGame permite jugar al juego de conexión Y online contra distintos bots con diferentes niveles de dificultad. Gestiona el registro y autenticación de usuarios, guarda el historial de partidas y ofrece una interfaz web accesible desde el navegador.
- Bloques de Construcción de Contenidos
| Nombre | Descripción |
|---|---|
Usuario |
Usuario de la aplicación que interactúa con ella a través del navegador web. |
Webapp |
Interfaz gráfica SPA (Single Page Application) construida con React, Vite y TypeScript. Gestiona las pantallas de inicio, registro, login y partida. Renderiza el tablero triangular en formato YEN, controla el temporizador de turno y se comunica con el backend mediante llamadas REST. |
Users |
Servicio backend construido con Node.js y Express. Gestiona el registro y autenticación de usuarios, el historial de partidas y actúa de intermediario entre la webapp y el motor de juego Gamey. Expone métricas para Prometheus. |
Gamey |
Motor de juego implementado en Rust. Implementa la lógica completa del juego Y sobre un tablero triangular con coordenadas trilineales (x,y,z). Expone una API REST para gestionar partidas y ofrece tres niveles de bot: RandomBot (fácil), BlockerBot (medio) y ProBot (difícil). |
MongoDB |
Base de datos NoSQL que almacena los usuarios registrados y el historial de partidas, utilizada tanto por el servicio Users como por Gamey. |
Prometheus |
Sistema de monitorización que recolecta métricas del servicio Users. |
Grafana |
Plataforma de visualización que muestra los dashboards con las métricas recogidas por Prometheus. |
- Important Interfaces
| Interfaz | Entre | Descripción |
|---|---|---|
REST |
Webapp → Users |
Inicia o reinicia una partida con el tamaño de tablero y dificultad seleccionados. Devuelve el estado inicial del tablero en formato YEN. |
REST |
Webapp → Users |
Envía el índice de celda elegida por el jugador. El servicio lo reenvía a Gamey, que responde con el nuevo estado del tablero tras el movimiento del jugador y la respuesta del bot. |
REST |
Webapp → Users |
Registra la rendición del jugador y actualiza el historial de partidas en MongoDB. |
REST |
Webapp → Users |
Consulta el historial de partidas del usuario autenticado almacenado en MongoDB. |
REST |
Webapp → Users |
Devuelve la lista de dificultades disponibles (Easy, Medium, Hard). |
REST |
Users → Gamey |
Reenvía los movimientos al motor de juego Rust, que ejecuta la lógica del tablero y devuelve el nuevo estado YEN junto con el resultado (ganador o partida en curso). |
5.1.1. Webapp
Purpose/Responsibility: Proporcionar la interfaz gráfica del juego al usuario final. Gestiona el flujo completo de la partida: selección de dificultad y tamaño de tablero, renderizado del tablero triangular YEN, temporizador de turno con movimiento automático al agotarse, y visualización del historial de partidas.
Interface(s): Se comunica exclusivamente con el servicio Users mediante peticiones HTTP REST. No accede directamente a Gamey ni a MongoDB.
Quality/Performance Characteristics: Aplicación SPA que no requiere recarga de página. El temporizador de turno opera en cliente con intervalos de 1 segundo.
Directory/File Location: webapp/src/
5.1.2. Users
Purpose/Responsibility: Gestionar la autenticación y registro de usuarios, el historial de partidas y actuar como API Gateway entre la webapp y el motor de juego Gamey.
Interface(s): Expone una API REST en el puerto 3000. Se conecta a MongoDB para persistencia y a Gamey (puerto 4000) para la lógica del juego.
Quality/Performance Characteristics: Expone métricas en formato Prometheus para monitorización en tiempo real mediante Grafana.
Directory/File Location: users/
5.1.3. Gamey
Purpose/Responsibility: Ejecutar toda la lógica del juego Y: validar movimientos, detectar la condición de victoria (conexión de los tres lados del triángulo), gestionar el estado del tablero en formato YEN y calcular las respuestas de los bots.
Interface(s): Expone una API REST en el puerto 3000 (mapeado al 4000 en Docker). Recibe y devuelve el estado del tablero en formato YEN (JSON).
Quality/Performance Characteristics: Implementado en Rust para máximo rendimiento en el cálculo de movimientos del ProBot, que usa BFS con potencial exponencial.
Directory/File Location: gamey/src/
5.2. Nivel 2
5.2.1. White Box Webapp
La webapp está organizada en pantallas independientes gestionadas por un router
interno en App.tsx:
| Componente | Descripción |
|---|---|
|
Pantalla inicial con acceso a registro e inicio de sesión. |
|
Formulario de registro de nuevos usuarios. |
|
Formulario de autenticación de usuarios existentes. |
|
Pantalla principal de juego. Renderiza el tablero triangular YEN, muestra el temporizador de turno con barra de progreso, y gestiona las acciones de reiniciar, rendirse, cambiar dificultad/tamaño y consultar historial. |
|
Componente raíz. Contiene toda la lógica de estado: gestión de turnos, temporizador automático (60s/30s/15s según dificultad), comunicación con el backend y navegación entre pantallas. |
5.2.2. White Box Gamey
El motor de juego Rust está organizado en los siguientes módulos:
| Módulo | Descripción |
|---|---|
|
Estado principal de la partida ( |
|
Implementación de la topología triangular. Pre-calcula vecinos y regiones para cada celda usando coordenadas trilineales (x+y+z = size-1). |
|
Sistema de coordenadas trilineales con conversión a/desde índice lineal. |
|
Bot fácil: elige una celda vacía aleatoriamente. |
|
Bot medio: prioriza bloquear los movimientos del oponente. |
|
Bot difícil: usa BFS para calcular distancias a los tres lados y puntúa cada celda con potencial exponencial, bonificación de centralidad y conectividad. |
|
Serialización/deserialización del formato YEN (JSON con layout
triangular separado por |
|
Servidor HTTP Axum que expone la API REST del motor de juego. |
5.2.3. White Box Users
| Módulo | Descripción |
|---|---|
|
Servicio principal Express. Define los endpoints REST, gestiona la conexión a MongoDB y reenvía las peticiones de juego a Gamey. |
|
Modelo Mongoose para usuarios y historial de partidas. |
|
Configuración de Prometheus para recolección de métricas. |
|
Dashboards de Grafana para visualización de métricas. |
5.3. Nivel 3
5.3.1. White Box ProBot (bot/pro_bot.rs)
El ProBot implementa la estrategia más avanzada en varias fases:
| Fase | Descripción |
|---|---|
Cálculo de distancias |
Para cada jugador ejecuta BFS desde cada uno de los tres lados del tablero, calculando el coste mínimo de conexión. Pasar por una celda propia cuesta 0, por una vacía cuesta 1 y por una del oponente cuesta 2. |
Potencial exponencial |
Convierte distancias en puntuación con la fórmula
|
Puntuación final |
Combina: potencial del oponente (×15) + potencial propio (×1) + bonificación de centralidad + bonificación de conectividad (+15 si conecta ≥2 fichas propias) + bloqueo crítico (+1000 si bloquea ≥2 fichas del oponente). |
Selección |
Elige la celda vacía con mayor puntuación total. |
5.3.2. White Box Topología Triangular (core/topology/)
| Elemento | Descripción |
|---|---|
|
Pre-calcula en construcción la lista de adyacencia y las regiones (lados A, B, C) de cada celda para acceso O(1) durante el juego. |
Coordenadas trilineales |
Cada celda se identifica por (x,y,z) donde x+y+z = size-1. Los tres lados del triángulo corresponden a x=0, y=0 y z=0 respectivamente. |
|
Motor genérico parametrizado con la topología. Gestiona el estado de las celdas y detecta la victoria mediante Union-Find sobre los tres lados. |
5.3.3. White Box Temporizador de turno (App.tsx)
| Elemento | Descripción |
|---|---|
|
Constante que define el límite en segundos por dificultad: Easy=60s, Medium=30s, Hard=15s. |
|
Arranca un intervalo de 1 segundo que decrementa |
|
Detiene el intervalo activo y resetea |
|
Selecciona una celda vacía aleatoria del layout actual y
ejecuta la misma lógica que |
6. Vista de Ejecución
6.1. Escenario de Registro de Usuario
This scenario describes how a new user registers in the application. The Webapp captures the data and communicates with the Users Service to store the information.
-
Notably: The separation between the frontend (Webapp) and the backend (Users Service) allows the logic to be decoupled.
-
API Usage: The Users Service exposes a REST API on port 3000.
6.2. Escenario de Inicialización de Partida
El motor de Rust ahora mantiene un estado persistente durante la partida. Este escenario es crucial porque es donde el servidor "elige" su personalidad.
-
Consistencia: Una vez elegida la dificultad, el bot asignado no cambia hasta que se reinicie el tablero.
-
Estado compartido: Se utiliza un
AppStateconArc<Mutex<String>>para recordar el bot activo.
6.3. Escenario de Turno de Juego y Persistencia
Este escenario ilustra el ciclo de vida de un movimiento. El motor de Rust no solo calcula la respuesta, sino que detecta el final de la partida y persiste el resultado.
-
Inteligencia: El motor delega la jugada al bot guardado en el
active_bot. -
Persistencia: Al detectar un ganador, el servicio de Rust se comunica directamente con MongoDB.
7. Vista de despliegue
7.1. Infraestructura de Nivel 1
En este apartado se describe la infraestructura global de YOVI, destacando el uso de contenedores para gestionar la heterogeneidad tecnológica del proyecto (Node.js y Rust) y la persistencia de datos.
- Motivación
-
La infraestructura se basa en la contenerización con Docker para resolver la necesidad de ejecutar dos entornos distintos (Node.js y Rust). El despliegue en la nube garantiza que la aplicación sea accesible publicamente, cumpliendo con el requisito de disponibilidad para usuarios y bots externos. Así, una parte se encarga de la web y los usuarios (Node.js) y otra exclusivamente de las reglas del juego (Rust).
- Características de Calidad y Rendimiento
-
-
Rapidez: Al tener la lógica del juego en Rust, las jugadas se calculan de manera casi inmediata.
-
Fiabilidad: Como se usan contenedores, el sistema funcionará igual de bien en los ordenadores donde se desarrolla que en los del servidor final.
-
Seguridad: Los datos viajan protegidos por internet para mantener las partidas privadas.
-
- Mapeo de piezas a la infraestructura
| ¿Qué se ha programado? | ¿Dónde se ejecuta? |
|---|---|
La interfaz Web |
En el ordenador o móvil donde la persona juega. |
La API y gestión de usuarios |
En el contenedor principal del servidor. |
Las reglas y estrategias del juego |
En el contenedor principal de Rust. |
El historial de partidas |
En el servidor de base de datos. |
7.2. Infraestructura de Nivel 2
7.2.1. Servidor en la Nube (Docker Host)
Es el servidor principal donde ocurre todo lo relativo al backend.
Explicación: En este nivel de detalle se observa que el servidor de Node.js funciona como un punto de control. Cuando el usuario solicita su historial, Node no accede a los datos de las partidas directamente; en su lugar, realiza una petición interna al servicio de Rust. Es Rust quien tiene la responsabilidad única de comunicarse con la colección partidas de MongoDB para registrar o recuperar los resultados de los juegos. Esta separación garantiza que la lógica del juego y la gestión de usuarios no interfieran entre sí.
7.2.2. Cliente
Es el dispositivo (PC o móvil) de la persona que utiliza la aplicación.
Explicación: Al acceder a la web, el navegador descarga la aplicación de React, que se ejecuta íntegramente en el dispositivo del usuario. El sistema utiliza el Estado Local (memoria RAM) para mantener identificada la sesión. Así, cuando el jugador solicita su historial, el código rescata el nombre guardado y construye una petición dinámica hacia el backend de Node.js. Esto permite que el juego sea fluido y que el servidor reciba siempre el contexto necesario para filtrar los datos de la base de datos correctamente.
7.2.3. Base de Datos (Persistencia)
Es el lugar donde se almacena la información. De esta manera no se perderá la información al reiniciar los contenedores.
Explicación: Se utiliza un motor de base de datos MongoDB que organiza la información en colecciones independientes: los perfiles de usuario (gestionados por Node.js) y el historial de juegos (registrado por Rust). Mediante un volumen persistente de Docker, los datos se sincronizan directamente con el disco duro del servidor. Esto garantiza que, aunque el contenedor de la base de datos se detenga o se actualice, la información de las partidas y las cuentas de usuario permanezca segura y disponible, funcionando como un almacenamiento externo permanente.
8. 8. Conceptos transversales
8.1. 8.1. Gestión de Proyecto
8.1.1. Metodología de desarrollo
El proyecto adopta una metodología ágil basada en Scrum. Este enfoque iterativo e incremental permite una adaptación continua a los cambios y una entrega de valor constante. Se realizan reuniones semanales de seguimiento para revisar el progreso, ajustar la planificación y asegurar la alineación del equipo.
8.1.2. Tareas y prioridades
La planificación y el seguimiento de las tareas se centralizan en GitHub Projects. Las prioridades se revisan cada semana, quedando documentadas en actas de reunión para garantizar la transparencia y el compromiso del equipo.
8.2. 8.2. Arquitectura y patrones de diseño
8.2.1. Arquitectura de Microservicios
La solución se ha diseñado siguiendo una arquitectura de microservicios. Este patrón estructura la aplicación como un conjunto de servicios pequeños, autónomos y débilmente acoplados.
Beneficios Clave:
-
Escalabilidad: Permite escalar componentes individuales según la demanda.
-
Mantenibilidad: Facilita la comprensión, el desarrollo y el despliegue independiente de cada servicio.
-
Flexibilidad Tecnológica: Posibilita el uso de diferentes tecnologías o lenguajes para cada servicio si fuera necesario.
8.3. 8.3. Entorno de Desarrollo y Despliegue
8.3.1. Contenerización con Docker
Se utiliza Docker y Docker Compose para estandarizar los entornos de desarrollo, pruebas y producción. Cada microservicio (Webapp, Users, GameY) se empaqueta en su propio contenedor, asegurando que la aplicación se ejecute de manera consistente independientemente de la máquina anfitriona. Esto elimina el problema de "funciona en mi máquina" y simplifica la configuración inicial para nuevos desarrolladores.
8.4. 8.4. Calidad y Automatización
8.4.1. Integración Continua y Calidad de Código (CI/CQ)
El proyecto implementa prácticas de Integración Continua (CI) y Calidad de Código (CQ) para mantener un alto estándar de desarrollo:
-
GitHub Actions: Se utilizan flujos de trabajo automatizados para ejecutar pruebas y verificar la integridad del código en cada push o pull request.
-
SonarQube / SonarCloud: Se integra el análisis estático de código para detectar bugs, vulnerabilidades de seguridad y deuda técnica de manera temprana.
9. Decisiones de Arquitectura
9.1. Lenguaje de programación
9.1.1. Contexto
Necesitamos un motor de juego con buen rendimiento y seguridad de memoria, y al mismo tiempo una capa web para interacción rápida y desarrollo de interfaz.
9.1.2. Decisión
Usar Rust para el motor del juego (gamey) y JavaScript/TypeScript (Node.js) para el servicio users y TypeScript + React para el frontend (Vite).
9.1.3. Consecuencias
-
Alto rendimiento y seguridad en el motor (Rust): evita problemas de memoria y mejora la latencia.
-
Desarrollo rápido y ecosistema web (Node/React/TypeScript): facilita iteración en frontend y servicios HTTP.
-
Interoperabilidad clara: API REST expuestos por cada servicio.
-
Curva de aprendizaje y complejidad operativa por el stack poliglota (Rust + Node + TS).
-
Mayor complejidad en CI/build (compilar Rust y bundles JS) y en la orquestación.
-
Desconocimiento por parte del equipo del lenguaje Rust.
9.2. Base de datos
9.2.1. Contexto
Se requiere persistencia para usuarios y registros de partidas; se valora flexibilidad de esquema y facilidad de integración con Node.js.
9.2.2. Decisión
Usar MongoDB como base de datos principal; users usa Mongoose y el servicio Rust puede escribir registros de partidas en Mongo cuando corresponda.
9.2.3. Consecuencias
-
Esquema flexible para usuarios y partidas, lo que facilita evolucionar el modelo de datos.
-
Integración sencilla con Node.js (Mongoose) y despliegue con Docker.
-
No es relacional por diseño: operaciones transaccionales complejas requieren atención o soluciones adicionales.
-
Riesgos de diseño incorrecto de índices y consultas (posibles problemas de rendimiento si no se indexa adecuadamente).
-
Desconocimiento por parte del equipo de MongoDB.
9.3. Frontend (React)
9.3.1. Contexto
Necesitamos una SPA con navegación por pantallas y una experiencia interactiva fluida para el juego.
9.3.2. Decisión
Usar React + TypeScript con Vite como bundler y desarrollo local.
9.3.3. Consecuencias
-
Desarrollo rápido de UIs reusables y tipadas.
-
Ecosistema amplio (testing, linters, herramientas) y buen soporte para Vite.
-
Dependencia de tooling (Vite, ESLint, etc.) y necesidad de mantener configuración.
9.4. Microservicios
9.4.1. Contexto
Queremos separar responsabilidades (UI, gestión de usuarios, motor del juego) y facilitar despliegues independientes.
9.4.2. Decisión
Arquitectura de microservicios ligeros: webapp, users, gamey (Rust). Comunicación mediante HTTP/REST; orquestación con docker-compose en desarrollo.
9.4.3. Consecuencias
-
Despliegue y escalado independientes por componente.
-
Claridad en responsabilidades y menor acoplamiento lógico.
-
Mayor complejidad en integración, testing e implementación CI/CD.
-
Latencia de red entre servicios y necesidad de gestionar variables de entorno y descubrimiento.
9.5. Docker
9.5.1. Contexto
Necesitamos reproducibilidad en entornos de desarrollo y despliegue local sencillo.
9.5.2. Decisión
Usar Docker y docker-compose para orquestar los servicios en desarrollo.
9.5.3. Consecuencias
-
Entornos reproducibles y aislamientos por servicio.
-
Facilita pruebas locales.
-
Consumo de recursos en máquinas locales.
9.6. LLMs empleados
9.6.1. Contexto
Valoramos la posibilidad de usar modelos de lenguaje para IA, pero no es un requisito actual.
9.6.2. Decisión
No integrar LLMs; las IAs del juego son bots heurísticos implementados en gamey.
9.6.3. Consecuencias
-
Arquitectura más simple y sin dependencias a servicios de LLM.
-
Menor capacidad para comportamientos avanzados sin diseñar heurísticas más complejas.
9.7. Plantilla Arc42
9.7.1. Contexto
Necesitamos una estructura clara para la documentación arquitectónica que sea comprensible por el equipo y terceros.
9.7.2. Decisión
Adoptar la plantilla arc42 para organizar la documentación (carpeta docs/).
9.7.3. Consecuencias
-
Estructura estándar y reconocible para documentar decisiones, vistas y riesgos.
-
Trabajo adicional para mantener documentación al día.
9.8. Observabilidad / Monitoring
9.8.1. Contexto
Se requiere visibilidad mínima del comportamiento del servicio (métricas de disponibilidad y latencia).
9.8.2. Decisión
Exponer métricas desde users con express-prom-bundle (Prometheus) y provisionar dashboards de Grafana (configuración en users/monitoring).
9.8.3. Consecuencias
-
Métricas simples disponibles para alertas y diagnóstico.
-
Infra adicional a desplegar y mantener (Prometheus/Grafana).
9.9. Seguridad / Autenticación
9.9.1. Contexto
Las contraseñas de usuario deben almacenarse de forma segura.
9.9.2. Decisión
Hashear contraseñas con bcryptjs en users. Actualmente no hay sessions implementados; añadir autenticación basada en tokens queda como mejora pendiente.
9.9.3. Consecuencias
-
Contraseñas no se almacenan en texto plano; protección básica frente a fugas.
-
Falta de mecanismo de autorización (tokens/sesiones) que limite recursos protegidos; requiere trabajo futuro.
9.10. CI / Calidad
9.10.1. Contexto
Mantener calidad del código y detectar regresiones tempranamente.
9.10.2. Decisión
Usar linting, tests locales (Vitest en servicios JS/TS) y configuración de Sonar (archivo sonar-project.properties) para facilitar análisis de calidad.
9.10.3. Consecuencias
-
Detectar errores y antipatróns temprano; control de calidad.
-
Requiere mantenimiento de reglas y tiempo de ejecución adicional en pipelines.
10. Requisitos de Calidad
10.1. Árbol de calidad
10.2. Escenarios de calidad
10.2.1. Escenarios de uso
| ID | Escenario | Estímulo | Respuesta esperada del sistema |
|---|---|---|---|
SC-01 |
Respuesta del bot en dificultad difícil |
El jugador realiza un movimiento en un tablero de tamaño 12x12x12 con el ProBot activo. |
El motor Gamey calcula y devuelve el movimiento del bot en menos de 2 segundos, actualizándose el tablero en la webapp sin demora visible. |
SC-02 |
Timeout de turno en dificultad Hard |
El jugador no realiza ningún movimiento durante 15 segundos en dificultad Hard. |
El sistema selecciona automáticamente una celda vacía aleatoria en nombre del jugador, y reinicia el temporizador para el siguiente turno. |
SC-03 |
Aviso visual de tiempo agotándose |
Quedan 5 segundos o menos en el temporizador de turno del jugador. |
La barra de progreso cambia de azul a rojo y el contador de segundos parpadea para alertar al jugador de que debe actuar con urgencia. |
SC-04 |
Registro de nuevo usuario |
Un usuario rellena el formulario de registro con nombre y contraseña válidos. |
El servicio Users crea el usuario en MongoDB y redirige automáticamente a la pantalla de juego en menos de 1 segundo. |
SC-05 |
Consulta del historial de partidas |
El jugador pulsa el botón "Historial" durante una partida. |
La webapp solicita al backend el historial y muestra una tabla con fecha, rival, tamaño de tablero, dificultad y resultado de cada partida previa en menos de 2 segundos. |
SC-06 |
Rendición del jugador |
El jugador pulsa el botón "Rendirse" durante una partida en curso. |
El sistema detiene el temporizador, registra la derrota en el historial de MongoDB y muestra el modal de resultado indicando "Has perdido". |
SC-07 |
Cambio de dificultad durante la partida |
El jugador cambia la dificultad de Easy a Hard desde el menú de la partida. |
El sistema reinicia el tablero con la nueva dificultad, arranca el temporizador con el nuevo límite (15 segundos) y muestra el mensaje "Dificultad cambiada a Hard". |
SC-08 |
Cambio de tamaño de tablero |
El jugador selecciona un tablero de 12x12x12 desde el tamaño por defecto (6x6x6). |
La webapp solicita un nuevo tablero al backend, lo renderiza correctamente con 78 celdas y reinicia el temporizador sin perder la dificultad seleccionada. |
SC-09 |
Acceso concurrente de múltiples usuarios |
Diez usuarios distintos inician sesión y juegan simultáneamente. |
Cada sesión es independiente; el estado de la partida de un usuario no interfiere con el de los demás y el servicio Users responde correctamente a todas las peticiones. |
SC-10 |
Condición de victoria |
Un jugador conecta los tres lados del tablero triangular con sus fichas. |
El motor Gamey detecta la victoria, detiene el juego, el temporizador se para y la webapp muestra el modal "Has ganado" o "Ha ganado el bot" según corresponda. |
10.2.2. Escenarios de cambio
| ID | Escenario | Cambio | Respuesta esperada del sistema |
|---|---|---|---|
SC-C01 |
Añadir un nuevo nivel de dificultad |
Se implementa un nuevo bot con dificultad "Expert" en el módulo |
El nuevo bot se registra en |
SC-C02 |
Cambio en el tiempo límite por dificultad |
Se decide reducir el tiempo de Hard de 15 a 10 segundos. |
Solo es necesario modificar la constante |
SC-C03 |
Caída del servicio Gamey |
El contenedor Gamey deja de responder durante una partida en curso. |
El servicio Users recibe un error de red al intentar contactar con Gamey. La webapp muestra "Error realizando el movimiento" y el temporizador se reinicia para permitir al jugador intentarlo de nuevo. |
SC-C04 |
Escalado del tamaño de tablero |
Se añade soporte para un nuevo tamaño de tablero (por ejemplo 15x15x15). |
Basta con añadir la opción en el modal de selección en |
SC-C05 |
Migración de base de datos |
Se decide cambiar de MongoDB local a MongoDB Atlas en producción. |
Solo es necesario actualizar la variable de entorno |
11. Riesgos y Deudas Técnicas
11.1. Riesgos
| Riesgo | Descripción | Prioridad |
|---|---|---|
Tiempo |
El tiempo dedicado al proyecto es limitado debido a que el equipo de desarrollo tiene otras obligaciones laborales. |
Medium |
Poca experiencia en Rust y Docker |
El equipo encuentra dificultades debido al conocimiento limitado del lenguaje Rust y la herramienta Docker. Para mitigarlo, se fomenta el aprendizaje activo y el intercambio de dudas. |
High |
Pérdida de datos |
Posible pérdida de información por errores en el sistema, fallos de hardware o eliminaciones accidentales que podrían ralentizar el desarrollo del proyecto. |
High |
Fallos de conexión |
Un fallo en la conexión a internet podría interrumpir el acceso a servidores en la nube y al repositorio de GitHub, retrasando el progreso. |
Medium |
11.2. Deudas Técnicas
La deuda técnica representa el costo del retrabajo adicional causado por la elección de una solución rápida en lugar de la más efectiva a largo plazo.
-
Falta de tests automatizados: Se ha priorizado el desarrollo de funcionalidades sobre la cobertura de tests, lo que podría generar errores en el futuro.
12. Glosario
| Term | Definition |
|---|---|
<Term-1> |
<definition-1> |
<Term-2> |
<definition-2> |
