feat: implement ROMs management UI (Phase 8)

Backend (Phase 8.1):
- Add ROMs endpoints: GET, GET/:id, PUT/:id/game, DELETE
- Add metadata search endpoint using IGDB/RAWG/TGDB
- Implement RomsController with ROM CRUD logic
- Add 12 comprehensive ROM endpoint tests
- Configure Vitest to run tests sequentially (threads: false)
- Auto-apply Prisma migrations in test setup

Frontend (Phase 8.2 + 8.3):
- Create ROM types: RomFile, Artwork, EnrichedGame
- Extend API client with roms and metadata namespaces
- Implement 5 custom hooks with TanStack Query
- Create ScanDialog, MetadataSearchDialog, RomCard components
- Rewrite roms.tsx page with table and all actions
- Add 37 comprehensive component and page tests

All 122 tests passing: 63 backend + 59 frontend
Lint: 0 errors, only unused directive warnings
This commit is contained in:
2026-02-12 19:52:59 +01:00
parent 630ebe0dc8
commit 571ac97f00
22 changed files with 2221 additions and 4 deletions

View File

@@ -0,0 +1,133 @@
## Phase 8 Complete: Integración ROMs + Metadata (UI completa)
Se implementó el flujo completo de gestión de ROMs: endpoints REST en backend, tipos y hooks en frontend, componentes interactivos (ScanDialog, MetadataSearchDialog, RomCard), tabla de ROMs con CRUD completo, integración con búsqueda de metadata (IGDB/RAWG/TheGamesDB), y vinculación con juegos. Todos los 122 tests pasan (63 backend + 59 frontend).
**Files created/changed:**
### Backend (Fase 8.1)
- backend/src/controllers/romsController.ts
- backend/src/routes/roms.ts
- backend/src/routes/metadata.ts
- backend/src/app.ts (registrar rutas)
- backend/tests/routes/roms.spec.ts (12 tests)
- backend/tests/routes/metadata.spec.ts
- backend/vitest.config.ts (threads: false para BD)
- backend/tests/setup.ts (migrations en setup)
- backend/tests/routes/games.spec.ts (actualizado beforeEach)
### Frontend (Fase 8.2 + 8.3)
- frontend/src/types/rom.ts
- frontend/src/lib/api.ts (extendido)
- frontend/src/hooks/useRoms.ts (5 custom hooks)
- frontend/src/components/roms/ScanDialog.tsx
- frontend/src/components/roms/MetadataSearchDialog.tsx
- frontend/src/components/roms/RomCard.tsx
- frontend/src/routes/roms.tsx (reescrito)
- frontend/tests/routes/roms.spec.tsx (13 tests)
- frontend/tests/components/ScanDialog.spec.tsx (11 tests)
- frontend/tests/components/MetadataSearchDialog.spec.tsx (13 tests)
**Functions created/changed:**
### Backend
- `RomsController.listRoms()` — Listar ROMs con opcional filtros
- `RomsController.getRomById()` — Obtener por ID
- `RomsController.linkGameToRom()` — Vincular juego a ROM
- `RomsController.deleteRom()` — Eliminar ROM
### Frontend
- `useRoms()` — Query para listar
- `useScanDirectory()` — Mutation para scan
- `useEnrichMetadata()` — Mutation para búsqueda
- `useLinkGameToRom()` — Mutation para vincular
- `useDeleteRom()` — Mutation para eliminar
- `ScanDialog` — Dialog input path
- `MetadataSearchDialog` — Dialog búsqueda metadata
- `RomCard` — Card display ROM
- `Roms` page — Tabla completa + dialogs
**Tests created/changed:**
### Backend
- 12 tests en roms.spec.ts: CRUD ROMs (lista, detail, link, delete)
- Métadata search tests (con y sin resultados)
- Total: 63 backend tests all passing ✅
### Frontend
- 13 tests en roms.spec.tsx: tabla, acciones, states
- 11 tests en ScanDialog.spec.tsx: input, submit, loading
- 13 tests en MetadataSearchDialog.spec.tsx: búsqueda, resultados, select
- Total: 59 frontend tests all passing ✅
**Test Results:**
- Backend: 63 passed (16 test files, 1 skipped) ✅
- Frontend: 59 passed (7 test files) ✅
- Total: 122 tests all passing ✅
- Lint: 0 errors, 12 warnings (solo directivas no utilizadas) ✅
**Review Status:** APPROVED
**Key Features Implemented:**
1. **Backend ROM Management**
- RESTful endpoints for ROMs
- Metadata search endpoint (orquesta IGDB, RAWG, TheGamesDB)
- Link ROM to existing Game
- Delete ROM with cascading
2. **Frontend UI Components**
- Scan dialog with path input
- Metadata search dialog with results
- ROM card display
- ROMs page with table and actions
- All using shadcn/ui, React Hook Form, TanStack Query
3. **Type Safety**
- RomFile interface (con relaciones)
- Artwork interface
- EnrichedGame interface (búsqueda results)
- ScanResult interface
4. **State Management**
- TanStack Query for API calls
- Proper cache invalidation on mutations
- Error and loading states in UI
5. **Integration**
- Backend ROMs connect to existing Games
- Metadata search uses existing IGDB/RAWG/TGDB clients
- DB migrations auto-applied in tests
**Git Commit Message:**
```
feat: implement ROMs management UI (Phase 8)
Backend (Phase 8.1):
- Add ROMs endpoints: GET, GET/:id, PUT/:id/game, DELETE
- Add metadata search endpoint using IGDB/RAWG/TGDB
- Implement RomsController with ROM CRUD logic
- Add 12 comprehensive ROM endpoint tests
- Configure Vitest to run tests sequentially (threads: false)
- Auto-apply Prisma migrations in test setup
Frontend (Phase 8.2 + 8.3):
- Create ROM types: RomFile, Artwork, EnrichedGame
- Extend API client with roms and metadata namespaces
- Implement custom hooks: useRoms, useScanDirectory, useEnrichMetadata, useLinkGameToRom, useDeleteRom
- Create ScanDialog component for directory scanning
- Create MetadataSearchDialog component for metadata lookup
- Create RomCard component for ROM display
- Rewrite roms.tsx page with table and all actions
- Add 37 comprehensive component and page tests
All 122 tests passing: 63 backend + 59 frontend
Lint: 0 errors
```

View File

@@ -0,0 +1,73 @@
## Plan: Fase 8 - Integración ROMs + Metadata (UI completa)
Implementar UI completa para gestionar ROMs: tabla con scan de directorios, búsqueda de metadata en IGDB/RAWG/TheGamesDB, vinculación con juegos, y visualización de artwork. Se reutiliza infraestructura backend existente (import, metadata clients) y se crean nuevos endpoints + componentes frontend.
**Sub-Fases: 3**
---
### **Fase 8.1: Backend ROMs API endpoints + Controller**
- **Objetivo:** Endpoints REST para listar ROMs, búsqueda de metadata, vincular ROM a juego
- **Archivos/Funciones a crear/modificar:**
- `backend/src/controllers/romsController.ts``listRoms()`, `getRomById()`, `linkGameToRom()`, `deleteRom()`
- `backend/src/routes/roms.ts``GET /api/roms`, `GET /api/roms/:id`, `PUT /api/roms/:id/game`, `DELETE /api/roms/:id`
- `backend/src/routes/metadata.ts``GET /api/metadata/search?q=query` (orquesta metadataService)
- **Tests a escribir:**
- `backend/tests/routes/roms.spec.ts` — lista vacía/con ROMs, get by id, link game, delete
- `backend/tests/routes/metadata.spec.ts` — búsqueda con results, sin results, mixed sources
- **Steps:**
1. Write tests (failing) — casos para CRUD + search
2. Implement romsController + routes
3. Run tests → pass
4. Lint + format
---
### **Fase 8.2: Frontend Types + API client + Custom Hooks**
- **Objetivo:** Tipos, cliente HTTP extendido, custom hooks con TanStack Query
- **Archivos/Funciones a crear/modificar:**
- `frontend/src/types/rom.ts``RomFile`, `Artwork`, `EnrichedGame`
- `frontend/src/lib/api.ts` — extender con `api.roms.*` y `api.metadata.*` namespaces
- `frontend/src/hooks/useRoms.ts``useRoms()`, `useScanDirectory()`, `useEnrichMetadata()`, `useLinkGameToRom()`
- **Tests a escribir:**
- Skipped por ahora (cubiertos en 8.3 con integration tests de páginas)
- **Steps:**
1. Create ROM types (RomFile, Artwork templates from Prisma schema)
2. Extend api.ts with roms and metadata namespaces
3. Implement hooks with TanStack Query (useQuery for list, useMutation for actions)
4. Format
---
### **Fase 8.3: Frontend Components + ROMs Page**
- **Objetivo:** Componentes UI para ROMs y tabla interactiva
- **Archivos/Funciones a crear/modificar:**
- `frontend/src/components/roms/ScanDialog.tsx` — input path + button submit, loading state
- `frontend/src/components/roms/MetadataSearchDialog.tsx` — search input + results list + select
- `frontend/src/components/roms/RomCard.tsx` — card display (simple card con info ROM)
- `frontend/src/routes/roms.tsx` — reescribir con tabla, botones (scan, link, delete), dialogs
- **Tests a escribir:**
- `frontend/tests/routes/roms.spec.tsx` — tabla, botones, acciones, empty/loading states
- `frontend/tests/components/ScanDialog.spec.tsx` — input validation, submit
- `frontend/tests/components/MetadataSearchDialog.spec.tsx` — search results display
- **Steps:**
1. Write tests (failing) para página y componentes
2. Crear componentes (ScanDialog, MetadataSearchDialog, RomCard, roms.tsx page)
3. Tests → pass
4. Format + lint
---
### **Open Questions**
1. ¿Agregar endpoint `GET /api/artwork/:gameId` (P1) o mantenerlo para Fase 9?
- **Respuesta:** Mantener para Fase 9 (artwork.ts). Fase 8 usa URLs directas de IGDB/RAWG.
2. ¿Cachear artwork localmente o usar proxy directo desde IGDB/RAWG?
- **Respuesta:** URLs directas de APIs (simples para Fase 8). Caché en Fase 9.
3. ¿Permitir batch scan (múltiples directorios) en Fase 8?
- **Respuesta:** No, un directorio por operación.