# Búsqueda de Juegos ## Resumen La funcionalidad de búsqueda de juegos permite a los usuarios buscar metadatos de juegos desde múltiples fuentes externas (IGDB, RAWG, TheGamesDB) y agregarlos a su biblioteca personal. ## Arquitectura ### Backend #### Endpoints ##### `GET /api/metadata/search` Busca metadatos de juegos en múltiples fuentes externas. **Parámetros de query:** - `q` (string, requerido): Término de búsqueda del título del juego - `platform` (string, opcional): Plataforma para filtrar (ej. "NES", "SNES") - `year` (number, opcional): Año de lanzamiento para filtrar (1900-2100) **Respuesta:** ```typescript interface EnrichedGame { source: 'igdb' | 'rawg' | 'thegamesdb'; externalIds: { igdb?: number; rawg?: number; thegamesdb?: number; }; name: string; title: string; slug: string; releaseDate?: string; genres?: string[]; coverUrl?: string; platforms?: PlatformInfo[]; } ``` **Ejemplo de solicitud:** ```bash curl "http://localhost:3003/api/metadata/search?q=Sonic&platform=Genesis&year=1991" ``` ##### `POST /api/games/from-metadata` Crea un juego nuevo a partir de metadatos de búsqueda. **Body:** ```typescript interface CreateGameFromMetadataBody { metadata: EnrichedGame; overrides?: { platformId?: string; description?: string; priceCents?: number; currency?: string; store?: string; date?: string; condition?: 'Loose' | 'CIB' | 'New'; }; } ``` **Respuesta:** ```typescript interface Game { id: string; title: string; slug: string; description?: string; releaseDate?: string; genre?: string; platform?: string; year?: number; cover?: string; source: string; sourceId?: string; } ``` **Ejemplo de solicitud:** ```bash curl -X POST http://localhost:3003/api/games/from-metadata \ -H "Content-Type: application/json" \ -d '{ "metadata": { "source": "igdb", "externalIds": { "igdb": 12345 }, "name": "Sonic the Hedgehog", "slug": "sonic-the-hedgehog", "releaseDate": "1991-06-23", "genres": ["Platform"], "coverUrl": "https://example.com/cover.jpg" }, "overrides": { "description": "Juego clásico de SEGA", "condition": "CIB" } }' ``` #### Servicios ##### `metadataService.searchGames()` Orquesta la búsqueda en múltiples fuentes externas. **Parámetros:** ```typescript interface SearchGamesParams { title: string; platform?: string; year?: number; } ``` **Respuesta:** Array de `EnrichedGame[]` **Fuentes soportadas:** - **IGDB:** Base de datos de videojuegos más completa - **RAWG:** API de videojuegos con datos de múltiples fuentes - **TheGamesDB:** Base de datos comunitaria de videojuegos ### Frontend #### Página `/games/add` Página principal para buscar y agregar juegos a la biblioteca. **Componentes:** ##### `SearchForm` Formulario de búsqueda con los siguientes campos: - **Título** (requerido): Campo de texto para el título del juego - **Plataforma** (opcional): Dropdown con plataformas comunes - **Año** (opcional): Campo numérico para filtrar por año **Props:** ```typescript interface SearchFormProps { onSearch: (params: SearchGamesParams) => void; isLoading?: boolean; } ``` ##### `SearchResults` Muestra los resultados de la búsqueda en una lista. **Props:** ```typescript interface SearchResultsProps { results: EnrichedGame[]; onSelectResult: (result: EnrichedGame) => void; isLoading?: boolean; } ``` **Características:** - Muestra la portada del juego - Muestra el título, año y géneros - Indica la fuente de los datos (IGDB, RAWG, TheGamesDB) - Botón para seleccionar un resultado ##### `GamePreviewDialog` Dialog modal para previsualizar y editar los metadatos antes de guardar. **Props:** ```typescript interface GamePreviewDialogProps { open: boolean; game: EnrichedGame | null; onClose: () => void; onSave: (data: CreateGameFromMetadataInput) => void; } ``` **Características:** - Muestra la portada del juego - Campos editables: título, descripción, condición, plataforma - Botón para guardar el juego en la biblioteca #### API Client Funciones disponibles en `src/lib/api.ts`: ```typescript // Buscar juegos metadataApi.searchGames(params: SearchGamesParams): Promise // Crear juego desde metadatos metadataApi.createGameFromMetadata(data: CreateGameFromMetadataInput): Promise ``` ## Flujo de Usuario 1. El usuario navega a `/games/add` 2. Ingresa un título de búsqueda (opcionalmente plataforma y año) 3. Hace clic en "Buscar" 4. El frontend llama a `metadataApi.searchGames()` 5. El backend busca en IGDB, RAWG y TheGamesDB 6. Los resultados se muestran en `SearchResults` 7. El usuario selecciona un resultado 8. Se abre `GamePreviewDialog` con los metadatos 9. El usuario puede editar los campos según sea necesario 10. Hace clic en "Guardar" 11. El frontend llama a `metadataApi.createGameFromMetadata()` 12. El juego se crea en la base de datos 13. El usuario es redirigido a la página del juego ## Configuración ### Variables de Entorno **Backend:** ```env # IGDB IGDB_CLIENT_ID=your_client_id IGDB_CLIENT_SECRET=your_client_secret # RAWG RAWG_API_KEY=your_api_key # TheGamesDB THEGAMESDB_API_KEY=your_api_key ``` **Frontend:** ```env NEXT_PUBLIC_API_URL=http://localhost:3003/api ``` ## Tests ### Backend Tests - `tests/services/metadataService.spec.ts`: Tests del servicio de búsqueda - `tests/routes/metadata.spec.ts`: Tests de endpoints de metadatos - `tests/routes/games.spec.ts`: Tests de endpoints de juegos **Ejecutar tests:** ```bash cd backend yarn test ``` ### Frontend Tests - `src/components/games/__tests__/SearchForm.spec.ts`: Tests del formulario de búsqueda - `src/components/games/__tests__/SearchResults.spec.ts`: Tests de resultados de búsqueda - `src/components/games/__tests__/GamePreviewDialog.spec.ts`: Tests del diálogo de previsualización **Ejecutar tests:** ```bash cd frontend yarn test ``` ## Consideraciones de Diseño ### Múltiples Fuentes El sistema busca en múltiples fuentes simultáneamente para maximizar la probabilidad de encontrar resultados. Cada resultado incluye: - La fuente de los datos (`source`) - Los IDs externos (`externalIds`) para referencia futura ### Normalización de Datos Los datos de diferentes fuentes se normalizan a un formato común (`EnrichedGame`): - `name` y `title` se unifican - Las fechas se normalizan a formato ISO - Los géneros se mapean a strings - Las plataformas se normalizan ### Validación - Los parámetros de búsqueda se validan con Zod - Los datos de creación de juego se validan antes de persistir - Los campos opcionales tienen valores por defecto apropiados ### Error Handling - Errores de API externas no bloquean la búsqueda en otras fuentes - Errores de validación se devuelven con mensajes claros - Errores de red se manejan con reintentos y timeouts ## Rendimiento - Las búsquedas en múltiples fuentes se ejecutan en paralelo - Los resultados se cachean por un período corto - Las imágenes se cargan de forma diferida (lazy loading) ## Seguridad - Las claves de API se almacenan en variables de entorno - No se exponen credenciales en el frontend - Los inputs se validan y sanitizan - Se implementan rate limiting en las APIs externas ## Roadmap Futuro - [ ] Soporte para más fuentes de metadatos - [ ] Búsqueda avanzada con filtros adicionales - [ ] Sugerencias de búsqueda mientras se escribe - [ ] Importación masiva desde listas externas - [ ] Sincronización automática de metadatos