Commit Graph

114 Commits

Author SHA1 Message Date
Boris Cherepanov df8d8f0d73 Merge branch 'DEV' into feature/node-app
Publish Metadata Agent Image / build-and-push-image (push) Successful in 1m5s
Publish Node Player Image / build-and-push-image (push) Failing after 26s
Publish Web Player Image / build-and-push-image (push) Successful in 1m43s
2026-04-19 21:11:31 +03:00
Boris Cherepanov 74d7b10386 feat: remove useless host
Publish Metadata Agent Image / build-and-push-image (push) Successful in 2m41s
Publish Web Player Image / build-and-push-image (push) Successful in 1m7s
2026-04-19 21:01:30 +03:00
ab 9467737a7c Merge pull request 'fix(node-player): remove unused API_ROOT import from NowPlaying' (#13) from feature/USERS into DEV
Publish Node Player Image (dev) / build-and-push-image (push) Successful in 2m12s
Publish Web Player Image (dev) / build-and-push-image (push) Successful in 1m49s
Publish Metadata Agent Image (dev) / build-and-push-image (push) Successful in 1m24s
Reviewed-on: #13
2026-04-08 16:55:19 +00:00
Ultradesu 2edc293ee0 fix(node-player): remove unused API_ROOT import from NowPlaying
Publish Web Player Image / build-and-push-image (push) Has been cancelled
Publish Node Player Image / build-and-push-image (push) Has been cancelled
Publish Metadata Agent Image / build-and-push-image (push) Has been cancelled
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 17:54:53 +01:00
ab 5c7f940b7e Merge pull request 'feature/USERS' (#12) from feature/USERS into DEV
Publish Metadata Agent Image (dev) / build-and-push-image (push) Successful in 44s
Publish Node Player Image (dev) / build-and-push-image (push) Failing after 27s
Publish Web Player Image (dev) / build-and-push-image (push) Successful in 1m25s
Reviewed-on: #12
2026-04-08 16:51:24 +00:00
Ultradesu 4a39d44211 fix(node-player): use AuthImg component for cover art with Bearer auth
Publish Web Player Image / build-and-push-image (push) Has been cancelled
Publish Node Player Image / build-and-push-image (push) Has been cancelled
Publish Metadata Agent Image / build-and-push-image (push) Has been cancelled
SW doesn't reliably intercept <img> requests (no-cors mode). Use a
thin AuthImg component that loads images via axios (which has the
Bearer token) and displays them as blob URLs. Audio streaming still
works via SW.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 17:50:19 +01:00
Ultradesu d3aba1152c fix(node-player): use blob for audio stream, keep SW for cover art
<audio> elements with Sec-Fetch-Mode: no-cors are unreliable with
Service Workers across browsers. Revert stream to blob download via
axios (Bearer token works). SW remains for cover art in <img> tags.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 17:45:54 +01:00
Ultradesu c11b71a0ef fix(node-player): use IndexedDB for SW token instead of postMessage
postMessage is unreliable on first load — SW may not be active yet.
IndexedDB is shared between page and SW, so the token is always
available regardless of SW lifecycle timing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 17:43:33 +01:00
Ultradesu ea2fc53faf fix(node-player): proxy /api through vite dev server for same-origin SW
Service Worker only intercepts same-origin requests. In dev mode, API
calls went directly to localhost:8085 (cross-origin), bypassing the SW.
Now vite proxies /api to Rust API, keeping everything same-origin so
the SW can inject Bearer tokens for audio/image requests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 17:40:47 +01:00
Ultradesu d6dd046fad feat(node-player): use Service Worker for auth, enable streaming playback
Add a Service Worker that intercepts /api/* requests and injects the
Bearer token. This allows <audio> and <img> elements to use direct
URLs instead of downloading entire files as blobs first.

- Audio now streams progressively (no full download before playback)
- Cover art loads via regular <img src> (SW adds auth header)
- Remove blob-based preloadStream, fetchCoverBlob, useCoverUrl hook
- Register SW in main.tsx, token synced via postMessage

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 17:30:17 +01:00
ab 3fa79423bd Merge pull request 'feature/USERS' (#11) from feature/USERS into DEV
Publish Metadata Agent Image (dev) / build-and-push-image (push) Successful in 1m28s
Publish Node Player Image (dev) / build-and-push-image (push) Successful in 37s
Publish Web Player Image (dev) / build-and-push-image (push) Successful in 1m53s
Reviewed-on: #11
2026-04-08 16:23:15 +00:00
Ultradesu 6b1aa6b5d5 feat: add recent plays history modal
Publish Metadata Agent Image / build-and-push-image (push) Successful in 1m23s
Publish Node Player Image / build-and-push-image (push) Successful in 37s
Publish Web Player Image / build-and-push-image (push) Successful in 1m49s
- GET /api/me/recent endpoint returning last 50 play events with track
  and artist info
- RecentPlays modal component with time-ago display
- "Recent plays" button in user dropdown menu
- Clicking a track in history starts playback

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 17:08:54 +01:00
Ultradesu 4fdd56dae4 feat: add user support with play event tracking
Backend (Rust API):
- Add users and play_events tables (migration 0005)
- Extract full user identity from JWT (sub, username, email, name)
  and pass AuthUser via request extensions to all handlers
- Auto-upsert user in background on every authenticated request
- POST /api/tracks/:slug/play endpoint to record play events
- Allow POST method in CORS

Frontend (Node player):
- Call recordPlay() when a track starts playing
- Add user profile avatar with dropdown menu (name, email, sign out)
- Pass user info from App through FurumiPlayer to Header

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 16:51:53 +01:00
Ultradesu 5bc2b55ffd feat(node-player): remove run-without-auth option from login page
Publish Metadata Agent Image (dev) / build-and-push-image (push) Successful in 1m28s
Publish Node Player Image (dev) / build-and-push-image (push) Successful in 38s
Publish Web Player Image (dev) / build-and-push-image (push) Successful in 1m56s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 16:32:19 +01:00
Ultradesu ed918b9373 feat(node-player): redesign auth page with loading state
Publish Metadata Agent Image (dev) / build-and-push-image (push) Successful in 1m31s
Publish Node Player Image (dev) / build-and-push-image (push) Successful in 43s
Publish Web Player Image (dev) / build-and-push-image (push) Successful in 2m22s
- Show spinner while checking session (no login form flash on refresh)
- Translate UI to English
- Match player's dark theme (colors, fonts, card style)
- Render login form only when authentication is actually needed

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 16:27:22 +01:00
Ultradesu 1ea5f66ea3 fix(node-player): add offline_access scope and server-side token refresh
Publish Metadata Agent Image (dev) / build-and-push-image (push) Has been cancelled
Publish Node Player Image (dev) / build-and-push-image (push) Successful in 36s
Publish Web Player Image (dev) / build-and-push-image (push) Successful in 1m50s
- Add offline_access to OIDC scope so Authentik issues a refresh token
- /auth/token now checks if access token is expired and refreshes it
  server-side before returning to the client

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 16:01:16 +01:00
Ultradesu 7bc7de44cf fix(node-player): restore useEffect import in QueueList
Publish Metadata Agent Image (dev) / build-and-push-image (push) Has been cancelled
Publish Node Player Image (dev) / build-and-push-image (push) Successful in 38s
Publish Web Player Image (dev) / build-and-push-image (push) Successful in 1m48s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 15:44:28 +01:00
Ultradesu befba57374 fix(node-player): auto-refresh expired JWT tokens on 401
Publish Metadata Agent Image (dev) / build-and-push-image (push) Has been cancelled
Publish Node Player Image (dev) / build-and-push-image (push) Failing after 28s
Publish Web Player Image (dev) / build-and-push-image (push) Has been cancelled
Adds an axios response interceptor that catches 401 errors, fetches a
fresh access token from /auth/token, and retries the original request.
Concurrent refresh attempts are deduplicated.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 15:41:47 +01:00
Ultradesu a9a8ee81b8 fix(node-player): load cover art via axios with Bearer token
Publish Metadata Agent Image (dev) / build-and-push-image (push) Successful in 1m22s
Publish Node Player Image (dev) / build-and-push-image (push) Failing after 29s
Publish Web Player Image (dev) / build-and-push-image (push) Has been cancelled
Cover images were loaded via <img src> which doesn't include the
Authorization header, resulting in 401 from the Rust API. Now covers
are fetched through axios as blobs and displayed via object URLs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 15:39:52 +01:00
ab 1df10fb0b7 Merge pull request 'fix(node-player): use Express 5 catch-all route syntax' (#10) from feature/JWT-OIDC-SSO into DEV
Publish Metadata Agent Image (dev) / build-and-push-image (push) Has been cancelled
Publish Node Player Image (dev) / build-and-push-image (push) Successful in 37s
Publish Web Player Image (dev) / build-and-push-image (push) Successful in 1m48s
Reviewed-on: #10
2026-04-08 14:21:54 +00:00
Ultradesu b1f75b3ee2 fix(node-player): use Express 5 catch-all route syntax
Publish Metadata Agent Image / build-and-push-image (push) Has been cancelled
Publish Web Player Image / build-and-push-image (push) Has been cancelled
Publish Node Player Image / build-and-push-image (push) Has been cancelled
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 15:20:02 +01:00
ab 5a5c9967e1 Merge pull request 'fix(node-player): use expires_in instead of expires_at on AccessToken type' (#9) from feature/JWT-OIDC-SSO into DEV
Publish Metadata Agent Image (dev) / build-and-push-image (push) Successful in 3m38s
Publish Node Player Image (dev) / build-and-push-image (push) Successful in 36s
Publish Web Player Image (dev) / build-and-push-image (push) Successful in 1m50s
Reviewed-on: #9
2026-04-08 14:11:17 +00:00
Ultradesu f3392eff9f fix(node-player): use expires_in instead of expires_at on AccessToken type
Publish Web Player Image / build-and-push-image (push) Waiting to run
Publish Metadata Agent Image / build-and-push-image (push) Successful in 4m18s
Publish Node Player Image / build-and-push-image (push) Successful in 1m20s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 15:01:30 +01:00
ab e920059125 Merge pull request 'feature/JWT-OIDC-SSO' (#8) from feature/JWT-OIDC-SSO into DEV
Publish Web Player Image (dev) / build-and-push-image (push) Has been cancelled
Publish Node Player Image (dev) / build-and-push-image (push) Has been cancelled
Publish Metadata Agent Image (dev) / build-and-push-image (push) Has been cancelled
Reviewed-on: #8
2026-04-08 13:53:36 +00:00
Ultradesu e99cacae8b feat(auth): replace cookie/api-key auth with JWT Bearer tokens, separate UI from API
Publish Metadata Agent Image / build-and-push-image (push) Successful in 6m3s
Publish Node Player Image / build-and-push-image (push) Failing after 58s
Publish Web Player Image / build-and-push-image (push) Has been cancelled
- Add JWT Bearer token validation to Rust API via OIDC provider JWKS
  with automatic key rotation and 1-hour cache
- Remove x-api-key auth support and built-in web UI from furumi-web-player,
  leaving it as a pure API server
- Add /auth/token endpoint to Node player server to expose OIDC access
  tokens to the frontend
- Move Node player auth endpoints from /api/* to /auth/* to avoid
  path conflicts with Rust API
- Add static file serving to Node Express server for production
  single-container deployment
- Fix SameSite=Strict cookie issue breaking OIDC redirect flow (use Lax)
- Add Dockerfile.node-player with multi-stage Node.js build
- Add CI workflows for node-player Docker image (dev + release)
- Optimize Rust Dockerfiles with dependency caching layer
- Update docker-compose with OIDC env vars and OLLAMA_MODEL support
- Cherry-pick agent LLM client fixes from DEV branch

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 14:51:52 +01:00
ab 48c473de56 fix(agent): increase max_tokens for merge requests to avoid truncated responses
Publish Metadata Agent Image (dev) / build-and-push-image (push) Successful in 3m43s
Publish Web Player Image (dev) / build-and-push-image (push) Successful in 4m20s
normalize: 512 tokens (sufficient for single track metadata)
merge: 4096 tokens (needed for artists with many albums)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 22:52:23 +01:00
ab 1e75644abb feat(agent): switch LLM client from Ollama to OpenAI-compatible API (LM Studio support)
Publish Metadata Agent Image (dev) / build-and-push-image (push) Successful in 4m7s
Publish Web Player Image (dev) / build-and-push-image (push) Successful in 3m57s
- Replace /api/chat with /v1/chat/completions endpoint
- Use json_schema response_format (LM Studio does not support json_object)
- Make schema parameter optional in call_ollama to support different schemas per use case
- Add dedicated normalize schema (normalized_metadata) with release_kind field
  instead of release_type to avoid model repetition loops
- Add dedicated merge schema (artist_merge) so model no longer confuses
  normalize and merge response structures
- Add retry with frequency_penalty=1.5 on parse failure to suppress repetition
- Add id3 crate as fallback metadata reader for MP3 files with large embedded
  cover art that exceed Symphonia probe limit of 1MB

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 22:34:39 +01:00
ab 2d7ac3d8ce Fixed openai api endpoint
Publish Metadata Agent Image (dev) / build-and-push-image (push) Successful in 4m0s
Publish Web Player Image (dev) / build-and-push-image (push) Successful in 4m23s
2026-04-07 19:52:03 +01:00
ab 70a947a8c1 Fixed openai api endpoint
Publish Metadata Agent Image (dev) / build-and-push-image (push) Successful in 3m38s
Publish Web Player Image (dev) / build-and-push-image (push) Successful in 3m49s
2026-04-07 19:32:17 +01:00
Boris Cherepanov 94d14e8fc8 feat: update styles
Publish Metadata Agent Image / build-and-push-image (push) Successful in 5m22s
Publish Web Player Image / build-and-push-image (push) Successful in 4m15s
2026-04-04 19:34:20 +03:00
Boris Cherepanov 0b6f518b72 feat: refactoring
Publish Metadata Agent Image / build-and-push-image (push) Successful in 4m2s
Publish Web Player Image / build-and-push-image (push) Successful in 4m47s
2026-04-04 19:17:33 +03:00
Boris Cherepanov 3199c12af5 feat: added alternative queue display
Publish Metadata Agent Image / build-and-push-image (push) Successful in 3m58s
Publish Web Player Image / build-and-push-image (push) Successful in 4m16s
2026-04-04 18:49:29 +03:00
Boris Cherepanov daaa3b0814 feat: update styles 2026-04-04 18:33:45 +03:00
Boris Cherepanov e42566f44e fix: correct behavior click of buttons
Publish Metadata Agent Image / build-and-push-image (push) Successful in 3m46s
Publish Web Player Image / build-and-push-image (push) Successful in 5m1s
2026-04-02 00:48:57 +03:00
Boris Cherepanov 30c6400354 feat: create playback service
Publish Metadata Agent Image / build-and-push-image (push) Successful in 7m58s
Publish Web Player Image / build-and-push-image (push) Has been cancelled
2026-04-02 00:38:30 +03:00
Boris Cherepanov 480880f292 fix: load audio thmb 2026-04-02 00:29:21 +03:00
Boris Cherepanov 83a145d0a8 feat: work with order in state 2026-04-02 00:13:30 +03:00
XakPlant aea4aef4b2 Merge pull request 'feature/node-app' (#7) from feature/node-app into DEV
Publish Metadata Agent Image (dev) / build-and-push-image (push) Successful in 1m8s
Publish Web Player Image (dev) / build-and-push-image (push) Successful in 1m7s
Reviewed-on: #7
2026-03-23 14:00:08 +00:00
Boris Cherepanov 8ceee6028a fix: then height 100%
Publish Metadata Agent Image / build-and-push-image (push) Successful in 1m5s
Publish Web Player Image / build-and-push-image (push) Successful in 1m6s
2026-03-23 16:55:22 +03:00
Boris Cherepanov 3491c52793 feat: refactoring data fetching 2026-03-23 16:55:22 +03:00
Boris Cherepanov f0e1bbc7f8 feat: added redux 2026-03-23 16:55:22 +03:00
Boris Cherepanov 8f38e27eb0 feat: addex type declaration 2026-03-23 16:55:22 +03:00
Boris Cherepanov 8cac2d1160 feat: refactoring 2026-03-23 16:55:22 +03:00
Boris Cherepanov 5a5dab85d0 feat: added api conversation + api review 2026-03-23 16:55:22 +03:00
Boris Cherepanov 310f0061d3 feat: added cors for web-player-backend 2026-03-23 16:55:22 +03:00
Boris Cherepanov f26135ca25 feat: added auth by api key 2026-03-23 16:55:22 +03:00
ab 71d5a38f21 Fix source-missing auto-merge and remove Pink Floyd examples from prompts
Publish Metadata Agent Image (dev) / build-and-push-image (push) Successful in 1m10s
Publish Web Player Image (dev) / build-and-push-image (push) Successful in 1m10s
Auto-merge: when ingest pipeline detects "source file missing", now checks
if the track already exists in the library by file_hash. If so, marks the
pending entry as 'merged' instead of 'error' — avoiding stale error entries
for files that were already successfully ingested in a previous run.

Prompts: replaced Pink Floyd/The Wall/Have a Cigar examples in both
normalize.txt and merge.txt with Deep Purple examples. The LLM was using
these famous artist/album/track names as fallback output when raw metadata
was empty or ambiguous, causing hallucinated metadata like
"artist: Pink Floyd, title: Have a Cigar" for completely unrelated tracks.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 01:05:22 +00:00
ab 8d70a5133a Disabled obsolete CI
Publish Metadata Agent Image (dev) / build-and-push-image (push) Successful in 1m17s
Publish Web Player Image (dev) / build-and-push-image (push) Successful in 1m14s
2026-03-20 00:49:27 +00:00
ab 56760be586 Disabled obsolete CI
Publish Metadata Agent Image (dev) / build-and-push-image (push) Failing after 10s
Publish Web Player Image (dev) / build-and-push-image (push) Failing after 9s
2026-03-20 00:01:30 +00:00
ab 108c374c6d ci: update Dockerfile paths after moving to docker/ directory
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 00:00:42 +00:00