Skip to content

Commit f2a443c

Browse files
Your Nameclaude
andcommitted
v1.4.0: sequential enrichment, GPU auto-detection, repo cleanup
- Run audio analysis and vibe embedding phases sequentially to prevent resource contention (CPU/memory) from concurrent analyzers - Auto-detect GPU availability in both audio analyzers (CUDA/ROCm) - Fix false lite mode detection on startup by checking analyzer scripts on disk before falling back to heartbeat/DB checks - Fix Dockerfile NEXT_PUBLIC_BACKEND_URL and frontend rewrite proxy - Route enrichment failures through notification system instead of persistent error banner - Remove playback error banner from player components - Reduce enrichment cycle interval from 6h to 2h - Comprehensive repo cleanup: remove 127 decorative comment dividers across 17 files, clean verbose comments, harden .gitignore, remove tracked docs from git Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent cc3f1fb commit f2a443c

34 files changed

+408
-2038
lines changed

.gitignore

Lines changed: 62 additions & 319 deletions
Large diffs are not rendered by default.

CHANGELOG.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,39 @@ All notable changes to Lidify will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.4.0] - 2026-02-05
9+
10+
### Performance
11+
12+
- **Sequential audio/vibe enrichment:** Vibe phase skips when audio analysis is still running, preventing concurrent CPU-intensive Python analyzers from competing for resources
13+
- **Faster enrichment cycles:** Reduced cycle interval from 30s to 5s; the rate limiter already handles API throttling, making the extra delay redundant
14+
- **GPU auto-detection (CLAP):** PyTorch-based CLAP vibe embeddings auto-detect and use GPU when available, falling back to CPU
15+
- **GPU auto-detection (Essentia):** TensorFlow-based audio analysis detects GPU with memory growth enabled, with device logging on startup
16+
17+
### Changed
18+
19+
- **Enrichment orchestration simplified:** Replaced 4 phase functions with duplicated stop/pause handling with a generic `runPhase()` executor and `shouldHaltCycle()` helper
20+
21+
### Fixed
22+
23+
- **Docker frontend routing:** Fixed `NEXT_PUBLIC_BACKEND_URL` build-time env var in Dockerfile so the frontend correctly proxies API requests to the backend
24+
- **Next.js rewrite proxy:** Updated rewrite config to use `NEXT_PUBLIC_BACKEND_URL` for consistent build-time/runtime behavior
25+
- **False lite mode on startup:** Feature detection now checks for analyzer scripts on disk, preventing false "lite mode" display before analyzers send their first heartbeat
26+
- **Removed playback error banner:** Removed the red error bar from all player components (FullPlayer, MiniPlayer, OverlayPlayer) that displayed raw Howler.js error codes
27+
- **Enrichment failure notifications:** Replaced aggressive per-cycle error banner with a single notification through the notification system when enrichment completes with failures
28+
29+
## [1.3.9] - 2026-02-04
30+
31+
### Fixed
32+
33+
- **Audio analysis cleanup:** Fixed race condition in audio analysis cleanup that could reset tracks still being processed
34+
35+
## [1.3.8] - 2026-02-03
36+
37+
### Fixed
38+
39+
- **Enrichment:** CLAP queue and failure cleanup fixes for enrichment debug mode
40+
841
## [1.3.7] - 2026-02-01
942

1043
### Added
@@ -69,6 +102,34 @@ Automatic detection of available analyzers with graceful degradation.
69102
- **Docker Profiles:** Replaced Docker profiles with override file approach for better compatibility
70103
- **Mood Columns:** Marked as legacy in schema - may be derived from CLAP embeddings in future
71104

105+
## [1.3.5] - 2026-01-22
106+
107+
### Fixed
108+
109+
- **Audio preload:** Emit preload 'load' event asynchronously to prevent race condition during gapless playback
110+
111+
## [1.3.4] - 2026-01-22
112+
113+
### Added
114+
115+
- **Gapless playback:** Preload infrastructure and next-track preloading for seamless transitions
116+
- **Infinite scroll:** Library artists, albums, and tracks now use infinite query pagination
117+
- **CachedImage:** Migrated to Next.js Image component with proper type support
118+
119+
### Fixed
120+
121+
- **CSS hover performance:** Fixed hover state performance issues
122+
- **Audio analyzer:** Fixed Enhanced mode detection
123+
- **Onboarding:** Accessibility improvements
124+
- **Audio format detection:** Simplified to prevent wrong decoder attempts
125+
- **Audio cleanup:** Improved Howl instance cleanup to prevent memory leaks
126+
- **Audio cleanup tracking:** Use Set for pending cleanup tracking
127+
- **Redis connections:** Disconnect enrichmentStateService connections on shutdown
128+
129+
### Changed
130+
131+
- **Library page:** Optimized data fetching with tab-based queries and memoized delete handlers
132+
72133
## [1.3.3] - 2026-01-18
73134

74135
Comprehensive patch release addressing critical stability issues, performance improvements, and production readiness fixes. This release includes community-contributed fixes and extensive internal code quality improvements.

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ RUN npm ci && npm cache clean --force
183183
COPY frontend/ ./
184184

185185
# Build Next.js (production)
186-
ENV NEXT_PUBLIC_API_URL=
186+
ENV NEXT_PUBLIC_BACKEND_URL=http://127.0.0.1:3006
187187
RUN npm run build
188188

189189
# ============================================

backend/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "lidify-backend",
3-
"version": "1.3.8",
3+
"version": "1.4.0",
44
"description": "Lidify backend API server",
55
"license": "GPL-3.0",
66
"repository": {

backend/src/routes/browse.ts

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,6 @@ function deezerRadioToUnified(radio: DeezerRadioStation): PlaylistPreview {
5858
};
5959
}
6060

61-
// ============================================
62-
// Playlist Endpoints
63-
// ============================================
64-
6561
/**
6662
* GET /api/browse/playlists/featured
6763
* Get featured/chart playlists from Deezer
@@ -138,10 +134,6 @@ router.get("/playlists/:id", async (req, res) => {
138134
}
139135
});
140136

141-
// ============================================
142-
// Radio Endpoints
143-
// ============================================
144-
145137
/**
146138
* GET /api/browse/radios
147139
* Get all radio stations (mood/theme based mixes)
@@ -215,10 +207,6 @@ router.get("/radios/:id", async (req, res) => {
215207
}
216208
});
217209

218-
// ============================================
219-
// Genre Endpoints
220-
// ============================================
221-
222210
/**
223211
* GET /api/browse/genres
224212
* Get all available genres
@@ -296,10 +284,6 @@ router.get("/genres/:id/playlists", async (req, res) => {
296284
}
297285
});
298286

299-
// ============================================
300-
// URL Parsing (supports both Spotify & Deezer)
301-
// ============================================
302-
303287
/**
304288
* POST /api/browse/playlists/parse
305289
* Parse a Spotify or Deezer URL and return playlist info
@@ -343,10 +327,6 @@ router.post("/playlists/parse", async (req, res) => {
343327
}
344328
});
345329

346-
// ============================================
347-
// Combined Browse Endpoint (for frontend convenience)
348-
// ============================================
349-
350330
/**
351331
* GET /api/browse/all
352332
* Get a combined view of featured content (playlists, genres)

backend/src/routes/library.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -942,9 +942,8 @@ router.get("/artists/:id", async (req, res) => {
942942
return res.status(404).json({ error: "Artist not found" });
943943
}
944944

945-
// ========== DISCOGRAPHY HANDLING ==========
946-
// For enriched artists with ownedAlbums, skip expensive MusicBrainz calls
947-
// Only fetch from MusicBrainz if the artist hasn't been enriched yet
945+
// For enriched artists with ownedAlbums, skip expensive MusicBrainz calls.
946+
// Only fetch from MusicBrainz if the artist hasn't been enriched yet.
948947
let albumsWithOwnership = [];
949948
const ownedRgMbids = new Set(artist.ownedAlbums.map((o) => o.rgMbid));
950949
const isEnriched =
@@ -994,8 +993,7 @@ router.get("/artists/:id", async (req, res) => {
994993
}
995994
}
996995

997-
// ========== ALWAYS include albums from database (actual owned files) ==========
998-
// These are albums with actual tracks on disk - they MUST show as owned
996+
// Albums from database have actual tracks on disk - they MUST show as owned
999997
const dbAlbums = artist.albums.map((album) => ({
1000998
...album,
1001999
owned: true, // If it's in the database with tracks, user owns it!
@@ -1007,7 +1005,6 @@ router.get("/artists/:id", async (req, res) => {
10071005
`[Artist] Found ${dbAlbums.length} albums from database (actual owned files)`
10081006
);
10091007

1010-
// ========== Supplement with MusicBrainz discography for "available to download" ==========
10111008
// Always fetch discography if we have a valid MBID - users need to see what's available
10121009
const hasDbAlbums = dbAlbums.length > 0;
10131010
const shouldFetchDiscography =
@@ -1286,15 +1283,12 @@ router.get("/artists/:id", async (req, res) => {
12861283
}));
12871284
}
12881285

1289-
// ========== HERO IMAGE FETCHING ==========
1290-
// Use DataCacheService: DB -> Redis -> API -> save to both
12911286
const heroUrl = await dataCacheService.getArtistImage(
12921287
artist.id,
12931288
artist.name,
12941289
effectiveMbid
12951290
);
12961291

1297-
// ========== SIMILAR ARTISTS (from enriched JSON or Last.fm API) ==========
12981292
let similarArtists: any[] = [];
12991293
const similarCacheKey = `similar-artists:${artist.id}`;
13001294

backend/src/routes/mixes.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -440,10 +440,6 @@ router.post("/mood/save-preferences", async (req, res) => {
440440
}
441441
});
442442

443-
// ============================================
444-
// NEW SIMPLIFIED MOOD BUCKET ENDPOINTS
445-
// ============================================
446-
447443
/**
448444
* @openapi
449445
* /mixes/mood/buckets/presets:

backend/src/routes/notifications.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,6 @@ router.post(
132132
}
133133
);
134134

135-
// ============================================
136-
// Download History Endpoints
137-
// ============================================
138-
139135
/**
140136
* GET /notifications/downloads/history
141137
* Get completed/failed downloads that haven't been cleared

backend/src/routes/playlists.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -537,10 +537,6 @@ router.put("/:id/items/reorder", async (req, res) => {
537537
}
538538
});
539539

540-
// ============================================
541-
// Pending Tracks (from Spotify imports)
542-
// ============================================
543-
544540
/**
545541
* GET /playlists/:id/pending
546542
* Get pending tracks for a playlist (tracks from Spotify that haven't been matched yet)

0 commit comments

Comments
 (0)