Jonathan
2ca0f7a385
feat: MbBrowser seam and FakeMbBrowser test double
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-07-11 12:12:17 +02:00
Jonathan
ec85016d88
feat: monitoring data model (WatchedArtist, MonitoredRelease, Request link)
2026-07-11 12:07:09 +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
c75b9d3562
fix: force IPv4 in worker, count real Qobuz files, flatten nested output
...
- worker had no IPv6 route -> Qobuz CDN (dual-stack) failed ~half the tracks
with 'Network is unreachable'; disable IPv6 in the container (IPv4 only).
- StreamripClient counted metadata tracks (always full) -> a partial download
falsely imported; now count the actual files written (short count -> needs_attention).
- streamrip writes into a nested 'Artist - Album [..]/' folder the tagger never saw;
flatten audio files up into the album dir so tagging/organization runs.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-07-11 01:01:23 +02:00
Jonathan
00b3dddca6
feat: Qobuz auth-token (user_id + token) login as a reliable alternative to email/password
...
Qobuz's email/password API login returns 401 even with valid credentials
(a known Qobuz limitation, unaffected by streamrip version). Add settings
fields for a Qobuz user ID + auth token (token stored encrypted); when both
are present StreamripClient uses use_auth_token=True, else falls back to
email/password.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-07-11 00:46:17 +02:00
Jonathan
caa0d542ea
fix: MD5-hash Qobuz password and never log credential-bearing login errors
...
streamrip's email/password login expects the MD5 digest, not plaintext
(caused 'Invalid credentials'). Also wrap login() so streamrip's exception —
which embeds the email/password/app_id — can never reach the worker logs;
re-raise a clean credential-free RuntimeError instead.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-07-11 00:30:34 +02:00
Jonathan
f91117092b
refactor: use one album path for tagging and library record
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-07-11 00:09:42 +02:00
Jonathan
1596bab23e
feat: wire the mutagen tagger into the worker loop
2026-07-10 23:59:28 +02:00
Jonathan
d1fcfd544f
fix: make album tagging best-effort per file
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-07-10 23:57:28 +02:00
Jonathan
32deac65a6
feat: real mutagen tagger and MusicBrainz tracklist
2026-07-10 23:52:19 +02:00
Jonathan
1c02a870f3
feat: Tagger seam and pipeline tag-stage integration
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-07-10 23:47:20 +02:00
Jonathan
2812695465
feat: organized album directory and persistent /music bind-mount
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-07-10 23:43:15 +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
fef8cf0681
feat: wire MusicBrainz resolver into the worker loop
2026-07-10 23:27:28 +02:00
Jonathan
85c74ba109
feat: add real MusicBrainz resolver and opt-in live test
2026-07-10 23:21:50 +02:00
Jonathan
c16e9f1035
feat: MusicBrainz-aware intake and completeness check against canonical track count
2026-07-10 23:17:06 +02:00
Jonathan
cf5632aa5f
fix: isolate per-adapter search failures in the pipeline match loop
...
Wrap each adapter's search() call in the match stage in try/except so
a down source (dead slskd, Qobuz auth error, etc.) contributes no
candidates instead of crashing run_pipeline and killing the worker.
2026-07-10 23:12:33 +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
f93d71f78a
test: verify SoulseekAdapter through the pipeline and full ranking order
2026-07-10 22:56:23 +02:00
Jonathan
6b09047f64
feat: add Soulseek to the config-aware registry
2026-07-10 22:53:25 +02:00
Jonathan
ec1fc568ba
fix: scope slskd download polling to enqueued files and raise on timeout
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-07-10 22:52:03 +02:00
Jonathan
7b4b7ef1aa
feat: add real slskd Soulseek client and opt-in live test
2026-07-10 22:45:36 +02:00
Jonathan
b5931a7b66
feat: add SoulseekAdapter with injectable client seam
2026-07-10 22:40:53 +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
7510e7718b
test: verify real QobuzAdapter flows through the pipeline and outranks YouTube
2026-07-10 22:16:03 +02:00
Jonathan
71143dc15d
feat: config-aware registry gating Qobuz on credentials; wire config into worker
2026-07-10 22:13:11 +02:00
Jonathan
085193aa82
fix: run Qobuz login inside try/finally and reuse a single streamrip config
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-07-10 22:11:25 +02:00
Jonathan
707038da64
feat: add real streamrip Qobuz client and opt-in live test
2026-07-10 22:05:36 +02:00
Jonathan
0091c4f5e7
feat: add QobuzAdapter with injectable client seam
2026-07-10 21:59:57 +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
f3d718d9c0
test: verify real YouTubeAdapter flows through the pipeline
2026-07-10 21:33:05 +02:00
Jonathan
4b2b2888ca
feat: wire real YouTube adapter into the registry
2026-07-10 21:29:26 +02:00
Jonathan
a93c248aaf
feat: add real yt-dlp client and opt-in live test; ffmpeg in worker image
2026-07-10 21:24:05 +02:00
Jonathan
5a3e64b057
feat: add YouTubeAdapter with injectable client seam
2026-07-10 21:19:27 +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
feaff42010
feat: add worker config reader with secret decryption
2026-07-10 20:07:49 +02:00
Jonathan
c90e055343
feat: add worker AES-256-GCM crypto matching the web envelope
2026-07-10 20:03:28 +02:00
Jonathan
69a8835c86
feat: add settings page for credentials
2026-07-10 19:58:46 +02:00
Jonathan
1b11fa37bd
feat: add config API with encrypted secret storage
2026-07-10 19:54:27 +02:00
Jonathan
91ea32c4b8
feat: add web AES-256-GCM secret crypto and LYRA_SECRET_KEY plumbing
2026-07-10 19:50:16 +02:00
Jonathan
45cf9e8527
feat: add Config schema
2026-07-10 19:46:17 +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
d3bec2ee10
refactor: make adapter .tier the single source of truth for ranking
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-07-10 19:07:58 +02:00
Jonathan
fbd6a056a4
feat: wire adapter registry into worker loop
2026-07-10 18:59:28 +02:00
Jonathan
7c28eddd47
fix: persist all found candidates and guard duplicate adapter names
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-07-10 18:54:15 +02:00
Jonathan
71c7945da2
feat: replace fake pipeline with staged adapter-driven pipeline
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-07-10 18:45:01 +02:00
Jonathan
60f3cd0df9
feat: add Candidate and LibraryItem schema
...
Adds Candidate (per-job download candidates found by the pipeline)
and LibraryItem (per-request imported album, deduped on
artist+album) tables. LibraryItem.requestId is @unique since
Request.libraryItem is a one-to-one back-relation (required for
Prisma validation, matching the existing Job.requestId pattern).
2026-07-10 18:40:41 +02:00
Jonathan
991365e746
feat: add SourceAdapter contract and fake adapters
2026-07-10 18:35:52 +02:00
Jonathan
ffc4d1f483
feat: add candidate ranker with confidence gate
2026-07-10 18:31:09 +02:00