music: self-hosted scrobbler (Spotify poller, Last.fm + streaming-history importers, /trackers/music, homepage listening card)
All checks were successful
Deploy production / deploy (push) Successful in 2m37s

- music schema: artists/albums/tracks (+album art), plays with source + dedupe, now_playing,
  spotify_auth, import_state; plays_deduped view hides Last.fm scrobbles Spotify also has
- in-app Spotify poller (60s, leased) started from hooks init; no new role or env needed
- /api/spotify/connect + callback (owner only), /trackers/music public stats
- scripts: music-poll, music-import-lastfm (resumable), music-import-history
- deploy/music-collector: optional host timer with its own role
This commit is contained in:
2026-10-24 15:56:50 +00:00
parent 45c124a365
commit b757269151
37 changed files with 22124 additions and 6 deletions

View File

@@ -1,4 +1,5 @@
import type { Handle } from '@sveltejs/kit/hooks';
import type { Handle, ServerInit } from '@sveltejs/kit/hooks';
import { startMusicPoller } from '#lib/server/music/poller.js';
import { building } from '$app/env';
import { auth } from '#lib/server/auth.js';
import { isOwner, isOwnerOnlyPath, isOwnerWritePath } from '#lib/server/owner.js';
@@ -6,6 +7,11 @@ import { error } from '@sveltejs/kit';
const analytics = /<!-- analytics -->[\s\S]*?<!-- \/analytics -->/;
// Background jobs that live in the app process: the Spotify scrobbler (idle until connected).
export const init: ServerInit = () => {
if (!building) startMusicPoller();
};
export const handle: Handle = async ({ event, resolve }) => {
// Match the endpoint path here: the dev proxy may terminate HTTPS before Vite.
// Better Auth validates request origins against its configured public URL.