Files
project-afterlife/docs/architecture.md
consultoria-as 81e978947e
Some checks failed
Deploy / deploy (push) Has been cancelled
feat: switch Minecraft from FTB Infinity Evolved to FTB Evolution
Minecraft 1.21.1 + NeoForge 21.1.218 with 200+ mods.
Added MAX_TICK_TIME=-1 to prevent watchdog crashes on startup.
Updated CMS entries, README, and all docs to reflect new modpack.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 13:14:55 +00:00

8.0 KiB

Arquitectura Tecnica

Vision General

Project Afterlife es un monorepo que combina una plataforma web de preservacion de videojuegos con los servidores de los juegos preservados. La infraestructura se gestiona completamente con Docker Compose.

Diagrama de Servicios

                    ┌─────────────────────────────────────┐
                    │           USUARIO / CLIENTE          │
                    └───────────┬───────────┬─────────────┘
                                │           │
                    ┌───────────▼───┐ ┌─────▼─────────────┐
                    │  Next.js :3000│ │ Clientes de juegos │
                    └───────┬───────┘ └──┬──────┬─────┬───┘
                            │            │      │     │
                    ┌───────▼───────┐    │      │     │
                    │ Strapi  :1337 │    │      │     │
                    └───┬───────┬───┘    │      │     │
                        │       │        │      │     │
                ┌───────▼──┐ ┌──▼────┐   │      │     │
                │ PG :5432 │ │ MinIO │   │      │     │
                │          │ │ :9000 │   │      │     │
                └──────────┘ └───────┘   │      │     │
                                         │      │     │
          ┌──────────────────────────────┘      │     │
          │                                     │     │
  ┌───────▼──────────┐  ┌──────────────────┐   │     │
  │  OpenFusion      │  │  MapleStory 2    │   │     │
  │  :23000-23001    │  │  Login :20001    │   │     │
  └──────────────────┘  │  World :21001    │   │     │
                        │  Game  :20002    │   │     │
                        │  Web   :4000     │   │     │
                        │  MySQL :3307     │   │     │
                        └──────────────────┘   │     │
                                               │     │
                        ┌──────────────────────▼─┐   │
                        │  Minecraft FTB :25565   │   │
                        └────────────────────────┘   │
                                                     │
                              (Juegos futuros...)  ◄──┘

Componentes

Frontend (Next.js 15)

Ubicacion: apps/web/

  • Framework: Next.js 15 con App Router
  • React: 19 (forzado via overrides en root package.json)
  • Estilos: Tailwind CSS v4 con @tailwindcss/postcss
  • i18n: next-intl con prefijo de ruta (/es/, /en/)
  • Audio: Howler.js para reproductor de documentales
  • Animaciones: Framer Motion

Estructura de rutas:

src/app/
├── layout.tsx                          # Pass-through (return children)
├── globals.css                         # Tailwind v4 imports
├── not-found.tsx                       # 404 page
└── [locale]/
    ├── layout.tsx                      # <html>, <body>, providers
    ├── page.tsx                        # Home
    ├── about/page.tsx                  # About
    ├── catalog/page.tsx                # Game catalog
    ├── donate/page.tsx                 # Donations
    └── games/
        └── [slug]/
            ├── page.tsx                # Game detail
            └── documentary/page.tsx    # Interactive documentary

Patron de layout: El root layout.tsx es un pass-through que solo retorna children. El layout real con <html>, <body>, y NextIntlClientProvider esta en [locale]/layout.tsx. Esto es necesario para que next-intl funcione correctamente con el App Router.

CMS (Strapi 5)

Ubicacion: apps/cms/

  • Version: Strapi 5.36.0
  • Base de datos: PostgreSQL 16
  • Almacenamiento: MinIO (compatible con S3)
  • React: 18 (admin panel, separado del frontend)
  • i18n: Plugin nativo con locales ES/EN

Content Types:

  • Game — Entrada de juego con metadata, screenshots, estado del servidor
  • Documentary — Documental con titulo, descripcion, relacion 1:1 con Game
  • Chapter — Capitulo con contenido rich text, audio opcional, orden

Nota sobre schemas: Los archivos schema.json de Strapi 5 deben copiarse manualmente al directorio dist/ durante el build. El Dockerfile del CMS incluye este fix.

Tipos Compartidos

Ubicacion: packages/shared/

Paquete TypeScript puro (@afterlife/shared) con las interfaces compartidas entre web y CMS:

// Game, Documentary, Chapter, StrapiMedia, StrapiResponse, etc.

Base de Datos

PostgreSQL 16 para el CMS:

  • 44 tablas (contenido + sistema Strapi)
  • Modelo i18n: cada contenido tiene filas separadas por locale (en/es) y estado (draft/published)
  • Relaciones via tablas _lnk (e.g., games_documentary_lnk)

MySQL 8.0 para MapleStory 2:

  • Dos databases: maple-data (datos del juego, read-only) y game-server (datos de jugadores)
  • Puerto 3307 para evitar conflicto con PostgreSQL 5432

Almacenamiento (MinIO)

MinIO corre como servicio S3-compatible para almacenar:

  • Imagenes de portada de juegos
  • Screenshots
  • Archivos de audio para documentales
  • Cualquier otro media subido al CMS

Puertos: 9000 (API), 9001 (consola web)

Docker Compose: Tres Archivos

Archivo Proposito Servicios
docker-compose.dev.yml Desarrollo local PG, MinIO, CMS, Web, OpenFusion, Minecraft FTB Evolution
docker-compose.maple2.yml MapleStory 2 MySQL, World, Login, Game, Web, File-Ingest
docker-compose.yml Produccion PG, MinIO, CMS, Web, Nginx, Certbot

MapleStory 2 tiene su propio compose porque son 6 servicios (demasiados para mezclar con el stack principal) y requiere su propia base de datos MySQL.

Red Docker

Todos los servicios del mismo archivo compose comparten una red Docker implicita. Los servicios se referencian entre si por nombre de servicio (e.g., cms desde web, maple2-mysql desde maple2-world).

Las variables de entorno como DB_IP, GRPC_WORLD_IP se configuran en cada servicio para apuntar al nombre de contenedor correcto dentro de la red Docker.

CI/CD

GitHub Actions (.github/workflows/deploy.yml):

  1. Push a main dispara el deploy
  2. SSH al VPS
  3. Pull, build, restart de servicios Docker

Decisiones Arquitectonicas

React 19 vs 18

El monorepo tiene dos versiones de React: 19 para Next.js (web) y 18 para Strapi (admin). Resuelto con overrides en el root package.json que solo afecta al workspace de web. El CMS corre en su propio contenedor Docker con sus propias dependencias.

Tailwind v4

Usa la nueva sintaxis @import "tailwindcss" en globals.css con el plugin @tailwindcss/postcss. No hay tailwind.config.js.

i18n con Strapi 5

Strapi 5 maneja i18n con filas separadas por locale y un document_id compartido. Cada documento tiene 4 filas: draft EN, draft ES, published EN, published ES. Las relaciones (_lnk) conectan las filas del mismo estado/locale.

Servidores de juegos separados

Los servidores de juegos no son parte del build del monorepo. Son proyectos externos (OpenFusion en C++, Maple2 en C#) que se clonan en servers/ y se ejecutan via Docker. El .gitignore excluye servers/maple2/ (14 GB de datos de cliente) y los binarios de OpenFusion.