## 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.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` — 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.ts` — `GET /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.ts` — `GET /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)