Commit Graph

41 Commits

Author SHA1 Message Date
Jonathan 67f374c470 feat: Qobuz pacing budget gate (human-like volume + cadence)
Avoid re-triggering a USER_BLOCKED account by capping Qobuz to a human-looking
volume and cadence. A per-album gate (worker/lyra_worker/qobuz_gate.py) allows
Qobuz only within active hours, under today's cap (a warm-up ramp of a steady
cap), and past a randomized spacing since the last Qobuz download; the gap spreads
the day's budget across active hours with jitter. When the gate is closed the
pipeline drops Qobuz candidates so the job falls through to another source (and
monitored albums upgrade to Qobuz later); a Qobuz-only setup is never gated.
Config keys read live each loop; counters reset at the day boundary via the DB
clock. Tunable in Settings -> Qobuz -> Pacing (new /api/qobuz/pacing route).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 18:45:56 +02:00
Jonathan 878eac066e docs: implementation plan for Press controls + inter-job delay
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 11:50:54 +02:00
Jonathan 603c62ef87 docs: design spec for Press controls + inter-job delay
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 11:43:09 +02:00
Jonathan ccaaa41fec docs: slim README for self-hosting, move advanced topics to docs/DEPLOYMENT.md
Restructure the docs ahead of sharing the project for others to self-host. The
README is now a focused get-it-running path (overview, architecture, prereqs,
quick start, operational notes, security, backup/restore). Moved the fuller
feature tour, the maintainer pre-built-image release flow, and the Gluetun VPN
guide into a new docs/DEPLOYMENT.md, cross-linked both ways. The pre-built-image
section is now labelled a maintainer process with a LYRA_REGISTRY override so a
self-hoster can point at their own registry (or just build from source).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 02:57:45 +02:00
Jonathan c7bab8e997 docs: handoff plan for 3 post-deploy UX fixes
Qobuz progress smoothing, parallel source searches, bonus-track filename
canonicalization. Lyra is live on the VM; these are worker-only polish.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 02:24:56 +02:00
Jonathan e74d1d9c7b docs: implementation plan for Discover unified rows
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 23:33:04 +02:00
Jonathan 9dd235c2bc docs: spec for Discover unified rows + newest/most-popular albums
Design for collapsing the Artists|Albums tabs into one artist-centric row,
surfacing each similar artist's newest AND most-popular (Last.fm) album inline,
album-click → AlbumModal tracklist, artist name → full page (drop the Discover
ArtistModal). Approved design; implementation plan next.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 23:29:23 +02:00
Jonathan c918cba654 docs: note generalizing the MB cache table to a shared ApiCache
The Last.fm browse page has the same live-external-call-per-load problem;
name the cache table/helper generically (ApiCache) so Last.fm rides the
same read-through, with a manual Refresh button and live own-state
annotation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 00:37:31 +02:00
Jonathan 2158d988f8 docs: add MusicBrainz Postgres cache implementation plan
A read-through cache shared by the web app and the worker so reopening an
artist/album (and repeat lookups during scans/discovery) stop re-hitting
MusicBrainz. Postgres-only (Redis disregarded — PG is already shared across
web + worker); keys on the logical operation so both processes share entries;
serve-stale-on-outage; TTL-only invalidation. Four tasks: MbCache table →
web read-through → worker CachingMbBrowser → client Map + pruning.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 00:33:03 +02:00
Jonathan b6623944ff docs: plan for Last.fm artist modal (personal most-played songs + albums)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 21:17:31 +02:00
Jonathan 5315b240f0 docs: implementation plan for Last.fm integration (3 slices)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 18:51:03 +02:00
Jonathan 6decdc7fc9 docs: implementation plan for cleanup batch (Tier A + B)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 15:04:19 +02:00
Jonathan 785385f0a2 docs: spec for cleanup batch (Tier A loose ends + Tier B design fixes)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 14:27:51 +02:00
Jonathan 34ebe39dd7 docs: implementation plan for deferred-items batch
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 00:12:56 +02:00
Jonathan ab94945f9f docs: spec for deferred-items batch (settings, correctness, chunk discovery)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 00:07:15 +02:00
Jonathan 5f0dcda2ab docs: Pressing Plant frontend Phase 1 implementation plan
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 13:57:35 +02:00
Jonathan 4655d815ee docs: Pressing Plant frontend design system spec (Phase 1)
Design language + Phase 1 plan (design system + app shell + home page).
Comp signed off. Liner Notes / record-label identity, chrome-only
metaphor, manila+spruce palette, Fraunces/mono, state-as-form.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 13:53:52 +02:00
Jonathan ade9cd7694 docs: worker robustness design (scan chunking + DB reconnect)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 12:36:54 +02:00
Jonathan 3f77bb1f4c fix(preview): guard want() on res.ok; docs: preview in README + artists-search TODO
- preview-client want() no longer flips the Monitored badge when the POST fails
  (deferred item #1 from the discovery-preview whole-branch review).
- README: discovery section notes the artist preview page.
- Plan Notes + project-state: TODO to reuse the preview page from the /artists
  live search (wire artists-client.tsx hits to /discover/artist/[mbid]).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 02:03:08 +02:00
Jonathan 170180d471 docs: discovery preview implementation plan (6 tasks, TDD)
MB lib (getArtistName + browseReleaseGroupTracks) → tracks route → preview route
(annotated discography) → want route → preview page/client → feed+Find-similar
wiring. Web-only, each route TDD against lyra_test; pages build-verified.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 01:31:18 +02:00
Jonathan 4dbb6d9d83 docs: discovery preview design — artist preview page (disco + tracklists + own-state)
Follow-up to slice 3: a read-only artist preview page keyed by MBID, reachable from
suggested artists, suggested albums, and Find-similar results. Shows discography,
lazy per-album tracklists, own-state badges; Follow (reuse /api/artists) + Want
(new /api/discover/want upsert). Web-side MB reads only, no worker changes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 01:26:16 +02:00
Jonathan decb6302d4 docs: mark slice 3 (discovery) done + record deferred todos
README: discovery status → done (ListenBrainz-native, no Spotify); off-by-default
note for the discovery sweep; architecture mentions MusicBrainz+ListenBrainz.
Plan: check off final verification (suites green, whole-branch review passed,
live-API algorithm fix), append the review's deferred items to Notes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 01:06:56 +02:00
Jonathan 0d2b7f0ae5 docs: slice 3 discovery implementation plan (14 tasks, TDD)
Schema → SimilaritySource + ListenBrainz engine → run_discovery (artists+albums)
→ worker sweep/trigger wiring → web feed/run/search/action/config routes →
/discover UI + settings. Each task independently testable against lyra_test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 22:49:40 +02:00
Jonathan 0cf464aad0 docs: slice 3 discovery design — MetaBrainz-native (ListenBrainz), suggestion feed
Spotify similarity/new-release APIs are dead for new apps (Nov 2024 + Feb 2026),
so discovery is built on ListenBrainz similar-artists (MBID-native) behind a
pluggable SimilaritySource interface. Manual review feed of similar artists +
albums; Follow/Want reuse slice-2 operations, Dismiss is permanent. Off by default.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 22:35:49 +02:00
Jonathan f421904c9b docs: add library-scan implementation plan
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 16:50:57 +02:00
Jonathan a4ae60a99e docs: add library-scan design (ingest on-disk albums as have+monitored)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 16:45:58 +02:00
Jonathan 1d847e2aeb docs: add staged-download + atomic-import implementation plan
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 15:07:01 +02:00
Jonathan 2614e32f55 docs: add staged-download + atomic-import design (pipeline fix)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 14:59:55 +02:00
Jonathan eb2a2207a1 docs: add monitoring-web implementation plan (slice 2, plan 2)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 13:08:19 +02:00
Jonathan 915bd96cd3 docs: add monitoring-core implementation plan (slice 2, plan 1)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 12:01:57 +02:00
Jonathan dcddcac86c docs: add library-manager design (slice 2)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 11:46:41 +02:00
Jonathan 6cce95cec6 docs: add tagging, import & persistent library plan (slice 1, plan 4b)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 23:41:46 +02:00
Jonathan 6ea930ec7a docs: add MusicBrainz intake + search-hardening plan (slice 1, plan 4a)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 23:10:10 +02:00
Jonathan 9804f3bb90 docs: add Soulseek adapter plan (slice 1, plan 3d)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 22:39:34 +02:00
Jonathan 50931c0cf5 docs: add Qobuz adapter plan (slice 1, plan 3c)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 21:58:44 +02:00
Jonathan da1ed5caba docs: add YouTube adapter plan (slice 1, plan 3b)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 21:18:09 +02:00
Jonathan 349f699bb6 docs: add configuration & secrets plan (slice 1, plan 3a)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 19:45:08 +02:00
Jonathan b62b4145da docs: add pipeline-core implementation plan (slice 1, plan 2)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 18:19:06 +02:00
Jonathan d939f83ce3 chore: relax worker dep pins for local Python 3.14
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 16:28:34 +02:00
Jonathan dcdb9752a2 Add walking-skeleton implementation plan (slice 1, plan 1)
Seven TDD tasks: monorepo + compose scaffold, Prisma Request/Job
schema, request API, live queue UI, worker claim logic, fake
pipeline, and worker loop + Dockerfiles with end-to-end verification.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 16:23:45 +02:00
Jonathan 3adefe929b Add Lyra acquisition-engine design spec, README, gitignore
Initial design for slice 1 (acquisition engine): three-container
architecture (Next.js UI, Python worker, slskd), the six-stage
pipeline, source-adapter contract, data model, error handling, and
testing strategy.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 16:14:55 +02:00