Files
Your Name b6abfd0830 v1.4.1: bug fixes, enrichment resilience, frontend lint cleanup
Audio & Playback:
- Fix doubled audio on track change (destroy old Howl before creating new)
- Fix play/pause visual desync by using Howler state as source of truth

Soulseek & Downloads:
- Fix Soulseek download 400 error (closes #101)
- Expand Soulseek documentation (closes #27)

Enrichment & Analysis:
- Fix CLAP analyzer clobbering Essentia analysisStatus (root cause of #79)
- Add embedding check to both Python analyzers before resetting tracks
- Set analysisStartedAt when marking tracks as processing
- Clear analysisStartedAt on successful completion
- Include vibe embeddings in isFullyComplete check
- Add keepPreviousData to enrichment progress query for UI resilience
- Shut down idle worker pool to free ~5.6 GB when no work pending
- Fix compilation matching for multi-disc albums (closes #70)
- Add podcast auto-refresh in enrichment cycle (closes #81)

Admin & Auth:
- Add admin password reset via env var (closes #97)
- Add retry failed analysis button in settings (closes #79)
- Add requireAdmin to onboarding config and cleanup routes
- Remove userId from 2FA challenge response

Queue & UI:
- Fix cancelJob/refreshJobMatches not persisting state
- Fix discovery polling leak on batch failure
- Fix withTimeout timer leak in enrichment worker
- Fix useAlbumData infinite re-render loop
- Fix unhandled audio.play() promise rejection

Performance:
- Eliminate N+1 queries in recommendation endpoints
- Idle Essentia worker pool shutdown (8 processes, ~5.6 GB freed)

Frontend Quality:
- Fix all 377 ESLint errors and warnings (0 remaining)
- Fix Rules of Hooks, setState-in-effect, exhaustive-deps
- Type api.ts and 50+ files (remove explicit any)
- Remove 1664 lines of dead code and duplicates
- Extract shared utilities from duplicated patterns
2026-02-06 18:30:40 -06:00

26 lines
497 B
JavaScript

/* eslint-disable @typescript-eslint/no-require-imports */
// Minimal health check script - no external dependencies
const http = require('http');
const options = {
hostname: 'localhost',
port: 3030,
path: '/',
method: 'GET',
timeout: 5000,
};
const req = http.request(options, (res) => {
process.exit(res.statusCode >= 200 && res.statusCode < 400 ? 0 : 1);
});
req.on('error', () => process.exit(1));
req.on('timeout', () => {
req.destroy();
process.exit(1);
});
req.end();