All checks were successful
build-and-push / build (push) Successful in 32s
- 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
82 lines
3.8 KiB
Markdown
82 lines
3.8 KiB
Markdown
# 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
|
||
|
||
1. **Skeleton end-to-end** — repo, CI, Dockerfile, dockge stack, NPM
|
||
vhost, login; an empty authenticated shell reachable on
|
||
`lyssnarr.brasse-pc.eu`
|
||
2. **Lidarr integration** — library state + add/monitor actions
|
||
3. **Search page** — MusicBrainz search enriched with YT Music
|
||
thumbnails/links, add/play/open actions
|
||
4. **On-demand suggestions** — "generera nu": Gemini prompt built from
|
||
Lidarr library + Youtubarr playlist adds + Jellyfin play history
|
||
(used as soon as it's configured)
|
||
5. **Scheduler + history** — cron-generated batches, history page
|
||
6. **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
|