- README.md: project overview, server status, quick start guide, architecture diagram, tech stack, and content inventory - docs/architecture.md: technical architecture, service diagram, component details, and design decisions - docs/game-servers.md: setup and operation guide for OpenFusion, MapleStory 2, and Minecraft FTB Infinity Evolved - docs/cms-content.md: Strapi content model, i18n strategy, documentary structure, and API endpoints - docs/deployment.md: local dev, production deploy, CI/CD, SSL setup, backup procedures, and monitoring Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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
overridesen rootpackage.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 servidorDocumentary— Documental con titulo, descripcion, relacion 1:1 con GameChapter— 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) ygame-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 |
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):
- Push a
maindispara el deploy - SSH al VPS
- 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.