• bvandeusen released this 2026-05-08 13:46:23 -04:00 | 1005 commits to main since this release

    First 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/apierror package: typed *Error, sentinels, constructors. ~342 writeErr call sites converted to writeErr(err).
    • resolveByID[T] helper for the parseUUID → fetch → 404 pattern (~7 sites migrated).
    • audit.WriteOrLog(ctx, pool, logger, ...) wrapper (~13 sites migrated).
    • Per-package ErrNotFound declarations consolidated to alias apierror.ErrNotFound.
    • Handler prelude helpers (requireUser / requireURLUUID / decodeBody) — ~25 handler files cleaner.
    • sqlc *ForUser track query pairs unified via nullable user_id.
    • Test fixtures: withUser helper migration (51 sites).

    Web SPA

    • errCode / errMessage helpers (38 sites).
    • Single <Modal> component (8 admin modals).
    • pushToast store + global <ToastHost /> (8 sites).
    • offsetGetNextPageParam + pageGetNextPageParam paging helpers (8 sites).
    • Theme hex now reads from tokens.json (single source).
    • auth/user.svelte.ts extracted to break the auth↔player import cycle.
    • svelte-query mock factored into vitest.setup.ts (-180 LoC across 34 test files).
    • PlaylistTrackRow drag-reorder migrated to @neodrag/svelte (matches QueueTrackRow).
    • 5 open-coded /api/albums/${id}/cover sites → coverUrl() helper.
    • .play-overlay CSS hoisted from 3 components to app.css.

    Cover-art (Go)

    • Shared httpClient struct 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.json expanded from 14 → 46 codes (auth/validation/404 flows), mirrored to Flutter.

    Notes

    Wire-format normalization across /api/* errors: many handlers were emitting inconsistent unauthorized / auth_required / unauthenticated codes for the same condition. The DRY pass standardized on auth_required. Frontend error-copy was expanded so the change is invisible to users.

    Downloads