# Muzick — Progress

## Stack
React/Vite + TanStack Router frontend, Fastify backend, BullMQ workers, PostgreSQL, Redis, Typesense. Docker Compose stack.

## What's working
- Full 3-pane UI: NavRail + TopBar + main + NowPlayingPanel (queue/lyrics tabs) + PlaybackBar
- Audio playback: play/pause/next/prev, seek, volume, shuffle, repeat (none/all/one)
- Lyrics button in PlaybackBar → opens panel to lyrics tab
- All pages themed with semantic design tokens; 5 presets (Purple default)
- Enrichment pipeline: MusicBrainz, Last.fm, Discogs, LRCLib, Cover Art Archive — best-effort, per-toggle
- Real Essentia WASM audio analysis: BPM, key, energy, danceability, dynamic complexity
- Real MD5 content hash; track deduplication UI in Settings
- Multi-signal Vibe engine: genre + artist similarity + feedback + audio features + jitter; diversity caps; shuffle-aware
- Artist feat. dedup via `normalize_artist()` PostgreSQL function
- `track_artists` junction table (role: main/featured); scanner parses feat from tags/titles
- Clickable artist links in TrackRow (main + featured, navigate to artist page)
- Schema migration system: `schema_migrations` table, runs pending migrations on every boot
- Typesense auto-reindex after every scan (v3 API)
- Play history, feedback, Quarantine (dislike → delayed deletion) with frontend page
- Periodic integrity sweep worker (corrupt metadata, missing files)
- Genres page: hierarchical parent → sub-genre display

## Next
1. **Redeploy** — `docker compose down && docker compose up --build -d`; migrations will run on boot (track_artists backfill + clear Last.fm placeholder images)
2. **Rescan library** — Settings → Scan library; populates `track_artists` with real feat splits for all tracks
3. **Enrichment** — enable toggles, scan again; leave audio analysis off until initial enrichment finishes (~3.9k tracks will be slow)
4. **Artist avatars** — after enrichment re-runs, Last.fm placeholder URLs are cleared; artists without a real image show the gradient fallback
5. **External track acquisition** — yt-dlp download worker for Last.fm similar tracks into the probation pool (infrastructure ready, worker not built)
6. **Multi-user / auth** — currently single-user, no `x-user-id` per-user isolation
7. **Runtime smoke-test gate** — `node dist/server.js` fail-fast check in CI/deploy; ESM extension errors not caught by `tsc`

## Known issues
- Recommendation quality depends on enrichment having run (genres, artist similarity, audio features)
- `cleanup_sweep` worker (grace-period transitions, ntfy notifications) implemented but untested against live stack
- Frontend built and typechecked but not fully verified against live stack end-to-end
