# Arquitectura — Diseño técnico de alto nivel

## Visión general

Arquitectura pensada para un **MVP local-first / self-hosted** que pueda evolucionar a un servicio multiusuario. Propuesta: **monorepo** con dos paquetes principales: `/backend` y `/frontend` (Yarn workspaces). Backend expone una REST API (Fastify + TypeScript); Frontend es una SPA en React (Vite o similar) usando **TanStack Query** y **TanStack Router**.

## Diagrama de alto nivel (texto)

```
Usuario (Browser React) ↔ Frontend (TanStack Query/Router) ↔ Backend REST (Fastify + TypeScript)
                                 ↕
                Worker (Bull/BullMQ) ↔ Redis (cache/cola, opcional)
                                 ↕
          DB (SQLite dev → Postgres prod) + Storage (local FS | S3)
                                 ↕
                     APIs externas (IGDB, RAWG, TheGamesDB)
```

---

## Decisiones clave y justificación

- **Monorepo (Yarn workspaces)**: coherencia de versiones, compartir utilidades y configuración (lint/tsconfig).
- **Fastify + TypeScript** (REST): recomendado para rendimiento y ergonomía con TypeScript; ofrece sistema de plugins encapsulados, validación/serialización basada en Ajv integrada, logging muy rápido (pino) y mejor throughput en producción.
- **Prisma** como ORM: productivo y portátil entre SQLite/Postgres.
- **SQLite en dev / Postgres en producción**: facilidad de desarrollo y migraciones seguras para futuro.
- **Bull/BullMQ + Redis** para trabajos asíncronos (escaneo, enrich, procesamiento de imágenes).
- **Storage**: Adapter pattern para `StorageAdapter` que permita usar S3 o disco local según despliegue.

---

## Stack propuesto (resumen)

- Backend: Node.js, TypeScript, Fastify, Prisma, Bull/BullMQ, Redis (opcional), Sharp (procesado de imágenes), @fastify/multipart (uploads), @fastify/helmet, @fastify/rate-limit, Ajv (validación), pino (logging).
- Frontend: React, TypeScript (opcional), Vite, TanStack Query, TanStack Router, Tailwind CSS (opcional).
- Infra / DevOps: Docker Compose (self-hosting), GitHub Actions (CI), env vars + GitHub Secrets.

---

## Estructura de carpetas sugerida

```
/ (monorepo)
  package.json (workspaces)
  /backend
    package.json
    prisma/schema.prisma
    src/
      index.ts
      controllers/
      services/
      routes/
      jobs/
      workers/
      lib/
  /frontend
    package.json
    src/
      routes/
      components/
      hooks/
      lib/
      assets/
  /docs
```

---

## Scripts útiles sugeridos (`package.json` raíz)

```json
{
  "scripts": {
    "dev": "concurrently \"yarn dev:backend\" \"yarn dev:frontend\"",
    "dev:backend": "cd backend && ts-node-dev --respawn src/index.ts",
    "dev:frontend": "cd frontend && vite",
    "start": "node backend/dist/index.js",
    "lint": "eslint . --ext .ts,.tsx,.js",
    "format": "prettier --write .",
    "prisma:migrate": "cd backend && prisma migrate dev",
    "prisma:studio": "cd backend && prisma studio"
  }
}
```

---

## Seguridad y operacionales

- Variables sensibles en `.env` y en GitHub Secrets para CI.
- CORS configurado para orígenes permitidos; validación y saneamiento de entradas.
- Rate limiting global y por endpoint (enriquecimiento de metadatos).
- Backups: snapshots regulares de la DB y copia periódica de carpeta `artwork/`.
- Despliegue: `docker-compose.yml` con volúmenes para DB y assets; salud (`/health`) y readiness probes.
- Observabilidad: logs estructurados (pino/winston); endpoint de métricas básico (Prometheus) o integraciones simples.

---

## Integración de APIs externas

- Encapsular cada proveedor en un adaptador (ej.: `IgdbClient`, `RawgClient`) con interfaz común: `search(query)`, `getById(id)`, `getArtwork(id)`.
- Caching: Redis o LRU en memoria con TTL (ej. 24h) para respuestas y metadatos de artwork.
- Retries y protección: reconectar con backoff + circuit breaker para evitar fallos en cascada.

---

## Fuentes

- Documentación: Fastify, Prisma, Bull/BullMQ, Redis, Sharp, TanStack Query/Router.

---

**Metadatos**
Autor: Quasar (investigación automatizada)
Última actualización: 2026-02-07
