Files
quasar/plans/gestor-coleccion-plan.md
2026-02-07 18:47:06 +01:00

15 KiB

Plan: Gestor de biblioteca de videojuegos y ROMs (Quasar)

Aplicación web self-hosted para gestionar una biblioteca de ROMs y videojuegos físicos/digitales. Permite escanear directorios de ROMs, enriquecer metadatos vía APIs públicas (IGDB, RAWG, TheGamesDB), y registrar manualmente juegos físicos/digitales con precio, condición y notas. Stack: TypeScript + React + Vite + shadcn/ui (frontend), Node.js + Express + SQLite (backend).

Fases: 9


Fase 1: Análisis comparativo de proyectos y servicios

  • Objetivo: Documentar todos los proyectos, herramientas y APIs analizados durante la investigación inicial, describiendo qué hace cada uno, sus características principales, licencias, y lecciones aprendidas para aplicar a Quasar.
  • Archivos/Funciones a crear/modificar:
    • docs/competitive-analysis.md — análisis detallado de proyectos (Playnite, LaunchBox, OpenEmu, EmulationStation, RetroArch, ROMVault, etc.)
    • docs/apis-comparison.md — comparativa de APIs (IGDB, RAWG, TheGamesDB, Screenscraper, MobyGames, PriceCharting, ITAD, eBay)
    • docs/lessons-learned.md — patrones y mejores prácticas extraídas del análisis
  • Pasos:
    1. Crear documentos con información estructurada de la investigación inicial
    2. Incluir tablas comparativas, enlaces, y conclusiones
    3. Documentar patrones útiles y mejores prácticas aplicables a Quasar

Fase 2: Requisitos y diseño técnico

  • Objetivo: Definir arquitectura (monorepo o separado), estructura de carpetas, stack definitivo (Express/Fastify, Prisma/TypeORM, SQLite), APIs a integrar (IGDB, RAWG, TheGamesDB), y documento de modelo de datos inicial.
  • Archivos/Funciones a crear/modificar:
    • docs/requirements.md — requisitos funcionales y no funcionales
    • docs/architecture.md — decisiones arquitectónicas (monorepo vs multi-repo, API REST structure)
    • docs/api-integration.md — descripción de APIs públicas a usar, endpoints, rate limits, autenticación
    • docs/data-model.md — entidades (Game, RomFile, Platform, Purchase, Artwork)
  • Pasos:
    1. Crear documentos docs/requirements.md, docs/architecture.md, docs/api-integration.md, docs/data-model.md con contenido inicial
    2. Definir estructura de carpetas y convenciones de código
    3. Documentar decisiones técnicas y justificaciones

Fase 3: Backend base y modelo de datos

  • Objetivo: Configurar backend (Express + TypeScript + Prisma + SQLite), definir schema de BD (Game, RomFile, Platform, Purchase, Artwork), migraciones y seeders básicos.
  • Archivos/Funciones a crear/modificar:
    • backend/package.json — dependencias (express, prisma, cors, dotenv, etc.)
    • backend/tsconfig.json — configuración TypeScript backend
    • backend/src/index.ts — servidor Express inicial
    • backend/prisma/schema.prisma — modelos (Game, RomFile, Platform, Purchase, Artwork)
    • backend/prisma/migrations/ — migraciones Prisma
    • backend/src/routes/healthcheck.ts — endpoint /api/health
  • Tests a escribir:
    • backend/tests/server.spec.ts — test del servidor (inicia y responde en /api/health)
    • backend/tests/models/game.spec.ts — validaciones del modelo Game (TDD)
    • backend/tests/models/romFile.spec.ts — validaciones del modelo RomFile
  • Pasos:
    1. Escribir tests que fallen (healthcheck endpoint, crear modelo Game y validar)
    2. Configurar Express + Prisma, definir schema, ejecutar migración
    3. Implementar endpoint /api/health
    4. Ejecutar tests y verificar que pasan

Fase 4: Importadores y gestión de ROMs

  • Objetivo: Implementar servicio para escanear directorios locales, calcular checksums (CRC32/MD5/SHA1), detectar formatos (ZIP/7z/CHD), y almacenar en BD. Incluir soporte básico para DAT verification (No-Intro/Redump).
  • Archivos/Funciones a crear/modificar:
    • backend/src/services/fsScanner.ts — función scanDirectory(path: string)
    • backend/src/services/checksumService.ts — funciones calculateCRC32(), calculateMD5(), calculateSHA1()
    • backend/src/services/datVerifier.ts — función verifyAgainstDAT(romFiles, datPath)
    • backend/src/routes/import.ts — endpoint POST /api/import/scan (body: {path})
    • backend/src/utils/archiveReader.ts — leer contenido de ZIP/7z/CHD
  • Tests a escribir:
    • backend/tests/services/fsScanner.spec.ts — casos: carpeta vacía, carpeta con ROMs, carpeta con subdirectorios
    • backend/tests/services/checksumService.spec.ts — calcular checksum de archivo fixture
    • backend/tests/services/datVerifier.spec.ts — verificar ROM válido/inválido contra DAT fixture
    • backend/tests/routes/import.spec.ts — test E2E de endpoint /api/import/scan
  • Pasos:
    1. Crear fixtures (ROMs de prueba, DAT de prueba)
    2. Escribir tests que fallen (escaneo de carpeta, checksum, DAT verification)
    3. Implementar fsScanner, checksumService, datVerifier mínimos
    4. Implementar endpoint /api/import/scan
    5. Ejecutar tests y verificar que pasan

Fase 5: Integración con APIs de metadata

  • Objetivo: Clientes para IGDB (OAuth Twitch), RAWG (API key), TheGamesDB (API key); lógica de matching heurística (nombre + plataforma), caché local de respuestas para evitar rate limits.
  • Archivos/Funciones a crear/modificar:
    • backend/src/services/igdbClient.tssearchGames(query, platform?), getGameById(id)
    • backend/src/services/rawgClient.tssearchGames(query), getGameById(id)
    • backend/src/services/thegamesdbClient.tssearchGames(query), getGameById(id)
    • backend/src/services/metadataService.tsenrichGame(romFile) (orquesta clientes, fallbacks, matching heurística)
    • backend/src/utils/cache.ts — caché en memoria o Redis (simple LRU)
    • backend/src/routes/metadata.ts — endpoints GET /api/metadata/search?q=...&platform=..., POST /api/metadata/enrich/:romFileId
  • Tests a escribir:
    • backend/tests/services/igdbClient.spec.ts — mock de respuestas IGDB, test de OAuth flow, test de búsqueda
    • backend/tests/services/rawgClient.spec.ts — mock de respuestas RAWG
    • backend/tests/services/metadataService.spec.ts — casos: match exacto, match parcial, sin match (fallback)
    • backend/tests/routes/metadata.spec.ts — test E2E de endpoints metadata
  • Pasos:
    1. Escribir tests con mocks (respuestas API simuladas)
    2. Implementar clientes (IGDB OAuth, RAWG key, TheGamesDB key) con retry y timeout
    3. Implementar metadataService con lógica de matching y fallbacks
    4. Implementar endpoints REST
    5. Ejecutar tests y verificar que pasan

Fase 6: Frontend base (React + Vite + shadcn/ui)

  • Objetivo: Configurar proyecto frontend con Vite, React, TypeScript, Tailwind CSS, shadcn/ui, TanStack Query, TanStack Router. Implementar layout base (navbar, sidebar), rutas (Home, ROMs, Games, Settings) y componentes UI básicos (Button, Card, Table, Dialog de shadcn/ui).
  • Archivos/Funciones a crear/modificar:
    • frontend/package.json — dependencias (react, vite, @shadcn/ui, tailwindcss, @tanstack/react-router, @tanstack/react-query)
    • frontend/tsconfig.json — configuración TypeScript frontend
    • frontend/vite.config.ts — configuración Vite (proxy a backend, aliases, TanStack Router plugin)
    • frontend/tailwind.config.js — configuración Tailwind para shadcn/ui
    • frontend/src/main.tsx — entry point con QueryClientProvider y RouterProvider
    • frontend/src/routes/__root.tsx — layout raíz con navbar y sidebar
    • frontend/src/routes/index.tsx — ruta Home
    • frontend/src/routes/roms.tsx — ruta ROMs
    • frontend/src/routes/games.tsx — ruta Games
    • frontend/src/components/layout/Navbar.tsx
    • frontend/src/components/layout/Sidebar.tsx
    • frontend/src/lib/api.ts — cliente HTTP base (fetch/axios wrapper)
    • frontend/src/lib/queryClient.ts — configuración de TanStack Query
    • frontend/src/hooks/useGames.ts — custom hook con TanStack Query para juegos
  • Tests a escribir:
    • frontend/tests/App.spec.tsx — renderizado de rutas (usando Vitest + React Testing Library)
    • frontend/tests/components/Navbar.spec.tsx — navegación básica
    • tests/e2e/navigation.spec.ts — E2E con Playwright (navegar entre páginas)
  • Pasos:
    1. Escribir tests que fallen (renderizado de App, navegación E2E)
    2. Configurar Vite + React + TypeScript + Tailwind + shadcn/ui + TanStack Query
    3. Implementar layout, rutas, páginas vacías, configuración de QueryClient
    4. Ejecutar tests y verificar que pasan

Fase 7: Gestión manual de juegos (frontend + backend)

  • Objetivo: CRUD completo para juegos: crear/editar/eliminar juegos manualmente (frontend form con shadcn/ui + TanStack Query), registrar juegos físicos/digitales con campos: nombre, plataforma, precio, condición (Loose/CIB/New), fecha de compra, vendedor, notas.
  • Archivos/Funciones a crear/modificar:
    • backend/src/routes/games.tsGET /api/games, POST /api/games, PUT /api/games/:id, DELETE /api/games/:id
    • backend/src/controllers/gamesController.ts — lógica de CRUD
    • backend/src/validators/gameValidator.ts — validación de input (Zod/Joi)
    • frontend/src/routes/games.tsx — tabla de juegos con acciones (editar, eliminar)
    • frontend/src/components/games/GameForm.tsx — formulario para crear/editar juego
    • frontend/src/components/games/GameCard.tsx — card de vista de juego
    • frontend/src/hooks/useGames.ts — custom hooks con TanStack Query (useGames, useCreateGame, useUpdateGame, useDeleteGame)
    • frontend/src/components/ui/* — shadcn/ui components (Form, Input, Select, Textarea, DatePicker)
  • Tests a escribir:
    • backend/tests/routes/games.spec.ts — CRUD endpoints (casos: crear juego válido, crear juego con datos faltantes, actualizar, eliminar)
    • frontend/tests/routes/games.spec.tsx — renderizado de lista, acciones
    • frontend/tests/components/GameForm.spec.tsx — validación de formulario
    • tests/e2e/games-crud.spec.ts — E2E completo (crear/editar/eliminar juego)
  • Pasos:
    1. Escribir tests que fallen (endpoints CRUD, renderizado de form, E2E CRUD)
    2. Implementar backend endpoints y validators
    3. Implementar frontend page, form, custom hooks con TanStack Query
    4. Ejecutar tests y verificar que pasan

Fase 8: Integración ROMs + Metadata (UI completa)

  • Objetivo: Vista de ROMs escaneados en frontend, botón para scan de directorio, búsqueda/asociación de metadata (UI para seleccionar resultado de IGDB/RAWG con TanStack Query), y vincular ROM con juego. Incluir vista de artwork (covers, screenshots).
  • Archivos/Funciones a crear/modificar:
    • frontend/src/routes/roms.tsx — tabla de ROMs escaneados, botón "Scan Directory", acciones (asociar metadata, ver detalles)
    • frontend/src/components/roms/ScanDialog.tsx — dialog para input de path y scan
    • frontend/src/components/roms/MetadataSearchDialog.tsx — búsqueda y selección de metadata
    • frontend/src/components/roms/RomCard.tsx — card con info de ROM + artwork
    • frontend/src/hooks/useRoms.ts — custom hooks con TanStack Query (useRoms, useScanDirectory, useEnrichMetadata)
    • backend/src/routes/artwork.tsGET /api/artwork/:gameId (proxy/cache de imágenes)
  • Tests a escribir:
    • frontend/tests/routes/roms.spec.tsx — renderizado de tabla, acciones
    • frontend/tests/components/ScanDialog.spec.tsx — submit de path, loading state
    • tests/e2e/roms-import.spec.ts — E2E: scan → ver ROMs → asociar metadata → ver juego enriquecido
  • Pasos:
    1. Escribir tests que fallen (UI de ROMs, scan dialog, E2E import completo)
    2. Implementar componentes frontend y custom hooks con TanStack Query
    3. Implementar endpoint de artwork (cache/proxy)
    4. Ejecutar tests y verificar que pasan

Fase 9: CI, tests E2E, docs y seguridad

  • Objetivo: GitHub Actions para CI (lint, tests unitarios, tests E2E con Playwright), configuración de ESLint/Prettier, docs de uso de APIs (cómo obtener keys), seguridad (env vars, .gitignore actualizado, SECURITY.md), y README completo.
  • Archivos/Funciones a crear/modificar:
    • .github/workflows/ci.yml — pipeline (install, lint, test, e2e)
    • .eslintrc.cjs — ajustar para backend + frontend
    • .prettierrc — ajustar formatos
    • README.md — actualizar con: setup, features, screenshots, roadmap
    • SECURITY.md — políticas de seguridad, reporte de vulnerabilidades
    • docs/API_KEYS.md — instrucciones para obtener keys de IGDB, RAWG, TheGamesDB
    • .env.example — template de variables de entorno
    • backend/.env.example, frontend/.env.example — templates específicos
  • Tests a escribir:
    • tests/e2e/full-flow.spec.ts — E2E completo end-to-end (scan → enrich → crear juego manual → view)
    • Asegurar que CI ejecuta todos los tests y Playwright genera reporte
  • Pasos:
    1. Configurar GitHub Actions workflow
    2. Ejecutar pipeline en CI (puede fallar inicialmente)
    3. Corregir issues de lint/format/tests
    4. Actualizar docs (README, SECURITY, API_KEYS)
    5. Ejecutar CI nuevamente y verificar que todo pasa

Preguntas abiertas resueltas

  1. App web self-hosted (server + frontend separados)
  2. Frontend: TypeScript + React + Vite + shadcn/ui + TanStack Query + TanStack Router
  3. Solo APIs públicas: IGDB (OAuth Twitch gratuito), RAWG (API key gratuita con atribución), TheGamesDB (API key gratuita)
  4. Sin integración con tiendas (Steam/GOG/PSN) en MVP; dejar preparado para futuro (campo storeId, storePlatform en modelo Game)
  5. Prioridad: gestión de ROMs de directorio + creación manual de juegos físicos/digitales

Decisiones técnicas clave 🔧

  • Monorepo: /backend y /frontend en el mismo repo, con workspaces de Yarn
  • Backend: Node.js + Express + TypeScript + Prisma + SQLite (migration a PostgreSQL posible en futuro)
  • Frontend: React + Vite + TypeScript + Tailwind CSS + shadcn/ui + TanStack Query + TanStack Router
  • APIs de metadata: IGDB (primary), RAWG (fallback), TheGamesDB (artwork/retro)
  • Tests: Backend (Vitest + Supertest), Frontend (Vitest + React Testing Library), E2E (Playwright)
  • CI: GitHub Actions con pipeline: install → lint → test → e2e
  • Seguridad: API keys en .env, no commitear secrets

Roadmap futuro (fuera del MVP) 🚀

  • Integración con tiendas (Steam/GOG/PSN/Xbox) para import automático de compras
  • Price tracking con PriceCharting/IsThereAnyDeal (requiere suscripción/API paga)
  • Plugins/extensiones (LaunchBox export, Playnite sync)
  • Sincronización en nube (opcional, con cifrado E2E)
  • Soporte para multiple usuarios (autenticación/autorización)
  • Mobile app (React Native o PWA)