Commit Graph
146 Commits
Author SHA1 Message Date
Admin 03f5936944 Add track coauthors with invitations, acceptance and coauthor-aware track responses
Owners invite existing users to coauthor a track; invitees accept or reject,
and either side can remove a coauthor. Only accepted coauthors appear in track
responses and in the coauthor's public track list. The owner also receives the
full invitation list with statuses on the user tracks response.
2026-09-25 02:14:23 +02:00
Admin ebfd41b160 Add track publication, album types, optional track pictures and batch upload URLs
Tracks
- Track.IsPublished (migration marks existing tracks as published). New
  tracks are created unpublished.
- PUT /tracks/{id}/published and PUT /tracks/published change the flag;
  publishing requires completed audio processing (the batch endpoint
  reports skipped tracks).
- An unpublished track is only visible to its owner. A WherePublished /
  VisibleTo filter is applied to search, genres, listening history, last
  listened, likes, mixes, album and playlist contents and counts, recently
  listened albums, public user tracks, track details and stream tickets.
- isPublished is part of the track responses, GET /tracks/users/{userId}
  accepts a published filter and status-counts reports published and
  unpublished totals.
- CreateTrackRequest.pictureIntentId is optional: without it the track
  uses the album cover or the preset picture and no picture processing
  runs. CreateTrackResourcesEvent carries nullable picture fields, so
  queues must be drained before deploying.
- POST /tracks/upload-urls accepts an audios list and one optional picture
  shared by all of them, and returns an intent per file. The upload intent
  limits are raised so a batch fits.

Albums
- AlbumType (Album, EP, Single) on create, update and responses.
- CreateAlbumRequest.trackIds creates the album and links the tracks in a
  single save.
2026-09-25 01:37:55 +02:00
Admin d839a72700 Add track status filter and counts, album track ids and bulk track deletion
GET /tracks/users/{userId} accepts repeated status values and returns the
albums each track belongs to. GET /tracks/users/{userId}/status-counts,
GET /albums/{id}/tracks/ids and DELETE /tracks with a list of track ids
are new.
2026-09-25 01:14:59 +02:00
Admin e4e4617f6e Copy .editorconfig into the migrator image so analyzers match the local build 2026-09-24 19:08:50 +02:00
Admin 1a302491d1 Changes 2026-09-24 17:58:48 +02:00
Admin e84c16cf92 A lot of changes 2026-09-24 17:54:16 +02:00
Admin ece6ce2a43 Merge branch 'backend-refactor-rev' into audit-merge-three
Adapt the refactored web player to the new backend API (id path params,
bulk track adds, flat list items, mix kind) and port AddAlbumToPlayList
to the backend conventions.
2026-09-24 17:30:40 +02:00
Admin ecf9faf640 Merge branch 'frontend-refactor-rev' into audit-merge-three 2026-09-24 17:25:31 +02:00
Admin 35d6314ce8 Point the IDE dev settings at the shared Infrastructure stack
CI/CD / BackEnd (push) Successful in 1m18s
CI/CD / WebPlayer (push) Successful in 41s
CI/CD / Deploy (push) Skipped
appsettings.Development.json still targeted Musify's old own Postgres
(port 59000) with the superuser, the default RabbitMQ vhost as guest and
the admin S3 keys. They now use Infrastructure's dev ports and Musify's
own dev credentials (role, vhost and S3 identity), the same defaults as
deploy/.env.example.

The API's non-secret Zitadel settings (issuer, metadata, endpoints) move
there too, so user-secrets only need the per-machine client id.
2026-09-24 17:11:50 +02:00
Admin b8524aa5a8 Update naming conventions in .editorconfig and docs.editorc
CI/CD / BackEnd (push) Successful in 1m34s
CI/CD / WebPlayer (push) Successful in 39s
CI/CD / Deploy (push) Skipped
2026-09-24 13:31:31 +02:00
Admin 73e37dbecd Change editor rule 2026-09-24 13:24:43 +02:00
Admin 16478678b5 Use System.Text.Json number handling for long values 2026-09-24 13:14:05 +02:00
Admin 7f51145915 Update docs for the refactored backend and add backend conventions guide 2026-09-24 13:01:32 +02:00
Admin 28a7c4a98c Enable more analyzers, drop log-and-rethrow in file activities and apply dotnet format
Use invariant culture when formatting ids, put cancellation tokens last in endpoint handlers, remove the
CS8618 pragmas and keep only the analyzer overrides that still apply.
2026-09-24 12:57:53 +02:00
Admin 2d0867e68a Add tests for MassTransit activities, routing slips, sagas, fault handling and playlist visibility
Infrastructure exposes its internals to the test project so the activities and slip builders can be
exercised directly, and the fault consumer and state machines run on the MassTransit test harness.
2026-09-24 12:53:33 +02:00
Admin bc6ca3651f Share the entity model between Database and the test database via ModelConfiguration 2026-09-24 12:41:05 +02:00
Admin c4cf5af7f1 Make the Worker validate its service container and align Worker and Gateway hosts
The Worker now registers the Application layer, observability and stream tickets, validates the
container on build and ships a complete appsettings. The Gateway drops underscore fields and uses a
placeholder bucket in its default YARP transform.
2026-09-24 12:40:18 +02:00
Admin fcf3093ad8 Unify API route parameters, return IResult everywhere, merge picture upload DTOs and centralize validation limits
Guid and long route constraints, id/trackId parameter names, Update*Request without the New prefix,
sentence-case operation summaries, shared security scheme id and a single Limits class.
2026-09-24 12:36:48 +02:00
Admin 405df082cc Deduplicate MassTransit routing slips, activities and consumers 2026-09-24 12:25:55 +02:00
Admin 0cba32f776 Simplify infrastructure services and move all recurring jobs to Hangfire 2026-09-24 12:18:57 +02:00
Admin 0fa033faff Separate responsibilities: start-listening command, API-side JSON converters, bulk track endpoints, mix kinds 2026-09-24 12:14:53 +02:00
Admin 75d0c0817e Deduplicate picture flows: shared upload issuer, cover query and picture source change 2026-09-24 12:04:54 +02:00
Admin 4b708aa987 backend: add endpoint to add a whole album to a playlist 2026-09-24 12:04:28 +02:00
Admin 4b147d9ee3 Add shared pagination, projections and ownership helpers; simplify query and command handlers 2026-09-24 11:59:34 +02:00
Admin 5a0f82b77b Clean up domain entities: shared picture value object, lifecycle and ownership interfaces, explicit tables 2026-09-24 11:43:50 +02:00
Admin 4d943e068e Unify picture configuration and options registration 2026-09-24 05:23:40 +02:00
Admin b011ccdd5b backend: expose track count and duration on playlist responses 2026-09-24 05:20:20 +02:00
Admin 5e819d7676 Remove dead code: unused storage/transcoder members, Upload table, retry columns, redundant packages 2026-09-24 05:19:59 +02:00
Admin 0e3576922f Fix query and API bugs: 403 for non-owners, page bounds, lifecycle filters, cover fallback, race-safe inserts, async album delete 2026-09-24 05:14:05 +02:00
Admin ab388e6ad6 Fix processing pipeline: report album failures, fault handling on create slips, config key names, audio duration 2026-09-24 05:02:04 +02:00
Admin c8e9c7790e Close data leaks: remove anonymous user creation, hide private playlists, validate uploads and clamp gateway ranges 2026-09-24 05:00:21 +02:00
Admin dda8c30d45 backend: expose owner user id on playlist responses 2026-09-24 04:59:50 +02:00
Admin c8fe28b07b Add editorconfig and analyzers, format backend code 2026-09-24 04:54:17 +02:00
Admin 302dd1e0f8 Merge master into web-player-general-changes
CI/CD / BackEnd (push) Canceled after 0s
CI/CD / WebPlayer (push) Canceled after 0s
CI/CD / BackEnd (pull_request) Successful in 1m23s
CI/CD / WebPlayer (pull_request) Successful in 40s
CI/CD / Deploy (pull_request) Skipped
CI/CD / Deploy (push) Canceled after 0s
2026-09-24 00:32:03 +02:00
Admin cb046bba9e Let users browse followers and following lists
Following lists are public; followers are visible to the user and to mutual followers.
Adds GET /users/{id}/followers and /following, exposes isFollowing and canViewFollowers
on the profile, and returns isFollowedByViewer from user search so the web player no
longer calls /is-following per user.
2026-09-23 22:55:14 +02:00
Admin cc7afe4326 Add explicit flag to tracks and mark it on upload 2026-09-23 22:41:57 +02:00
Admin b61ff1ebec Make Discover and upload genres dynamic
CI/CD / BackEnd (push) Successful in 1m22s
CI/CD / WebPlayer (push) Successful in 38s
CI/CD / Deploy (push) Skipped
CI/CD / BackEnd (pull_request) Successful in 1m21s
CI/CD / WebPlayer (pull_request) Successful in 40s
CI/CD / Deploy (pull_request) Skipped
Discover used a hardcoded list of genre tiles that searched track titles,
and the upload form kept its own copy of the genre list and compatibility
rules. Both now come from the backend.

Backend:
- GET /genres returns genres with at least one track and their counts.
- GET /genres/available returns every assignable genre with the genres
  it cannot be combined with, so the rules live only in
  GenreCompatibility.
- GET /tracks accepts ?genre= (case-insensitive, 400 on unknown values).

web-player:
- Discover tiles are built from /genres; each opens /explore?genre=X, a
  song list filtered by that tag. Unknown genres fall back to a label
  derived from their name.
- The upload form loads /genres/available, disables incompatible genres
  as you pick, and the server validates before reserving upload URLs.
- lib/data/trackGenres.ts is removed; its helpers merge into
  lib/data/genres.ts.
- Regenerate the typed API client.
2026-09-23 20:05:30 +02:00
Admin 8870c65c6f Move ListeningRules to its own file and split listening tests by subject
CI/CD / BackEnd (push) Successful in 1m16s
CI/CD / BackEnd (pull_request) Canceled after 0s
CI/CD / WebPlayer (pull_request) Canceled after 0s
CI/CD / Deploy (pull_request) Canceled after 0s
CI/CD / WebPlayer (push) Successful in 40s
CI/CD / Deploy (push) Skipped
The counted-listen tests lived in one catch-all UncountedListensTests
file. Each now sits next to the handler it covers, and the cleanup
handler gets its own test file.
2026-09-23 20:02:50 +02:00
Admin 5df5e635f3 Count real listening time instead of full track duration
"Listening time this week" summed the full duration of every track whose
stream ticket was issued, so pressing play and skipping counted the whole
song. Playback is now measured on the client and reported to the API.

Backend:
- ListeningHistory gains PlayedSeconds, LastProgressAt and IsCounted
  (migration TrackPlayedSeconds marks existing rows as counted).
- /tracks/{id}/stream returns a listenId; new
  PUT /tracks/listens/{listenId}/progress stores the accumulated seconds,
  capped by track duration and elapsed wall-clock time, monotonic and
  owner-only.
- A listen counts once it reaches min(30s, 50% of the track). Weekly
  stats, streak, recent history/albums, mixes and listensCount only use
  counted listens; seconds sum PlayedSeconds.
- ListeningHistoryCleanupJob (daily) deletes uncounted listens older
  than 8 days.

web-player:
- ListenTracker accumulates played time (seeks are ignored) and flushes
  on pause, track change, ended, every 30s, and on pagehide.
- Proxy route /api/listens/[id]/progress; repeat starts a new listen per
  loop.
2026-09-23 20:00:45 +02:00
Admin 505ae05c53 Refactor AuditableEntityInterceptor to use property access for UpdatedAt; update Database configuration to add interceptor and adjust tests for consistency
CI/CD / BackEnd (push) Successful in 1m16s
CI/CD / WebPlayer (push) Successful in 39s
CI/CD / Deploy (push) Skipped
CI/CD / BackEnd (pull_request) Successful in 1m17s
CI/CD / WebPlayer (pull_request) Successful in 39s
CI/CD / Deploy (pull_request) Skipped
2026-09-23 19:04:21 +02:00
Admin dd1cb8a5d1 Clean up backend and web-player leftovers
Remove dead scaffold/config cruft and stale references left over from
recent refactors: dotnet's WebApi.http template file, the AppSettings
PascalCase/Dockerfile workaround (renamed to appsettings.json to match
convention), empty directories left behind by the auth-route and
folder-structure moves, a stale ESLint ignore, and the now-fully-applied
frontend refactor plan doc.
2026-09-22 16:08:44 +02:00
Admin 2662abe460 Remove comments from backend and web-player source
Strip //, /* */ and XML doc comments from all backend .cs files, and
JS/TS/CSS/HTML comments from web-player source (.ts, .svelte, .css),
per the project's no-comments convention.
2026-09-21 17:12:18 +02:00
Admin a4ca1f32d3 Remove no-op playlist picture migration; cover picture-add transition in tests
The Sept migration MakePlayListPictureColumnsOptional altered the
PlayLists picture columns to nullable:true when they were already
nullable:true (set back in MakePlayListPicturesNullable, two months
earlier) — a dead migration left over from making the Pictures
navigation itself optional, which produces no actual schema change.
Verified with `dotnet ef migrations has-pending-model-changes` and a
full migration run against a fresh Postgres container that removing
it introduces no drift.

Also add a test for updating a playlist that has no picture yet,
which was the one Pictures-related state transition without coverage.
2026-09-20 22:40:40 +02:00
Admin ea9bf07126 Clean up Application layer commands/queries readability and correctness
Add missing AsNoTracking() on read-only queries, drop redundant
Update() calls on already-tracked entities, and fix inconsistent
formatting (stray spaces in generics, ternaries, and lambdas) across
the Albums/Tracks/PlayLists/Users command and query handlers.
2026-09-20 22:23:57 +02:00
Admin a963e2c9af Update backend NuGet packages to latest compatible versions
Bump MassTransit family to 8.5.10 (latest free/open-source patch on
the 8.x line; v9 requires a paid commercial license, so it's out of
scope). Align OpenTelemetry.Instrumentation.EntityFrameworkCore and
.Process prerelease versions with the rest of the OpenTelemetry 1.19.0
set. Microsoft.OpenApi and SixLabors.ImageSharp are left as-is: OpenApi
is already pinned to the latest version compatible with
Microsoft.AspNetCore.OpenApi's [2.12.0, 3.0.0) constraint, and
ImageSharp 3.x/4.x carry a commercial licensing model.
2026-09-20 22:09:48 +02:00
Admin 4251d292e1 Changes on packages 2026-09-20 16:23:49 +02:00
Admin 3f5e01f910 Update packages 2026-09-20 16:00:57 +02:00
Admin c14db5a711 Checkpoint web-player design-system refactor and backend track genre tagging
Advances the ongoing token/componentization cleanup (anchored player dock,
border-based panels instead of floating shadows, corrected light-mode
accent/gradient tokens) alongside in-progress backend support for track
genre tags.
2026-09-17 17:43:37 +02:00
Admin 31032bd8e8 Remove YouTube integration from backend and deployment config
Drops the YouTube-backed second catalog source entirely: the
Local/External split on Track/Album collapses into single concrete
entities, Artist/TrackArtist/ExternalTrack/ExternalAlbum and the
YouTube service/download pipeline (yt-dlp, MassTransit consumer,
routing slip) are deleted, and mixes now source discovery only from
local listening history. Includes the RemoveYouTubeIntegration EF
Core migration and matching Worker/deploy/compose cleanup (no more
yt-dlp/python/deno in the Worker image, no thumbnail-cache/YtDlp
config sections).
2026-09-15 21:17:03 +02:00
Admin dc1ba89a6d Add likes, follows and playlist visibility; redesign web-player UI
Backend:
- New Likes feature (toggle/get liked tracks) and endpoints
- User follow/unfollow, listening stats, public user profile
- Playlist visibility (public/private) support
- Various auth and DTO/response adjustments to support the above

Frontend (web-player):
- New design system pass: theme tokens/mode (light/dark), glass menu,
  tabs bar, player dock/extras/queue components, mix tiles, artist link
- New routes: Liked, public user profile (/u/[id]), likes API proxy
- Search refactor: shared SearchBox component used by TopBar and
  MobileHeader (search now reachable on mobile), live results as you
  type instead of requiring Enter, dropped the "Buscando…" quick-result
  preview
- Removed now-unused components (MobileNav, CoverBadge, MixBentoTile,
  PlayPauseOverlay, SuggestionsTable, userDirectory)
- Design handoff reference docs added under web-player/design_handoff_musify_player
  and web-player/docs/design-system-refactor-plan.md
2026-09-14 23:42:45 +02:00