Commit Graph
18 Commits
Author SHA1 Message Date
Admin dd3150e3d4 perf(backend): cache YouTube searches and shrink the thumbnail URLs
Repeated searches and song lookups now reuse a single-flight memory cache, so
concurrent or debounced queries hit YouTube once instead of on every keystroke.
Thumbnails are resolved at a configurable size instead of the largest variant,
which cuts the image payload the browser pulls from Google.
2026-07-20 17:29:28 +02:00
Admin b3eff65000 refactor(backend): clean up the AppSettings files
Drop the dead Keycloak and ConnectionStrings sections from the Worker and move
its hardcoded dev values to AppSettings.Development.json, so the base file is
the empty template the convention describes. Remove the stale Authentication
block from the API dev settings (provisioning writes those to user-secrets) and
the ManifestFileName left over from DASH. Point the stream-ticket key and the
Worker scratch directory at deploy/keys and deploy/.tmp instead of D:\weed and
D:\tempsFilesDev, and make the API listen on localhost instead of a fixed LAN
address.
2026-07-20 15:13:27 +02:00
Admin 2dc544b2c0 Changes 2026-07-18 23:29:57 +02:00
Admin 4a802e44a3 refactor(backend): unify YouTube track creation via a provisioner
Track get-or-create for YouTube videos was duplicated between the
old GetYouTubeTrackStream query handler (which also wrote to the
database) and AddYouTubeTrackToPlayList, with frontend-supplied
metadata (title/artist/duration/thumbnail) trusted at add-to-playlist
time instead of resolving it server-side.

Extract YouTubeTrackProvisioner as the single get-or-create path,
resolving structured artist refs (id + name) from YouTube Music so
multi-artist songs map to distinct Artist rows. Rename
GetYouTubeTrackStream to ResolveYouTubeTrackStream (it writes, so it
is a command, not a query) and delegate to the provisioner.
AddYouTubeTrackToPlayList slims down to (UserId, PlayListId, VideoId)
since all metadata now comes from the provisioner/YouTube API.
2026-07-17 17:56:37 +02:00
Admin 73826b9d08 feat(backend): auto-download YouTube tracks saved to playlists 2026-07-16 01:06:04 +02:00
Admin 11ed8b40ff feat(backend): YouTube Music search and playback resolution endpoints 2026-07-16 01:05:42 +02:00
Admin b4b08aa3fd feat(backend): add playlist cover endpoint and relax description validation
Adds GET /playlists/{id}/cover (mirrors the track cover endpoint) so
uploaded playlist pictures can actually be served. Also drops the
NotEmpty rule on playlist description, which rejected the blank
description the frontend treats as optional; CreatePlayList now falls
back to the domain's default text instead.
2026-07-15 16:09:40 +02:00
Admin f101ce69a0 Changes 2026-07-14 19:11:58 +02:00
Admin 54484d9fd4 feat(tracks): add track cover endpoint
Serve cover images via GET /tracks/{id}/cover with a size parameter, streamed from storage with long-lived immutable cache headers.
2026-07-14 04:54:40 +02:00
Admin 5c1edc0dc7 feat(tracks): add user listening history
Record a listening-history entry when a stream ticket is issued and expose GET /users/{id}/listening-history to read it back.
2026-07-14 04:54:35 +02:00
Admin 7aa5350484 fix(playlists): reject empty/whitespace name and description on update 2026-07-06 02:20:47 +02:00
Admin fabd26e42f feat(tracks): support search by name in GetTracks 2026-07-06 02:04:01 +02:00
Admin 695f4378c6 refactor(api): OpenAPI response metadata, cached user sync, ProblemDetails
- Document every endpoint's responses (Produces<T>/status codes/validation)
  so the generated OpenAPI/Scalar docs carry response schemas and status codes
  instead of empty responses
- Cache recently-synced user ids (IMemoryCache, 15 min) in the JWT
  TokenValidated handler so user provisioning no longer hits the DB on every
  authenticated request
- Add ProblemDetails + UseExceptionHandler for consistent RFC7807 errors
- Add ToCreatedResult ErrorOr helper and use it in the create endpoints
- Normalize the playlists route to lowercase (/playlists)

Verified: booted the Api against RabbitMQ + Postgres in Docker and inspected
/openapi/v1.json — operations now expose response schemas/status codes and the
route is /playlists.

Build: 0 warnings, 0 errors.
2026-07-05 21:04:15 +02:00
Admin a37dcc1b45 Formatting 2026-07-05 16:04:53 +02:00
Admin c84e29ed54 refactor(di): add AddApplication entry point and generic AddValidatedOptions
- Add Musify.Application.AddApplication(services, config) as the layer's DI
  entry point: registers Mediator, UploadIntentValidator and all app configs
- Collapse the 5 near-identical AddXConfiguration methods into a single
  generic AddValidatedOptions<T>(config, section)
- Move UploadIntentValidator registration out of Infrastructure into the
  Application layer (fixes layering leak); Infra config binding now uses the
  generic helper
- Api calls AddApplication; Worker uses AddValidatedOptions for its configs

Build: 0 warnings, 0 errors.
2026-07-05 04:36:46 +02:00
Admin db38740139 refactor(application): co-locate each command/query with its handler
One file per use case under the feature folder (Tracks/PlayLists/Users),
dropping the Commands/Queries/Handlers sub-folders and their namespaces.
Each file now holds the record and its handler in namespace
Musify.Application.<Feature>; external usings updated accordingly.

Build: 0 warnings, 0 errors.
2026-07-05 04:12:59 +02:00
Admin bf3b5ceedb refactor: replace Ardalis.Result with ErrorOr across the app
Ardalis Result<T> carried incoherent success sub-statuses and a clunky
generic converter; ErrorOr models success-or-errors cleanly.

- Application: all commands/queries/handlers now return ErrorOr<T>
  (non-generic Result -> ErrorOr<Success>); errors via Error.NotFound/
  Conflict/Validation/Unauthorized/Failure; success via value or new Success()
- Drop ResultExtensions.As<>(): error propagation is now just return .Errors
- Rewrite HTTP mapping (ErrorOrHttpExtensions) off Error.Type; success maps
  to 200 (value) or 204 (Success); Created still built in the endpoints
- Endpoints/gateway middleware: !IsSuccess -> IsError
- Swap Ardalis.Result package for ErrorOr 2.1.1 (remove unused ref from Worker)

Build: 0 warnings, 0 errors.
2026-07-05 04:05:43 +02:00
Admin f2933caa90 chore: group .NET into backend/ and drop non-.NET test artifacts
- Move all .NET (6 projects, solution, Directory.*.props, nuget.config)
  into backend/ so the monorepo root can host non-.NET projects later
- Remove throwaway test artifacts: player.html, pl.json
- Trim dead Flutter rules from .gitignore

Build from backend/Musify.slnx: 0 warnings, 0 errors.
2026-07-05 03:43:52 +02:00