Commit Graph
11 Commits
Author SHA1 Message Date
Admin f54ebec0eb Changes 2026-07-25 01:46:59 +02:00
Admin a59fa3a548 fix(backend): give track titles room to breathe
Titles were capped at 50 characters and the YouTube provisioner silently cut
them there, which mangles anything with a feature or a remix suffix. Albums
are about to make that far more visible, so the column now holds 200.
2026-07-20 20:06:47 +02:00
Admin 2dc544b2c0 Changes 2026-07-18 23:29:57 +02:00
Admin 4fed9bd059 A lot of changes 2026-07-17 18:56:23 +02:00
Admin 1bd6f18c5e fix(backend): propagate user renames to artist and harden migration backfill
Code review of the Artist/ownership refactor surfaced three gaps:

- SyncUser updated User.Name on every login but never the linked
  Artist row, so renames never reached track credits - defeating the
  point of centralizing names in Artist.
- YouTubeTrackProvisioner looked up artists by ExternalId only when a
  browseId was known, so it could never reuse the ExternalId-less
  rows the migration backfilled from legacy Artist strings, creating
  duplicate Artist rows for the same person. It now adopts the
  backfilled row (assigning it the browseId) when one matches by
  normalized name.
- AddArtistsAndTrackOwnership deduped legacy YouTube artist strings
  case-sensitively before hashing them into a case-insensitive unique
  index, and never guarded against local tracks with no UserHasTrack
  row - either would abort the migration on real data. Backfill now
  dedupes via DISTINCT ON over the normalized name and drops orphaned
  local tracks before the ownership check constraint is added.
2026-07-17 18:00:00 +02:00
Admin daec1a8d05 refactor(backend): group track pipeline state into owned types
Track mixed catalog fields (Title, Artist credit, Duration) with
picture-processing and audio-transcode pipeline state as ten flat
columns plus two computed [NotMapped] flags, making the entity read
like a media-pipeline worksheet.

Introduce TrackPictures and TrackAudio as EF owned types mapped onto
the same existing columns (explicit column names, no schema change -
verified via `dotnet ef migrations has-pending-model-changes`).
Track now reads as Title/Artist/Duration/Pictures/Audio instead of
fourteen loose properties.
2026-07-17 17:58:56 +02:00
Admin 64e1f3903e refactor(backend): read artist credit from TrackArtists join
Drop the now-redundant Track.Artist string column now that every
track (local and YouTube) links its credited artists through
TrackArtist. TrackApplicationResponse formats the display string by
joining TrackArtists ordered by position, and every read query that
projects a track now includes TrackArtists/Artist so the join isn't
empty at response time.
2026-07-17 17:57:22 +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 11ed8b40ff feat(backend): YouTube Music search and playback resolution endpoints 2026-07-16 01:05:42 +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