- covers are taken from the embedded picture of the first track or a
cover/folder/front image in the album folder, converted by ffmpeg to
WebP 64/300/1200 and named by content hash, so albums sharing a cover
share the files; a full scan looks again for albums without one
- a 3-colour palette (dominant, second, most saturated accent) from a
deterministic k-means feeds placeholders, page tints and the wave
- /covers/{id} is public but HMAC-signed and immutable; nginx serves
the file via X-Accel-Redirect, X_ACCEL=false serves it from api
- the web client picks the size by display size and pixel density
- install.sh and update.sh generate STREAM_SIGNING_KEY
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- artists, albums and tracks indexes are rebuilt from PostgreSQL next
to the live ones and swapped in, so search keeps working; a rebuild
runs on start, after every scan and when a source is removed
- transliteration fields (Кино ↔ kino) and a retry in the other
keyboard layout (ghbdtn → привет) reported as corrected_query
- /search/suggest (3 artists, 3 albums, 5 tracks), /search by type
with cursor pages, /admin/search/reindex; Meilisearch is part of
/readyz
- found ids are hydrated from the catalog, so a lagging index never
returns deleted entries
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>