- backend: /api/health, /api/login|logout|session, sessionscookie, timingSafeEqual-lösenordskoll, allt annat under /api kräver inloggning, serverar byggd frontend med SPA-fallback; 4 tester (node:test) - frontend: Vue 3 + Vite, login-sida, Upptäck-skal, sökfält (stub), mörkt tema enligt Jellyseerr-förlagan - docker: multi-stage arm64-image; config-plumbing för Lidarr/Jellyfin/ Gemini via env (Jellyfin-historik prioriterad som signal per Björn) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01824ZrvG2mDYYrmwqypLNup
3.8 KiB
lyssnarr — plan
Goal
Self-hosted music-discovery web app on the Pi5. A Jellyseerr-style UI where Björn can (a) search for new artists, albums and tracks, and (b) get scheduled AI-generated suggestions based on two taste signals: recent listening in the local library (Jellyfin) and tracks recently added to his YouTube Music playlists (via Youtubarr's data). Every result can be added to Lidarr with one click, opened in YouTube Music, or played inline in the app.
Stack
- Backend: Node ≥ 20, Fastify, better-sqlite3 (suggestion history + feedback), node-cron (scheduled generation)
- Frontend: Vue 3 + Vite; dark, poster/card-based UI modelled on Jellyseerr (top search bar, discover grid, action buttons per card); built to static files served by the backend
- Container: single arm64 image, multi-stage Dockerfile (frontend build → backend deps → slim runtime), mirrors Archivum
Deploy target
Pattern B (container on Pi5):
Gitea Actions on the Pi5 runner → localhost:5000/lyssnarr:latest →
Dockge stack /srv/dockge-staks/lyssnarr/ → NPM vhost
https://lyssnarr.brasse-pc.eu (public from day one → the app ships
with login from day one: single user, bcrypt-hashed password from the
stack .env, signed session cookie).
Integrations
| What | How |
|---|---|
| Lidarr | REST API (http://lidarr:8686): add/monitor artists & albums, check what's already in the library |
| MusicBrainz | search + canonical MBIDs (Lidarr adds are MBID-based) |
| YouTube Music | unofficial YT Music search from Node → browse/video IDs for "open in YT Music" deep links, thumbnails for the cards, inline playback via YouTube IFrame embed |
| Gemini API | suggestion generation; GEMINI_API_KEY + model via env |
| Youtubarr | read-only mount of its SQLite (/srv/docker/youtubarr/data/db.sqlite3) → "recently added to playlists" signal |
| Jellyfin | play-history signal (prioritised by Björn 2026-07-31) — infra prerequisite: mount /srv/storage1/Music into the jellyfin container + create a music library (container recreate, needs Björn's OK) |
UI sketch (Jellyseerr-like)
- Top: search bar with artist/album/track scope
- Landing "Upptäck": latest suggestion batch as poster cards, each with Gemini's one-line motivation
- Card actions: ➕ Lidarr · ▶ Spela (inline YouTube embed) · ↗ YT Music (deep link)
- Badge on cards already in the Lidarr library
- History page with earlier batches
Milestones
- Skeleton end-to-end — repo, CI, Dockerfile, dockge stack, NPM
vhost, login; an empty authenticated shell reachable on
lyssnarr.brasse-pc.eu - Lidarr integration — library state + add/monitor actions
- Search page — MusicBrainz search enriched with YT Music thumbnails/links, add/play/open actions
- On-demand suggestions — "generera nu": Gemini prompt built from Lidarr library + Youtubarr playlist adds + Jellyfin play history (used as soon as it's configured)
- Scheduler + history — cron-generated batches, history page
- Jellyfin music library — infra step on the Pi5 (mount + library) so the play-history signal has data
Roadmap / expansions (proposed — Björn confirms/strikes)
- 👍/👎 feedback per suggestion, fed into the next Gemini prompt
- Auto-add top suggestions to Lidarr as monitored (configurable)
- Track-level batches exported as M3U playlists into Jellyfin
- Library profile page (genre/decade distribution)
- Webhook/notification when a new batch lands
- Liked Music as a direct signal (ytmusicapi sidecar or Node port)
Open questions
- Gemini model: default
gemini-2.5-flash, configurable via env — ok? - Auth: built-in single-user login vs Authentik forward-auth later
- Artwork order: YT Music thumbnails first, Cover Art Archive fallback