BullMQ enrichment migration
- Rewrote enrichment pipeline on BullMQ v5: artist, track, podcast workers with
pause/resume/stop support and Bull Board visibility
- Essentia publishes audio:analysis:complete events; CLAP subscribes reactively
instead of polling (eliminates scan delay between phases)
- Thread-safe DB pool in CLAP worker, all DB calls in run_in_executor
- Fixed psycopg2.pool submodule import crash on BullMQ vibe worker startup
- Silenced EnrichmentStateService disconnect error on already-closed Redis conn
Enrichment fixes
- lastfmTags NULL caused mood-tags phase to silently skip all tracks; migration
backfills NULL -> '{}' and sets column default
- Cover art fetch errors for temp-MBID albums (temp-* passed to Cover Art Archive)
- VIBE-VOCAB vocabulary JSON not copied to Docker image (TypeScript omits .json)
- Wired cleanupOldResolved() to run daily; added missing enrichment status indexes
- Fixed circuit breaker reset, orphan cleanup, podcast entityType, hang detection
Soulseek
- Track search-page downloads in activity tracker
- Use async fs.promises.access instead of synchronous existsSync
- Verify file exists on disk before emitting download:complete (#110)
Docker image size: 28.4 GB -> 12.2 GB
- Removed all CUDA/NVIDIA dependencies; switched to CPU-only PyTorch/TensorFlow
- tensorflow-cpu + essentia-tensorflow --no-deps (avoids GPU TF transitive dep)
- Fixed .dockerignore: **/node_modules and **/.next now excluded from build context
PWA / mobile
- Background audio session loss on iOS/Android: SilenceKeepalive singleton,
tryResume() in MediaSession play handler, direct track load on 'ended' event,
visibilitychange/pageshow foreground recovery
- Lock orientation to portrait for Android device lock (#117)
Discovery
- Retry All re-importing albums already in library: apply same three-level filter
as GET /current before creating download jobs; delete stale UnavailableAlbum
records for already-present albums. Closes#34
CI / release
- linux/arm64 added to release and nightly Docker builds (#87)
- Isolated release CI from nightly GHA cache (cache-from/cache-to removed from
docker-publish.yml to guarantee clean release builds)
- Redis vm.overcommit_memory=1 sysctl added to prod and server compose files
Other fixes
- Cross-artist album fallback by title+year prevents library splitting (#50)
- Retry temp-MBID artists after 24h not 7 days; hide temp MBIDs from API (#112)
- 3-attempt ECONNRESET retry on all Deezer getPlaylist call sites (#119)
- check response.ok on health probe — fetch does not throw on 5xx (#104)
- Z-index stacking hierarchy established (MiniPlayer through OverlayPlayer)
- API token display overflow on iPhone (min-w-0/overflow-hidden on flex container)