-
released this
2026-05-08 13:46:23 -04:00 | 1005 commits to main since this releaseFirst release of the day. Two-round DRY pass across Go server + web SPA, plus PR3's cover-art provider HTTP plumbing extraction.
Server (Go)
- New
internal/apierrorpackage: typed*Error, sentinels, constructors. ~342writeErrcall sites converted towriteErr(err). resolveByID[T]helper for theparseUUID → fetch → 404pattern (~7 sites migrated).audit.WriteOrLog(ctx, pool, logger, ...)wrapper (~13 sites migrated).- Per-package
ErrNotFounddeclarations consolidated to aliasapierror.ErrNotFound. - Handler prelude helpers (
requireUser/requireURLUUID/decodeBody) — ~25 handler files cleaner. - sqlc
*ForUsertrack query pairs unified via nullable user_id. - Test fixtures:
withUserhelper migration (51 sites).
Web SPA
errCode/errMessagehelpers (38 sites).- Single
<Modal>component (8 admin modals). pushToaststore + global<ToastHost />(8 sites).offsetGetNextPageParam+pageGetNextPageParampaging helpers (8 sites).- Theme hex now reads from
tokens.json(single source). auth/user.svelte.tsextracted to break the auth↔player import cycle.- svelte-query mock factored into
vitest.setup.ts(-180 LoC across 34 test files). PlaylistTrackRowdrag-reorder migrated to@neodrag/svelte(matchesQueueTrackRow).- 5 open-coded
/api/albums/${id}/coversites →coverUrl()helper. .play-overlayCSS hoisted from 3 components toapp.css.
Cover-art (Go)
- Shared
httpClientstruct providing rate-limit + exponential backoff + retry + body-size limits. - Last.fm / Deezer / TheAudioDB providers now delegate HTTP plumbing — ~400 LoC removed across the trio.
Other
error-copy.jsonexpanded from 14 → 46 codes (auth/validation/404 flows), mirrored to Flutter.
Notes
Wire-format normalization across
/api/*errors: many handlers were emitting inconsistentunauthorized/auth_required/unauthenticatedcodes for the same condition. The DRY pass standardized onauth_required. Frontend error-copy was expanded so the change is invisible to users.Downloads
- New