Refactor code structure for improved readability and maintainability
Some checks failed
CI / lint (push) Failing after 1m4s
CI / test-backend (push) Has been skipped
CI / test-frontend (push) Has been skipped
CI / test-e2e (push) Has been skipped

This commit is contained in:
2026-02-22 18:18:46 +01:00
parent c27e9bec7a
commit 0c9c408564
98 changed files with 8207 additions and 5250 deletions

View File

@@ -1,28 +0,0 @@
## Phase 1 Complete: Análisis comparativo de proyectos y servicios
TL;DR: Se crearon y completaron cuatro documentos de análisis en `docs/` que resumen proyectos relevantes, APIs públicas y consideraciones legales para el MVP. Los documentos incluyen matrices comparativas, enlaces a TOS/repositorios y recomendaciones técnicas y legales.
**Files created/changed:**
- `docs/competitive-analysis.md` — análisis por proyecto (resumen, licencia, funcionalidades, riesgos) y tabla comparativa
- `docs/apis-comparison.md` — comparativa de APIs (auth, data types, fecha verificación, TOS y columna "Licencia / Nota legal")
- `docs/legal-considerations.md` — riesgos legales, recomendaciones operativas y fragmentos de disclaimer para UI/README
- `docs/lessons-learned.md` — lista priorizada de funcionalidades, PoC propuesta y recomendaciones técnicas
**Functions created/changed:**
- Ninguna (documentación)
**Tests created/changed:**
- Ninguno (el usuario solicitó no crear tests para esta fase)
**Review Status:** APPROVED ✅
**Git Commit Message:**
chore: add comparative analysis docs
- Add `docs/competitive-analysis.md` with project summaries and comparison table
- Add `docs/apis-comparison.md` with API TOS links and license notes
- Add `docs/legal-considerations.md` and `docs/lessons-learned.md` with recommendations and PoC
- Add `Metadatos` block (Autor / Fecha verificación: 2026-02-07 / Última actualización)

View File

@@ -1,31 +0,0 @@
## Phase 2 Complete: Requisitos y diseño técnico
TL;DR: Se documentaron y finalizaron los requisitos funcionales y no funcionales del MVP, el diseño de arquitectura (monorepo, stack propuesto) y el modelo de datos inicial para `Game`, `RomFile`, `Platform`, `Artwork`, `Purchase` y `PriceHistory`.
**Files created/changed:**
- `docs/requirements.md`
- `docs/architecture.md`
- `docs/api-integration.md`
- `docs/data-model.md`
- `plans/gestor-coleccion-plan.md` (plan maestro actualizado)
**Functions created/changed:**
- Ninguna (documentación)
**Tests created/changed:**
- Ninguno (recomendación: añadir tests que verifiquen la presencia y metadatos de los documentos claves si se automatiza la validación de docs en CI)
**Review Status:** APPROVED ✅ (con recomendación menor: añadir `docs/legal-considerations.md` si falta para cubrir riesgos legales antes de integrar scraping o descargas masivas)
**Git Commit Message:**
```
chore(docs): completar Fase 2 — requisitos y arquitectura
- Añade/actualiza `docs/requirements.md`, `docs/architecture.md`, `docs/api-integration.md`, `docs/data-model.md`
- Documenta criterios de aceptación y decisiones técnico-arquitectónicas
- Recomendación: añadir `docs/legal-considerations.md` (pendiente)
```

View File

@@ -1,69 +0,0 @@
## Phase 3 Complete: ArchiveReader
TL;DR: Implementado `archiveReader` para listar entradas dentro de contenedores ZIP y 7z usando utilidades del sistema (`7z` y `unzip` como fallback). Añadidos tests unitarios que mockean las llamadas a `child_process.exec` para validar parsing y comportamiento de fallback.
**Files created/changed:**
- backend/src/services/archiveReader.ts
- backend/tests/services/archiveReader.spec.ts
**Functions created/changed:**
- `listArchiveEntries(filePath, logger)` — lista entradas de ZIP/7z usando `7z -slt` y `unzip -l` como fallback.
**Tests created/changed:**
- `backend/tests/services/archiveReader.spec.ts` — cubre:
- listado con salida simulada de `7z -slt`
- fallback a `unzip -l` si `7z` falla
- comportamiento para formatos no soportados
**Review Status:** APPROVED
**Git Commit Message:**
feat: add archive reader and tests
- Añade `archiveReader` que lista entradas en ZIP/7z con fallback a `unzip`
- Añade tests unitarios que mockean `child_process.exec` para validar parsing
- Documenta dependencia de binarios en README y CI (pasos previos)
## Phase 3 Complete: Backend base y modelo de datos
Fase completada: configuré el backend mínimo (dependencias, Prisma schema), generé el cliente Prisma y aseguré que los tests TDD de backend pasan.
**Files created/changed:**
- backend/package.json
- backend/prisma/schema.prisma
- backend/tests/models/game.spec.ts
- package.json
- .yarnrc.yml
- prisma-client/package.json
**Files generados por herramientas (no necesariamente versionadas):**
- prisma-client/client/\* (Prisma Client generado)
- node_modules/.prisma/client/\* (artefacto runtime generado)
**Functions / cambios clave:**
- Ajustes en `backend/tests/models/game.spec.ts` para fallback de carga del cliente Prisma generado.
- `backend/prisma/schema.prisma`: definición de modelos (Game, RomFile, Platform, Purchase, Artwork, Tag, PriceHistory) ya presente; ajustado el `generator client` para flujo de generación local.
**Tests created/changed:**
- backend/tests/models/game.spec.ts (modificado: mejor manejo de require/generación del cliente)
- backend/tests/server.spec.ts (existente — pase verificable)
**Migraciones aplicadas durante pruebas:**
- `backend/prisma/migrations/20260208102247_init/migration.sql` (aplicada en DB temporal de test)
**Review Status:** APPROVED
**Git Commit Message:**
feat: backend base, Prisma schema, client gen and tests
- Añade/ajusta `backend` para usar Prisma y Vitest
- Genera cliente Prisma y corrige resoluciones PnP/node-modules
- Actualiza tests para cargar cliente generado y pasar TDD

View File

@@ -1,29 +0,0 @@
## Phase 4 Complete: DAT verifier
TL;DR: Implementado `datVerifier` para parsear archivos DAT (XML) y verificar hashes de ROMs (CRC/MD5/SHA1/size). Se añadieron tests TDD y una fixture XML; los tests específicos pasan y se aplicó un parche menor de calidad.
**Files created/changed:**
- backend/src/services/datVerifier.ts
- backend/tests/services/datVerifier.spec.ts
- backend/tests/fixtures/sample.dat.xml
- backend/package.json (se añadió `fast-xml-parser` en devDependencies)
**Functions created/changed:**
- `parseDat(xml: string): DatDatabase` — parsea y normaliza la estructura DAT a un modelo en memoria.
- `verifyHashesAgainstDat(datDb: DatDatabase, hashes): {gameName, romName, matchedOn} | null` — verifica hashes contra el DAT y devuelve la coincidencia.
**Tests created/changed:**
- `backend/tests/services/datVerifier.spec.ts` — cubre parsing, match por CRC/MD5/SHA1/size y ausencia de match.
- `backend/tests/fixtures/sample.dat.xml` — fixture usada por las pruebas.
**Review Status:** APPROVED with minor recommendations
**Git Commit Message:**
feat: add datVerifier and tests
- Añade `datVerifier` con `parseDat` y `verifyHashesAgainstDat`
- Añade tests y fixture XML para validar matching por CRC/MD5/SHA1/size
- Añade `fast-xml-parser` en `backend/package.json` (devDependency)

View File

@@ -1,31 +0,0 @@
## Phase 5 Complete: Job runner en memoria
TL;DR: Se implementó un runner en memoria (`ImportRunner`) con control de concurrencia configurable, API de encolado (`enqueue`), estado (`getStatus`) y utilidades de parada (`stop`, `stopAndWait`). Se añadieron tests TDD que cubren concurrencia, rechazo tras `stop` y contabilización de tareas completadas. La ruta de importación ahora encola jobs en background y registra errores.
**Files created/changed:**
- backend/src/config.ts
- backend/src/jobs/importRunner.ts
- backend/src/routes/import.ts
- backend/tests/jobs/importRunner.spec.ts
- backend/tsconfig.json
**Functions created/changed:**
- `ImportRunner` (class) — `enqueue`, `getStatus`, `start`, `stop`, `stopAndWait`.
- `runner` (singleton) — instanciado y arrancado por defecto.
- `IMPORT_CONCURRENCY` (export) in `config.ts`.
**Tests created/changed:**
- `backend/tests/jobs/importRunner.spec.ts` — 56 tests (enqueue result, concurrencia, getStatus, rechazo tras stop, completed incrementa en rechazo).
**Review Status:** APPROVED
**Git Commit Message:**
feat: import job runner in-memory
- Añade `ImportRunner` en memoria con concurrencia configurable
- Tests TDD para enqueue, concurrencia y comportamiento tras `stop`
- Actualiza `/api/import/scan` para encolar jobs y registrar errores
- Ajusta `tsconfig.json` para incluir `tests` en comprobaciones de tipo

View File

@@ -1,49 +0,0 @@
## Phase 6 Complete: Frontend base (React + Vite + shadcn/ui)
Se scaffoldó el frontend mínimo con Vite + React + TypeScript, configuración de Vitest y pruebas básicas. Los tests unitarios escritos pasan correctamente y el proyecto contiene los componentes y rutas base necesarios para continuar con la Fase 7.
**Files created/changed:**
- frontend/package.json
- frontend/tsconfig.json
- frontend/vite.config.ts
- frontend/vitest.config.ts
- frontend/index.html
- frontend/postcss.config.cjs
- frontend/tailwind.config.cjs
- frontend/src/main.tsx
- frontend/src/App.tsx
- frontend/src/components/layout/Navbar.tsx
- frontend/src/components/layout/Sidebar.tsx
- frontend/src/routes/index.tsx
- frontend/src/routes/roms.tsx
- frontend/src/routes/games.tsx
- frontend/src/lib/queryClient.ts
- frontend/src/lib/api.ts
- frontend/src/hooks/useGames.ts
- frontend/src/styles.css
- frontend/src/setupTests.ts
- frontend/tests/App.spec.tsx
- frontend/tests/components/Navbar.spec.tsx
**Functions created/changed:**
- `App` component (frontend/src/App.tsx)
- `Navbar` component (frontend/src/components/layout/Navbar.tsx)
- `Sidebar` placeholder (frontend/src/components/layout/Sidebar.tsx)
- `queryClient` export (frontend/src/lib/queryClient.ts)
- `useGames` hook (stub) (frontend/src/hooks/useGames.ts)
**Tests created/changed:**
- frontend/tests/App.spec.tsx
- frontend/tests/components/Navbar.spec.tsx
**Review Status:** APPROVED
**Git Commit Message:**
feat: scaffold frontend base (Vite + React + Vitest)
- Añade scaffold de frontend con Vite y React
- Configura Vitest y tests básicos (App, Navbar)
- Añade QueryClient y hooks/plantillas iniciales

View File

@@ -1,121 +0,0 @@
## Phase 7 Complete: Gestión manual de juegos (frontend + backend)
Se implementó el CRUD completo para juegos: endpoints REST en backend (GET/POST/PUT/DELETE /api/games), validación con Zod, y frontend con formulario reactivo, tabla de juegos, y custom hooks con TanStack Query. Todos los tests unitarios y de integración pasan exitosamente.
**Files created/changed:**
### Backend
- backend/src/routes/games.ts
- backend/src/controllers/gamesController.ts
- backend/src/validators/gameValidator.ts
- backend/tests/routes/games.spec.ts
### Frontend
- frontend/src/routes/games.tsx
- frontend/src/components/games/GameForm.tsx
- frontend/src/components/games/GameCard.tsx
- frontend/src/hooks/useGames.ts
- frontend/tests/routes/games.spec.tsx
- frontend/tests/components/GameForm.spec.tsx
**Functions created/changed:**
### Backend
- `GamesController.listGames()` - Obtiene todos los juegos
- `GamesController.createGame()` - Crea un nuevo juego con validación
- `GamesController.updateGame()` - Actualiza un juego existente
- `GamesController.deleteGame()` - Elimina un juego
### Frontend
- `GameForm` component - Formulario para crear/editar juegos con validación Zod
- `GameCard` component - Card para mostrar detalles de un juego
- `useGames()` hook - Obtiene lista de juegos (TanStack Query)
- `useCreateGame()` hook - Crear nuevo juego (TanStack Query mutation)
- `useUpdateGame()` hook - Actualizar juego (TanStack Query mutation)
- `useDeleteGame()` hook - Eliminar juego (TanStack Query mutation)
- Games page component - Tabla de juegos con acciones (crear, editar, eliminar)
**Tests created/changed:**
### Backend
- tests/routes/games.spec.ts - 11 tests (CRUD endpoints)
- GET /api/games: list empty, list with games
- POST /api/games: create valid, missing required, empty title, required fields only
- PUT /api/games/:id: update existing, 404 not found, partial update
- DELETE /api/games/:id: delete existing, 404 not found
### Frontend
- tests/routes/games.spec.tsx - 10 tests (Games page)
- Render games table
- Mock TanStack Query hooks
- Display loading state
- Display empty state
- Render action buttons
- tests/components/GameForm.spec.tsx - 8 tests (GameForm component)
- Render required and optional fields
- Validate required title field
- Validate required platform field
- Submit valid form data
- Allow optional fields empty
- Populate with initial data
- Show loading state
**Test Results:**
- Backend: 11 tests passed ✅ (games.spec.ts)
- Backend total: 46 passed, 1 skipped ✅
- Frontend: 22 tests passed ✅ (4 test files)
- GameForm: 8 passed
- Games page: 10 passed
- App: 2 passed
- Navbar: 2 passed
- Lint: 0 errors, 12 warnings ✅
**Review Status:** APPROVED
**Key Features Implemented:**
1. **Backend CRUD API**
- RESTful endpoints for complete game lifecycle
- Input validation with Zod schema
- Error handling with proper HTTP status codes
- Prisma integration for database operations
2. **Frontend Components**
- React Hook Form + Zod for form validation
- TanStack Query for state management and caching
- Responsive UI with Tailwind CSS
- Loading and error states
3. **Type Safety**
- TypeScript throughout
- Zod schemas for runtime validation
- Proper type inference in React components
**Git Commit Message:**
```
feat: implement games CRUD (Phase 7)
Backend:
- Add REST endpoints: GET, POST, PUT, DELETE /api/games
- Implement GamesController with CRUD logic
- Add Zod validator for game input validation
- Add 11 comprehensive tests for all endpoints
Frontend:
- Create GameForm component with React Hook Form + Zod
- Create GameCard component for game display
- Implement useGames, useCreateGame, useUpdateGame, useDeleteGame hooks
- Add Games page with table and action buttons
- Add 18 component and page tests with 100% pass rate
All tests passing: 46 backend + 22 frontend tests
```

View File

@@ -1,133 +0,0 @@
## 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

@@ -1,73 +0,0 @@
## 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.

View File

@@ -1,214 +0,0 @@
# Phase 9 Complete: CI/CD, Tests E2E, Documentación y Seguridad
**Fase 9** cierra el MVP con automación completa, documentación de seguridad, tests E2E, y asegura que el proyecto es reproducible y listo para deployment público.
## Fases Completadas: 5 de 5
**9.1**: Variables de Entorno (.env.example templates)
**9.2**: Documentación de Seguridad (SECURITY.md, docs/API_KEYS.md)
**9.3**: Tests E2E con Playwright (15 tests multi-navegador)
**9.4**: Gitea Actions CI Workflow (.gitea/workflows/ci.yml)
**9.5**: README Actualizado y Verificación Final
## Archivos Creados/Modificados
### Configuración de Entorno
- [.env.example](.env.example) — Variables globales template
- [backend/.env.example](backend/.env.example) — Variables backend template
- [frontend/.env.example](frontend/.env.example) — Variables frontend template
### Documentación
- [README.md](README.md) — Actualizado con setup mínimo y links a docs
- [SECURITY.md](SECURITY.md) — Políticas de seguridad, vulnerabilidades, secrets
- [docs/API_KEYS.md](docs/API_KEYS.md) — Guía paso-a-paso para IGDB, RAWG, TheGamesDB
- [frontend/README.md](frontend/README.md) — Setup específico del frontend
### CI/CD
- [.gitea/workflows/ci.yml](.gitea/workflows/ci.yml) — Workflow Gitea Actions completo
- Job lint (ESLint)
- Job test-backend (Vitest + SQLite)
- Job test-frontend (Vitest)
- Job test-e2e (Playwright) - BLOQUEANTE
### Tests
- [tests/env-example.spec.ts](tests/env-example.spec.ts) — 13 tests validando .env.example files
- [tests/documentation.spec.ts](tests/documentation.spec.ts) — 12 tests validando SECURITY.md y API_KEYS.md
- [tests/gitea-workflow.spec.ts](tests/gitea-workflow.spec.ts) — 12 tests validando estructura del workflow
- [tests/readme-validation.spec.ts](tests/readme-validation.spec.ts) — 12 tests validando README
- [tests/e2e/full-flow.spec.ts](tests/e2e/full-flow.spec.ts) — 15 tests E2E (5 scenarios × 3 navegadores)
## Tests Creados/Modificados
### Tests de Fase 9 (49 tests nuevos)
- ✅ 13 tests env-example (validar .env.example files)
- ✅ 12 tests documentation (validar SECURITY.md y API_KEYS.md)
- ✅ 12 tests gitea-workflow (validar .gitea/workflows/ci.yml)
- ✅ 12 tests readme-validation (validar README.md structure)
- ✅ 15 tests E2E (5 scenarios × 3 navegadores: chromium, firefox, webkit)
### Total de Tests del Proyecto
- Backend Unit Tests: 63+ ✅
- Frontend Unit Tests: 59+ ✅
- Configuration Tests: 49+ ✅ (nuevos en Fase 9)
- E2E Tests: 15 ✅
- **TOTAL: 186+ tests ✅**
## Validación Final
### ✅ Lint Status
```
0 errores nuevos
12 warnings pre-existentes (no-console, no-var-requires)
```
### ✅ Tests Fase 9
```
✓ tests/env-example.spec.ts (13 tests)
✓ tests/documentation.spec.ts (12 tests)
✓ tests/gitea-workflow.spec.ts (12 tests)
✓ tests/readme-validation.spec.ts (12 tests)
✓ tests/e2e/full-flow.spec.ts (15 tests)
```
### ✅ Estructura del Proyecto
```
.env.example ✓
.env.*.example ✓
backend/.env.example ✓
frontend/.env.example ✓
.gitea/workflows/ci.yml ✓
SECURITY.md ✓
docs/API_KEYS.md ✓
README.md (actualizado) ✓
frontend/README.md ✓
tests/e2e/ ✓
```
### ✅ Reproducibilidad End-to-End
- Clone → ✓
- Install (yarn install) → ✓
- .env setup → ✓
- Migrations → ✓
- All tests pass → ✓
- Build frontend → ✓
## Git Commits Sugeridos
### Commit 9.1
```
feat: add .env.example templates for development setup
- Create .env.example with database and API key placeholders
- Add backend/.env.example for backend development
- Add frontend/.env.example for Vite frontend config
- Add tests/env-example.spec.ts with 13 validation tests
- Verify .gitignore correctly ignores .env files
```
### Commit 9.2
```
docs: add SECURITY.md and API_KEYS.md documentation
- Create SECURITY.md with vulnerability reporting policy
- Add environment variables & secrets best practices
- Document input validation and rate limiting strategies
- Create docs/API_KEYS.md with step-by-step API credential guides
- Update README.md with security and API configuration sections
- Add tests/documentation.spec.ts with 12 validation tests
```
### Commit 9.3
```
test: add E2E tests covering full user journeys
- Create tests/e2e/full-flow.spec.ts with 5 E2E scenarios
- Test home page navigation and layout
- Test game creation via form
- Test metadata search functionality
- Test ROM-to-game linking workflow
- Test complete user journey: create → search → link → view
- Configure Playwright for multi-browser testing (chromium, firefox, webkit)
```
### Commit 9.4
```
ci: add Gitea Actions workflow for automated testing
- Create .gitea/workflows/ci.yml with 4 sequential jobs
- Add lint, test-backend, test-frontend, test-e2e jobs
- Configure Gitea Secrets for IGDB, RAWG, TheGamesDB API keys
- Add artifact upload for Playwright reports on failure
- Update SECURITY.md with CI/CD Secrets setup instructions
- Update docs/API_KEYS.md with production Gitea workflow guide
- Add tests/gitea-workflow.spec.ts with 12 validation tests
```
### Commit 9.5
```
docs: update README and add frontend documentation
- Rewrite README.md with minimal but complete structure
- Add Features, Quick Start, Installation, Testing sections
- Add Project Structure with folder tree
- Add Configuration, Troubleshooting guides
- Add links to SECURITY.md and docs/API_KEYS.md
- Create frontend/README.md with React-specific setup
- Add tests/readme-validation.spec.ts with 12 validation tests
- Verify end-to-end reproducibility
```
## Review Status
**APPROVED** — Todas las fases de Fase 9 completadas
## Next Steps
1. **Commit todas las fases** (git commit y push)
2. **Trigger Gitea Actions** (push a main or develop)
3. **Verificar CI workflow** en Gitea UI
4. **Setup API Secrets** en Gitea (repo settings)
5. **Documentar deployment** en docs/ si es necesario
## Recomendaciones para Siguiente Fase (v1.1.0)
Si hay Fase 10+, considerar:
- [ ] OAuth Twitch integration (IGDB)
- [ ] Game screenshots/gallery view
- [ ] More metadata APIs (MobyGames, HLTB)
- [ ] Platform/genre filtering
- [ ] Favorites/ratings system
- [ ] Backup/restore functionality
- [ ] Docker deployment guide
---
## MVP v1.0.0 Status: 🚀 LISTO
**Quasar es un proyecto MVP completo, documentado, testeado y listo para deployment público en Gitea.**
- ✅ 186+ tests pasando
- ✅ Documentación completa
- ✅ CI/CD automatizado
- ✅ E2E tests validando flujos reales
- ✅ Seguridad documentada
- ✅ Reproducible desde cero
**Date**: 2026-02-12
**Version**: v1.0.0
**Status**: Production Ready (MVP) 🎮

View File

@@ -1,237 +0,0 @@
## 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:**
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 (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 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 (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 backend
- `backend/src/index.ts` — servidor Fastify 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 Fastify + 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 + 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)