CHANGELOG.md
Rama main · réplica de lectura del repositorio original.
# Registro de cambios
Todos los cambios notables de este proyecto se documentan en este archivo.
El formato se basa en [Keep a Changelog](https://keepachangelog.com/es-ES/1.1.0/),
y este proyecto sigue [Versionado Semantico](https://semver.org/lang/es/).
> English version: [CHANGELOG.en.md](CHANGELOG.en.md)
## [Sin publicar]
### Mantenimiento
- Retirado el ejecutor de agentes en desuso y sus dependencias exclusivas de desarrollo.
- Retirados los informes internos de auditoría y planes de ejecución del código público; las exclusiones de Git y Docker ahora cubren los artefactos locales de automatización y worktrees.
- Retirados los planes de implementación ya completados y el alias redundante del README; actualizada la guía de contribución para el código TypeScript actual.
- Limitado el contexto de Docker a los archivos necesarios para compilar y la aplicación de la imagen final al código compilado. Excluidos de Git los datos locales, cachés y backups de desarrollo.
- Retirada la implementación antigua e inaccesible de enriquecimiento de Radar, junto con su estado, contratos y tests exclusivos. Se conserva el flujo activo de actualización de Wantlist.
- Corregida la documentación de dominio de Radar para reflejar su función actual de gestor de Wantlist y preferencias locales, sin revisión automática de precios.
## [0.4.1] - 2026-09-30
Versión de mantenimiento del backend centrada en integridad de datos, autenticación, cancelación y actualizaciones verificadas.
### Corregido
- **Identidad en importaciones** — las importaciones identifican cada copia mediante IDs de instancia y edición coherentes y rechazan filas ambiguas o contradictorias, incluidas columnas de identidad duplicadas.
- **Ediciones importadas persistentes** — las valoraciones y notas pendientes sobreviven a reinicios, fallos parciales y sincronizaciones entrantes. Las revisiones y la serialización de escrituras evitan que un reintento antiguo sustituya ediciones nuevas. Los clientes autenticados pueden reintentar con `POST /api/import/retry`; el estado incluye los contadores persistentes de campos `pending` y `pendingFailed`.
- **Revocación de sesiones** — cambiar o restablecer la contraseña invalida las sesiones anteriores; una cuenta eliminada no puede seguir usando su cookie. El login vuelve a comprobar la cuenta tras verificar la contraseña.
- **Límite de login concurrente** — los intentos reservan capacidad por cuenta, cliente y verificaciones simultáneas antes de verificar la contraseña, evitando saltarse el límite con peticiones paralelas.
- **Propiedad de tareas canceladas** — una tarea detenida o invalidada por un reset de cuenta no puede publicar resultados tardíos, repoblar datos borrados ni liberar el bloqueo de su sustituta.
- **Finalización de la sincronización** — el Discogs sync run sigue activo durante el inventario y el calentamiento de portadas, y comunica sus fallos en vez de anunciar éxito antes de tiempo.
- **Snapshots de Wantlist** — las respuestas paginadas malformadas, duplicadas o incompletas no marcan registros válidos de Radar como ausentes.
- **Snapshots de inventario** — el estado de los anuncios se conserva hasta recibir un inventario completo y coherente, incluso cuando hay varios anuncios para la misma edición.
- **Snapshots de colección** — una paginación incompleta no elimina copias locales ni reemplaza parcialmente sus datos; se siguen admitiendo distintas instancias de una misma edición.
- **Plazos en Discogs** — las esperas de cuota, peticiones, lecturas del cuerpo y reintentos por límite de API tienen plazos y respetan la cancelación. Las esperas de reintento están acotadas y se liberan los recursos de respuesta.
- **Plazos en portadas** — las descargas y lecturas de portadas respetan la cancelación de cuenta/tarea y un plazo de 30 segundos, incluidos el proxy autenticado y el calentamiento durante sync.
- **Puertos de Docker Compose** — cambiar el `PORT` del host mantiene el listener y el healthcheck del contenedor en el puerto 3800.
- **Rendimiento de filtros** — la caché acotada de facetas evita recorrer colecciones sin cambios, sobrevive a escrituras de sesión y detecta cambios de colección desde otras conexiones SQLite sin conservar datos revertidos.
- **Validación de datos** — se rechazan metadatos malformados de colección e inventario antes de reconciliar, y se normaliza la forma de los arrays JSON al leerlos para evitar errores en exportaciones y estadísticas.
### Cambiado
- Restaurada la comprobación TypeScript de todo el backend mediante contratos explícitos para base de datos, peticiones y datos externos; eliminadas las directivas backend `@ts-nocheck` restantes.
- Sustituidos los algoritmos copiados en tests de cabeceras, inventario y migraciones por pruebas del código de producción. El Database schema lifecycle completo se ejecuta en una transacción para revertir conjuntamente una migración fallida.
### Notas de actualización
- Las bases de datos existentes se migran automáticamente. Las sesiones creadas antes de esta versión requieren volver a iniciar sesión.
- La cola persistente de importación cubre las ediciones confirmadas con esta versión; no puede reconstruir fallos anteriores perdidos en memoria. Reintentar los cambios pendientes es una operación explícita de la API del backend.
[0.4.1]: https://github.com/SimonBlancoE/discographic/compare/v0.4.0...v0.4.1
## [0.4.0] - 2026-09-29
Release con rediseño de la interfaz, nuevas funciones basadas en la API de Discogs, actualización completa del stack y endurecimiento para producción.
### Añadido
- **Rareza y demanda** - datos de comunidad de Discogs (lo tienen / lo quieren / nota media) con rankings de discos más deseados, codiciados y raros.
- **Estado del disco y de la funda** - filtros por grado, edición desde la ficha y reparto de estados en el panel principal.
- **Carpetas de Discogs** - filtro por carpeta y traslado de discos entre carpetas.
- **Otras ediciones** - todas las ediciones del mismo master, marcando las que tienes y las de tu Wantlist.
- **Valor según Discogs** - mínimo, mediana y máximo de la colección, con histórico guardado en cada sincronización.
- **Precio sugerido por estado** - precio sugerido por Discogs para cada grado, resaltando el de tu copia (requiere ajustes de vendedor en Discogs).
- **Rediseño de la interfaz** - navegación lateral y barra inferior en móvil, vista de portadas en la colección, filtros con etiquetas y estado en la URL.
- **Diseño más sobrio** - paleta cálida con un único acento dorado, gráficos de un solo tono, bienvenida con accesos directos en lugar del carrusel del panel principal.
- **Pantallas estrechas** - las cifras y tarjetas se adaptan al ancho de su panel (container queries), sin desbordes de 360 px a monitores verticales.
- **README** - reescrito y con capturas nuevas en inglés y español.
### Cambiado
- **Stack** - Node 24 LTS, React 19, React Router 7, Recharts 3, Express 5, Vite 8, Tailwind CSS 4, TypeScript 7 y better-sqlite3 13.
- **Radar** - el aviso de cambios sin guardar cubre también el botón Atrás del navegador.
- **Seguridad** - secreto de sesión aleatorio persistente si no se configura, `TRUST_PROXY` para despliegues detrás de proxy/Cloudflare, límite de intentos de login, regeneración de sesión al iniciar, cabeceras de seguridad y `HEALTHCHECK` en la imagen Docker.
- **Docker** - los módulos nativos se compilan en la etapa de build; la imagen final solo lleva dependencias de producción.
### Corregido
- Editar notas podía sobrescribir el estado del disco o de la funda en Discogs.
- Ruta de portadas vulnerable a path traversal.
- Una respuesta vacía de Discogs podía borrar la colección local.
- Carreras en la revisión de precios y en el limitador de peticiones a Discogs.
- `xlsx` actualizado a 0.20.3 (CVE-2023-30533, CVE-2024-22363).
- `sharp` actualizado a 0.35.4 y `qs` a 6.16.0 por vulnerabilidades conocidas.
- Exportar a Excel descargaba un CSV y los filtros por formato vaciaban la exportación.
- Las ediciones que Discogs acepta se guardan aunque falle un paso posterior, y dos ediciones seguidas del mismo disco ya no se pisan.
- Filtros por género/estilo demasiado amplios, país borrado en cada sincronización, preferencias perdidas al cambiar de cuenta, fórmulas en exportaciones, fechas con desfase horario, enlaces rotos del Radar y catálogo de impresión limitado a 100 discos.
[0.4.0]: https://github.com/SimonBlancoE/discographic/compare/v0.3.4...v0.4.0
## [0.3.4] - 2026-07-04
Release de mantenimiento y robustez que corrige fallos funcionales y optimiza la exportación de la colección.
### Corregido
- **Tolerancia a fallos en tipos de cambio (ECB)** - la aplicación ahora recurre a tasas estáticas por defecto en lugar de arrojar un error HTTP 500 cuando el API del ECB está offline.
- **Tolerancia en detalles de lanzamiento (Discogs)** - los errores del API de Discogs al recuperar detalles ya no tiran la página de detalles; el sistema vuelve de forma segura a los datos locales.
- **Caché de portadas en CollectionTable** - la tabla de colección ahora utiliza el endpoint proxy local de portadas en lugar de hotlinking remoto.
- **Optimización de rendimiento en exportación** - las conversiones de divisas se realizan de forma síncrona en lote, eliminando miles de promesas asíncronas redundantes.
- **Condición de carrera en importación** - se previene un TypeError si un release es eliminado de forma concurrente durante la aplicación del import.
[0.3.4]: https://github.com/SimonBlancoE/discographic/compare/v0.3.3...v0.3.4
## [0.3.3] - 2026-05-10
Release de limpieza de documentacion y metadata.
### Cambiado
- **Referencias publicas del repositorio corregidas** - las instrucciones de
clonado del README, la metadata del paquete, la guia de contribucion, la
documentacion de planificacion y los tests de guardrails apuntan ahora solo
al repositorio publico de GitHub.
- **Detalles privados de desarrollo eliminados** - la documentacion visible del
repo ya no menciona remotos privados, nombres de upstream privados ni
lenguaje de publicacion downstream.
[0.3.3]: https://github.com/SimonBlancoE/discographic/compare/v0.3.2...v0.3.3
## [0.3.2] - 2026-05-10
Release de documentacion para aclarar la guia publica del proyecto.
### Cambiado
- **Introduccion del README aclarada** - la seccion inicial ahora se llama
"Que es Discographic?" y pide feedback a usuarios de Discogs, especialmente
a vendedores, porque esos flujos necesitan la opinion de quienes los usan.
- **Instancia manual de pruebas separada** - las instrucciones de la instancia
efimera de QA ahora aparecen como aviso para que no se confundan con la
instalacion normal.
- **Expectativas de contribucion aclaradas** - el README explica que no se
aceptan contribuciones directas como norma general, pero que el feedback,
los issues y los pull requests son bienvenidos y se agradecen.
[0.3.2]: https://github.com/SimonBlancoE/discographic/compare/v0.3.1...v0.3.2
## [0.3.1] - 2026-05-08
Release de mantenimiento con dos mejoras sobre la 0.3.0: mostrar el precio de
listado en el detalle de lanzamiento y pulir las traducciones en español.
### Corregido
- **Precio de listado en el detalle de lanzamiento** - la pantalla de detalle
muestra el precio de listado cuando existe.
- **Traducciones en español pulidas** - se normalizo la copia ES en imports,
logros y metadatos para un lenguaje mas natural.
### Tests
- Verificacion de release centrada en el bump de version, el changelog y la
sincronizacion del repositorio.
[0.3.1]: https://github.com/SimonBlancoE/discographic/compare/v0.3.0...v0.3.1
## [0.3.0] - 2026-05-02
Release centrada en la migracion completa a TypeScript, contratos compartidos
entre frontend/backend y verificacion de upgrade para instalaciones existentes.
### Nuevo
- **Arbol de codigo TypeScript-only** - frontend, backend, shared, tests,
scripts y configuracion soportada migrados a `.ts`/`.tsx` o formatos no JS.
- **Contratos compartidos tipados** - account, release, marketplace, sync
status, dashboard stats y collection views tienen tipos y normalizadores
explicitos en `shared/contracts/`.
- **Pipeline de verificacion unico** - `npm run verify` ejecuta scan de fuentes
JavaScript, typecheck, tests, build y smoke de upgrade.
- **Smoke de upgrade desde `v0.2.2`** - prueba runtime compilado y Docker contra
una fixture legacy para comprobar datos, configuracion y rutas de arranque.
- **Runtime backend compilado** - produccion arranca desde `dist/server/start.js`;
desarrollo usa `tsx` directamente.
- **Vistas guardadas de coleccion** - filtros, orden y columnas pueden guardarse
como vistas reutilizables.
- **Soporte de planificacion de implementacion** - runner, prompts y estandares
de trabajo para ejecutar slices de implementacion.
### Cambiado
- **Build separado de app y servidor** - `npm run build` compila Vite y despues
el backend con `tsc -p tsconfig.server.json`.
- **Code splitting de rutas** - bundles principales reducidos al cargar paginas
bajo demanda.
- **Render de tabla de coleccion estabilizado** - handlers, columnas visibles y
props de orden mantienen referencias estables para evitar renders evitables.
- **README y metadatos de repo** - se documento la metadata publica del
repositorio y la guia de release junto al alcance de la migracion.
- **Documentacion de contribucion** - `CONTRIBUTING.md`, PRD y ADRs documentan
reglas TypeScript-only, normalizacion de fronteras no confiables y verificacion.
### Corregido
- **Estados de marketplace preservados** - estados desconocidos/fallidos dejan
de colapsar a cero y los valores legacy se limpian de forma explicita.
- **Errores de marketplace normalizados** - las respuestas fallidas exponen
estados consistentes al frontend.
- **Filtro de sellos** - opciones largas dejan de truncarse de forma prematura.
- **Docker lockfile** - lockfile sincronizado con dependencias actuales.
### Tests
- Suite migrada a TypeScript con cobertura de contratos compartidos, rutas de
runtime, guardrails TypeScript-only, code splitting, upgrade smoke y badge de
vinilo. Verificacion actual: 183 tests.
[0.3.0]: https://github.com/SimonBlancoE/discographic/compare/v0.2.2...v0.3.0
## [0.2.2] - 2026-04-22
Patch visual para el carrusel del panel informativo.
### Corregido
- **Asomaba el siguiente slide por la derecha** — el padding que aplique al viewport en 0.2.1 desplazaba el track respecto al area recortada por `overflow: hidden`, dejando visible parte del slide siguiente en el margen derecho. Padding movido a cada slide con `box-sizing: border-box`. El viewport vuelve a ser un contenedor puro de overflow.
[0.2.2]: https://github.com/SimonBlancoE/discographic/compare/v0.2.1...v0.2.2
## [0.2.1] - 2026-04-22
Patch con correcciones al carrusel del dashboard y al logo animado del panel superior.
### Corregido
- **Botones del carrusel no respondian** — el gestor de drag capturaba todo el contenedor e interceptaba los clicks en flechas y puntos. Ahora el pointer solo se escucha en el viewport.
- **Cambio automatico demasiado rapido** — autoplay de 9s a 14s; tras interacion manual, el autoplay se pausa 5s en vez de 3s.
- **Traducciones al español** — reescritas en castellano neutro. Fuera jerga de DJ ("maleta", "pick", "cavando", "Spin the Crate", "tapete"). Mismo tratamiento en ingles: textos mas directos.
- **Movimiento al hacer hover** — eliminado el parallax de chips y orbes del panel hero. Interaccion en hover ahora limitada a un glow suave de borde cian en el viewport, sin desplazar elementos.
### Cambiado
- **Indicador "Siguiente pista" eliminado** — se ha quitado completamente del carrusel.
- **Logo giratorio del panel superior** — aumentado de 3.2rem a 5.25rem (disco de 2.35rem a 4.2rem). Se mantiene la aceleracion al pasar el raton sobre el logo, pero ya no aparece el nombre del genero.
[0.2.1]: https://github.com/SimonBlancoE/discographic/compare/v0.2.0...v0.2.1
## [0.2.0] - 2026-04-22
Release centrada en rendimiento del dashboard y muro, robustez de sincronizacion,
localizacion de importaciones y media, y una refactorizacion amplia que mueve
logica compartida a modulos reutilizables.
### Nuevo
- **Hero Carousel en el dashboard** — carrusel animado de caracteristicas con
autoplay, navegacion por puntero, teclado y soporte para `prefers-reduced-motion`.
- **VinylBadge** — insignia giratoria con generos destacados de la coleccion,
animacion pausada bajo `prefers-reduced-motion`.
- **DashboardStatsContext** — proveedor compartido que centraliza la carga de
estadisticas del dashboard y elimina peticiones duplicadas entre consumidores.
- **Contrato de estadisticas** — `shared/contracts/dashboardStats.js` normaliza
payloads del backend en una forma estable para el frontend.
- **Virtualizacion del muro de portadas** — `WindowedCoverWallGrid` renderiza
solo las filas visibles; colecciones grandes desplazan sin cortes.
- **Reconciliacion post-sync** — los sync completos eliminan filas de releases
que ya no existen en la coleccion del usuario, limpiando las portadas en cache
asociadas.
- **Localizacion de importaciones y fallbacks de media** — mensajes de
importacion y textos de fallback de portadas respetan el idioma del usuario.
- **Servicio de notas compartido** — `server/services/notes.js` unifica
normalizacion, serializacion y limpieza de notas entre sync, import y export.
- **Servicio de media de portadas** — `server/services/coverMedia.js`
centraliza cache de portadas, variantes (wall/poster) y limpieza.
- **Filtros de releases compartidos** — `server/services/releaseFilters.js` y
`shared/collectionFilters.js` consolidan filtros usados por stats, collection
y export.
- **Sync de importaciones** — `server/services/importSync.js` + `src/lib/importSync.js`
envian notas y puntuaciones importadas de vuelta a Discogs con estado.
- **Contratos tipados en `shared/contracts/`** — primer paso hacia un contrato
explicito frontend/backend.
- **Tests** — cobertura nueva para filtros de coleccion, reconciliacion, media
de portadas, parity de export, progreso de import, normalizacion de notas,
metricas del muro, contrato de stats, badge de generos, migracion de
marketplace_status y fetch de valor de marketplace. Total: 217 tests.
### Corregido
- **Migracion de `marketplace_status` re-ejecutada en cada arranque** — el
backfill ahora corre solo cuando la columna se acaba de anadir, preservando
estados existentes en re-ejecuciones.
- **Errores silenciosos en fetch del marketplace** — `fetchMarketplaceValue`
registra `releaseId` y `error.message` antes de devolver estado `FAILED`.
- **Renders innecesarios en consumidores del dashboard** — `refresh` envuelto en
`useCallback`, `badgeGenres` memoizado, y `getDashboardBadgeGenres` reducido a
un slice puro sin re-normalizar.
- **Parity entre export e import** — notas y campos derivados viajan de ida y
vuelta sin perder metadatos.
- **Sync de notas en import** — notas importadas se sincronizan de vuelta a
Discogs correctamente.
### Cambiado
- **Refactor de helpers compartidos** — colecciones, portadas y filtros dejan de
duplicarse entre rutas y servicios.
- **Dashboard.jsx** — consume el contexto compartido en lugar de gestionar su
propio fetch de stats.
- **Condicion de enriquecimiento** — centralizada en `server/services/enrichmentQueue.js`
con constantes de `MARKETPLACE_STATUS` para estado explicito.
### Eliminado
- **Componentes sin uso** — `CompletionRing`, `StatSparkline`, `CountryChart`,
hook `useAnimatedNumber` y la ruta `/api/value` sin consumidores.
[0.2.0]: https://github.com/SimonBlancoE/discographic/compare/v0.1.0...v0.2.0
## [0.1.0] - 2026-04-10
Primera release etiquetada. Discographic es un gestor de colecciones de Discogs
autoalojado para coleccionistas de vinilo, con sincronizacion, enriquecimiento,
exportacion/importacion y un dashboard con graficas y logros.
### Nuevo
- **Conversion de moneda dinamica** — precios almacenados en EUR, convertidos en
tiempo real con tasas del BCE con cache de 6 horas, fallback a fecha anterior
y deduplicacion de peticiones concurrentes. Selector de moneda en la cabecera
de la coleccion (EUR/USD/GBP) con preferencia persistente por usuario.
- **Columnas configurables** — registro de columnas como fuente unica de verdad,
popover ColumnToggle (renderizado via portal), preferencias de visibilidad por
usuario guardadas en base de datos.
- **Listings del marketplace** — sincronizacion de inventario con los listings
propios del usuario en Discogs, selecciona el mejor por release (prefiere
"For Sale" sobre "Draft", precio mas bajo), almacena precio original +
conversion a EUR. Dos columnas nuevas: estado de venta y precio de venta.
- **Exportaciones localizadas** — cabeceras CSV/XLSX con claves i18n en espanol
e ingles. Tolerancia de importacion cross-locale para que archivos exportados
en un idioma se importen en el otro.
- **Instancia de test efimera** — `docker-compose.test.yml` con almacenamiento
tmpfs, `scripts/test-instance.sh` para bootstrap automatizado y creacion de
usuarios, scripts npm `test:instance:start` / `test:instance:stop`.
- **Gestion de contrasenas** — el admin puede resetear contrasenas de usuarios,
los usuarios pueden cambiar la suya.
- **Sistema de logros** — hitos de coleccion y desbloqueos secretos con
animaciones de confeti.
- **Suite de tests** — 77 tests en 9 archivos cubriendo conversion de moneda,
sincronizacion de inventario, migraciones de DB, serializacion de exports,
columnas i18n, almacenamiento de preferencias y progreso de enriquecimiento.
### Corregido
- **Bucle infinito de enriquecimiento** — eliminado `country` de la condicion
de pendientes de enriquecimiento; releases donde Discogs no tiene datos de
pais ya no re-disparan el enriquecimiento indefinidamente.
- **Fallos silenciosos en sync de inventario** — los errores ahora se reportan
via estado de sincronizacion en lugar de solo registrarse en consola.
- **Overlay del menu de columnas** — popover de ColumnToggle renderizado via
portal de React, eliminando la dependencia fragil de z-index.
- **Dockerfile sin directorio shared/** — anadida copia de shared/ en la
etapa de runtime.
### Cambiado
- **API de preferencias** — restringida a una lista blanca de claves conocidas
(`collection_visible_columns`, `currency`) en lugar de regex permisiva.
- **Guardado de preferencia de columnas** — debounce de 500ms para agrupar
toggles rapidos en una sola llamada API.
- **Notificacion de reseteo de orden** — toast informativo cuando el orden se
resetea a artista al ocultar la columna actualmente ordenada.
- **Proxy dev de Vite** — puerto destino configurable via variable de entorno
`VITE_API_PORT`, por defecto 3800.
- **Defaults de moneda** — reemplazadas cadenas `'EUR'` hardcodeadas en
AuthContext y Collection por la constante compartida `DEFAULT_CURRENCY`.
[0.1.0]: https://github.com/SimonBlancoE/discographic/releases/tag/v0.1.0