15 KiB
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 + Fastify + TypeScript + Prisma + 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:
- Crear documentos con información estructurada de la investigación inicial
- Incluir tablas comparativas, enlaces, y conclusiones
- 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 (Fastify + Prisma, 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 funcionalesdocs/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óndocs/data-model.md— entidades (Game, RomFile, Platform, Purchase, Artwork)
- Pasos:
- Crear documentos
docs/requirements.md,docs/architecture.md,docs/api-integration.md,docs/data-model.mdcon contenido inicial - Definir estructura de carpetas y convenciones de código
- Documentar decisiones técnicas y justificaciones
- Crear documentos
Fase 3: Backend base y modelo de datos
- Objetivo: Configurar backend (Fastify + 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 (fastify, prisma, @fastify/cors, dotenv, etc.)backend/tsconfig.json— configuración TypeScript backendbackend/src/index.ts— servidor Fastify inicialbackend/prisma/schema.prisma— modelos (Game, RomFile, Platform, Purchase, Artwork)backend/prisma/migrations/— migraciones Prismabackend/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:
- Escribir tests que fallen (healthcheck endpoint, crear modelo Game y validar)
- Configurar Fastify + Prisma, definir schema, ejecutar migración
- Implementar endpoint
/api/health - 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ónscanDirectory(path: string)backend/src/services/checksumService.ts— funcionescalculateCRC32(),calculateMD5(),calculateSHA1()backend/src/services/datVerifier.ts— funciónverifyAgainstDAT(romFiles, datPath)backend/src/routes/import.ts— endpointPOST /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 subdirectoriosbackend/tests/services/checksumService.spec.ts— calcular checksum de archivo fixturebackend/tests/services/datVerifier.spec.ts— verificar ROM válido/inválido contra DAT fixturebackend/tests/routes/import.spec.ts— test E2E de endpoint/api/import/scan
- Pasos:
- Crear fixtures (ROMs de prueba, DAT de prueba)
- Escribir tests que fallen (escaneo de carpeta, checksum, DAT verification)
- Implementar
fsScanner,checksumService,datVerifiermínimos - Implementar endpoint
/api/import/scan - 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.ts—searchGames(query, platform?),getGameById(id)backend/src/services/rawgClient.ts—searchGames(query),getGameById(id)backend/src/services/thegamesdbClient.ts—searchGames(query),getGameById(id)backend/src/services/metadataService.ts—enrichGame(romFile)(orquesta clientes, fallbacks, matching heurística)backend/src/utils/cache.ts— caché en memoria o Redis (simple LRU)backend/src/routes/metadata.ts— endpointsGET /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úsquedabackend/tests/services/rawgClient.spec.ts— mock de respuestas RAWGbackend/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:
- Escribir tests con mocks (respuestas API simuladas)
- Implementar clientes (IGDB OAuth, RAWG key, TheGamesDB key) con retry y timeout
- Implementar
metadataServicecon lógica de matching y fallbacks - Implementar endpoints REST
- 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 frontendfrontend/vite.config.ts— configuración Vite (proxy a backend, aliases, TanStack Router plugin)frontend/tailwind.config.js— configuración Tailwind para shadcn/uifrontend/src/main.tsx— entry point con QueryClientProvider y RouterProviderfrontend/src/routes/__root.tsx— layout raíz con navbar y sidebarfrontend/src/routes/index.tsx— ruta Homefrontend/src/routes/roms.tsx— ruta ROMsfrontend/src/routes/games.tsx— ruta Gamesfrontend/src/components/layout/Navbar.tsxfrontend/src/components/layout/Sidebar.tsxfrontend/src/lib/api.ts— cliente HTTP base (fetch/axios wrapper)frontend/src/lib/queryClient.ts— configuración de TanStack Queryfrontend/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ásicatests/e2e/navigation.spec.ts— E2E con Playwright (navegar entre páginas)
- Pasos:
- Escribir tests que fallen (renderizado de App, navegación E2E)
- Configurar Vite + React + TypeScript + Tailwind + shadcn/ui + TanStack Query
- Implementar layout, rutas, páginas vacías, configuración de QueryClient
- 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.ts—GET /api/games,POST /api/games,PUT /api/games/:id,DELETE /api/games/:idbackend/src/controllers/gamesController.ts— lógica de CRUDbackend/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 juegofrontend/src/components/games/GameCard.tsx— card de vista de juegofrontend/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, accionesfrontend/tests/components/GameForm.spec.tsx— validación de formulariotests/e2e/games-crud.spec.ts— E2E completo (crear/editar/eliminar juego)
- Pasos:
- Escribir tests que fallen (endpoints CRUD, renderizado de form, E2E CRUD)
- Implementar backend endpoints y validators
- Implementar frontend page, form, custom hooks con TanStack Query
- 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 scanfrontend/src/components/roms/MetadataSearchDialog.tsx— búsqueda y selección de metadatafrontend/src/components/roms/RomCard.tsx— card con info de ROM + artworkfrontend/src/hooks/useRoms.ts— custom hooks con TanStack Query (useRoms, useScanDirectory, useEnrichMetadata)backend/src/routes/artwork.ts—GET /api/artwork/:gameId(proxy/cache de imágenes)
- Tests a escribir:
frontend/tests/routes/roms.spec.tsx— renderizado de tabla, accionesfrontend/tests/components/ScanDialog.spec.tsx— submit de path, loading statetests/e2e/roms-import.spec.ts— E2E: scan → ver ROMs → asociar metadata → ver juego enriquecido
- Pasos:
- Escribir tests que fallen (UI de ROMs, scan dialog, E2E import completo)
- Implementar componentes frontend y custom hooks con TanStack Query
- Implementar endpoint de artwork (cache/proxy)
- 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 formatosREADME.md— actualizar con: setup, features, screenshots, roadmapSECURITY.md— políticas de seguridad, reporte de vulnerabilidadesdocs/API_KEYS.md— instrucciones para obtener keys de IGDB, RAWG, TheGamesDB.env.example— template de variables de entornobackend/.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:
- Configurar GitHub Actions workflow
- Ejecutar pipeline en CI (puede fallar inicialmente)
- Corregir issues de lint/format/tests
- Actualizar docs (README, SECURITY, API_KEYS)
- Ejecutar CI nuevamente y verificar que todo pasa
Preguntas abiertas resueltas ✅
- ✅ App web self-hosted (server + frontend separados)
- ✅ Frontend: TypeScript + React + Vite + shadcn/ui + TanStack Query + TanStack Router
- ✅ Solo APIs públicas: IGDB (OAuth Twitch gratuito), RAWG (API key gratuita con atribución), TheGamesDB (API key gratuita)
- ✅ Sin integración con tiendas (Steam/GOG/PSN) en MVP; dejar preparado para futuro (campo
storeId,storePlatformen modelo Game) - ✅ Prioridad: gestión de ROMs de directorio + creación manual de juegos físicos/digitales
Decisiones técnicas clave 🔧
- Monorepo:
/backendy/frontenden el mismo repo, con workspaces de Yarn - Backend: Node.js + Fastify + 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)