Commit Graph
100 Commits
Author SHA1 Message Date
Admin e9e0b9ae9b docs: add project README and frontend pages notes 2026-07-14 04:55:44 +02:00
Admin a826c39003 refactor(frontend): tidy Navbar, Footer and document shell
Align Navbar and Footer with the new design tokens and enable stable scrollbar gutter on the document.
2026-07-14 04:55:44 +02:00
Admin 4f9ae51971 chore(frontend): add font/icon deps and dev config
Add @fontsource-variable (manrope/sora/inter), @lucide/svelte and @types/node, mark @lucide/svelte as noExternal for SSR, and add the dev-server launch config.
2026-07-14 04:55:39 +02:00
Admin 2eaca66ec2 feat(frontend): rework home page with recent, latest and playlists
Add SSR data loading for the home page and rebuild its layout (greeting hero, recently played, new releases, user playlists).
2026-07-14 04:55:12 +02:00
Admin f155ccc912 feat(frontend): add (app) route group and rework auth routing
Move authenticated pages under an (app) group with a Sidebar shell, add /auth/login and page-based /login, drop the old explore page and login +server endpoint, and add the server upload helper.
2026-07-14 04:55:04 +02:00
Admin 6cc41d1d6f feat(frontend): rework audio player and shared UI components
Expand the player store, split player controls (transport, seek, volume, track info), add Cover/PlaylistArt/NowPlaying UI primitives and a cover image proxy route.
2026-07-14 04:54:51 +02:00
Admin 8c87d84f80 feat(frontend): add theme tokens and dynamic accent palette
Introduce theme.css design tokens, color/palette helpers, and global layout styles (scrollbars, animations, home gradient).
2026-07-14 04:54:45 +02:00
Admin 0b72363c33 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 a40f3da247 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 18d3aea853 feat(frontend): play tracks from the explore page 2026-07-06 02:40:44 +02:00
Admin 9b34f2db84 feat(frontend): music player component with separated controls and stream proxy 2026-07-06 02:40:44 +02:00
Admin 812913156b refactor(application): drop redundant default values on query records 2026-07-06 02:23:35 +02:00
Admin 927f965023 fix(playlists): reject empty/whitespace name and description on update 2026-07-06 02:20:47 +02:00
Admin 7623b4e80e refactor(search): treat empty search strings as no filter (string.IsNullOrEmpty) 2026-07-06 02:12:58 +02:00
Admin fef788462d feat(frontend): add /explore page with track listing and name search 2026-07-06 02:05:47 +02:00
Admin b9cd3533dc chore(frontend): regenerate api types with track name search 2026-07-06 02:04:04 +02:00
Admin ac1c515dec feat(tracks): support search by name in GetTracks 2026-07-06 02:04:01 +02:00
Admin 5d2c9d3986 chore(frontend): generate backend API types from live OpenAPI spec 2026-07-06 01:54:28 +02:00
Admin 93fe2fb942 feat(frontend): add typed backend API client (openapi-fetch) with codegen script 2026-07-06 01:52:25 +02:00
Admin f58f6a0aa5 refactor(frontend): require refresh/id token in Session, validate at callback boundary 2026-07-05 23:57:19 +02:00
Admin ac5fc49800 refactor(frontend): restrict insecure HTTP issuer to dev / explicit opt-in 2026-07-05 23:56:35 +02:00
Admin 6a49b17e38 refactor(frontend): make SessionUser fields non-null and normalize claims at boundary 2026-07-05 23:45:18 +02:00
Admin ea36816777 refactor(frontend): centralize configurable auth/session values in config.ts 2026-07-05 23:43:50 +02:00
Admin 9613cd928d feat(frontend): encrypt session cookie (JWE) and auto-refresh access token 2026-07-05 23:41:49 +02:00
Admin 33ead1daab chore(frontend): remove scaffold comments and add conventions doc 2026-07-05 23:41:42 +02:00
AdminandClaude Opus 4.8 66cb970dd2 fix(frontend): full-page nav for auth links; land on home after login
- Add data-sveltekit-reload to the /login links so the browser performs a full
  navigation (the client router intercepted them and aborted on the external
  Zitadel redirect)
- Default post-login returnTo to / (home) since /explore is not built yet
- 'Empezar gratis' now starts the register flow (/login?mode=register)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 23:16:25 +02:00
AdminandClaude Opus 4.8 f8d4f83152 fix(deploy): use Zitadel built-in login v1 (disable required Login UI v2)
The 'latest' Zitadel image requires the Login UI v2, which runs as a separate
'login' container this stack doesn't deploy, so OIDC redirected to /ui/v2/login
and returned {code:5, Not Found}. provision.ps1 now disables the loginV2
requirement via the feature API so OIDC uses the built-in /ui/login. Also
applied to the running instance.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 23:08:27 +02:00
AdminandClaude Opus 4.8 454bffe4ba feat(frontend): make Zitadel client secret optional (support PKCE apps)
Configure openid-client with None auth (public client + PKCE) when no secret is
provided, so both PKCE and confidential (Code) Zitadel web apps work.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 23:01:44 +02:00
AdminandClaude Opus 4.8 0163da096e feat(frontend): server-side Zitadel OIDC auth (part 2)
Add Authorization Code + PKCE login/logout against Zitadel, handled entirely
server-side with an httpOnly signed session cookie:
- $lib/server/auth: openid-client discovery (config cached), jose-signed
  session encode/decode, cookie/name constants
- routes: /login (builds the authorize URL with PKCE/state/nonce, ?mode=register
  -> prompt=create), /auth/callback (code exchange + session cookie),
  /logout (clears session + Zitadel end_session)
- hooks.server populates locals.user/accessToken from the session
- +layout.server exposes the user; Navbar shows the signed-in user + Salir,
  or Iniciar sesión / Registrarse
- switch to adapter-node; env-driven config (.env gitignored, .env.example
  committed) with issuer http://host.docker.internal:8080

Verified: svelte-check + build clean; dev smoke test shows the landing in the
logged-out state and /login issuing a 302 to Zitadel's authorize endpoint with
PKCE/state/nonce (discovery reachable). Real client id/secret still needed to
complete the token exchange.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 22:58:47 +02:00
AdminandClaude Opus 4.8 6bb31ad7c5 feat(frontend): scaffold SvelteKit + Tailwind with landing (part 1)
New SvelteKit app in frontend/ (minimal template, TypeScript, TailwindCSS v4).
Adds the app shell (dark music theme navbar + footer) and a landing page with
hero and feature cards. CTAs point to /login and /explore (built in later parts).

Verified: production build succeeds and the page renders with Tailwind styles
applied (checked via preview).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 22:47:29 +02:00
AdminandClaude Opus 4.8 573539ea1b cleanup(worker): drop empty Worker BackgroundService; fix gateway ticket guard
- Remove the no-op Worker BackgroundService and its registration; the process
  is kept alive and does its work through the MassTransit bus and the upload
  intent jobs (their own hosted services)
- Fix the gateway middleware guard to reject on string.IsNullOrEmpty(prefix)
  instead of 'is null', which no longer matched TicketValidator returning
  string.Empty for invalid tickets (invalid tickets skipped the 401 and an
  empty object key could slip through)

Build: 0 warnings, 0 errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 22:13:20 +02:00
Admin e15e587267 Formatting 2026-07-05 22:07:43 +02:00
Admin dece2c77e8 Empty string 2026-07-05 22:06:50 +02:00
AdminandClaude Opus 4.8 5aeca4deb1 refactor(gateway): simplify prefix extraction in TicketValidator
Read the prefix claim via ClaimsIdentity.FindFirst instead of a three-part
ternary over the claims dictionary, and drop the XML summary.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 21:59:55 +02:00
AdminandClaude Opus 4.8 45ce66a6ee harden(gateway): prefix-boundary + path-traversal checks; simplify ticket validation
Tighten the stream-ticket authorization in the gateway middleware:
- Enforce a path-segment boundary on the prefix check instead of a bare
  StartsWith, so a ticket for 'users/12' no longer grants 'users/1234/...'
  (exact-match still allowed for single-object grants)
- Reject object keys containing '..'/'.' segments before proxying, closing a
  path-traversal bypass that SeaweedFS would otherwise resolve outside the
  authorized prefix

Also simplify TicketValidator.ValidateTicketAsync from ErrorOr<string> to
string? (null = invalid) since it has a single failure mode; drop the now
unused ErrorOr package reference from the gateway.

Verified: build clean; the authorization predicate passes a table of cases
covering both the escalation and traversal vulnerabilities.

Build: 0 warnings, 0 errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 21:50:43 +02:00
AdminandClaude Opus 4.8 a40de35a57 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.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 21:04:15 +02:00
AdminandClaude Opus 4.8 1d40abcab7 feat(deploy): consolidated dev stack with auto-provisioned Zitadel
Single docker-compose stack for local development (Postgres, Zitadel,
RabbitMQ, SeaweedFS + bucket init, Jaeger) plus an optional overlay to run
the .NET apps in Docker. up.ps1 orchestrates the full bootstrap: stack up,
stream-ticket keys, EF Core migrations and Zitadel provisioning.

- Zitadel is provisioned automatically (service-account PAT -> project +
  OIDC app with JWT access token); the generated ClientId is wired into
  Musify.Api user-secrets and .env. No manual console steps.
- ZITADEL_EXTERNAL_DOMAIN=host.docker.internal so token validation works
  both with local apps and full-docker.
- App Dockerfiles copy AppSettings*.json to lowercase so config loads on
  case-sensitive Linux; Worker image ships ffmpeg.
- Scripts split by responsibility (common/stream-keys/migrate/provision);
  apps overlay de-duped via YAML anchors.
- Remove the superseded standalone seaweedfs compose; point docs/development
  at the unified stack.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 20:32:40 +02:00
Admin d6c269d80f Formatting 2026-07-05 16:04:53 +02:00
AdminandClaude Opus 4.8 431b56a072 refactor(infra): register auditable interceptor via DI
Register AuditableEntityInterceptor as a singleton and attach it through the
AddDbContext options callback instead of newing it up inside
Database.OnConfiguring. The interceptor is stateless, so a single shared
instance is reused across contexts and its wiring lives in the DI layer.
The design-time factory keeps working (interceptor is runtime-only, irrelevant
for migrations).

Verified: build + ef migrations list (design-time context) OK; the Worker host
builds and validates the full DI graph (reaches endpoint configuration) with no
captive-dependency or interceptor error.

Build: 0 warnings, 0 errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 15:14:03 +02:00
AdminandClaude Opus 4.8 c2258569a0 refactor(infra): S3 client singleton, ffmpeg pipe ordering, tidy streams/jobs
- Register IAmazonS3 as a singleton instead of scoped: the AWS SDK client is
  thread-safe and manages its own connection pool, so one instance per DI scope
  (per request / per job iteration) was wasteful and risked socket exhaustion
- AudioTranscoderService: start reading stdout/stderr before writing stdin to
  remove the latent pipe-buffer deadlock shape
- Dispose the resized-picture MemoryStream in ResizePictureActivity
- Background jobs use PeriodicTimer instead of while + Task.Delay

Verified: Worker boots against RabbitMQ + Postgres in Docker with no captive-
dependency error (dev scope validation) and both jobs start.

Build: 0 warnings, 0 errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 15:07:49 +02:00
AdminandClaude Opus 4.8 a5305b8ed8 feat(infra): playlist processing saga + generalize fault handling (phase 3)
Adds the PlayList picture-processing lifecycle saga (correlated by PlayListId)
mirroring the track one, and generalizes the failure plumbing:
- Rename the track fault translator to ProcessingSlipFaultConsumer and use a
  generic Workflow.SubjectId variable + ProcessKind; it now emits typed
  Track{Picture,Audio}/PlayListPicture ProcessingFailed events for all slips
- PlayListProcessingStateMachine (+ EF-persisted PlayListProcessingState,
  migration): starts on CreatePlayListResourcesEvent, finalizes on
  PlayListPictureProcessed, and on failure marks the playlist Failed and
  removes the orphaned final picture (PlayListProcessingFailedConsumer +
  MarkPlayListAsFailedActivity)
- UpdatePlayListPictureActivity publishes PlayListPictureProcessed on success
- Picture slip carries SubjectId + PlayListPicture kind + fault subscription

Verified end-to-end in Docker (RabbitMQ + migrated Postgres): both saga
endpoints, the fault translator and cleanup consumers configure, and an
addressing cross-check confirms all 21 activity execute queues the builders
address exist (caught + fixed a kebab mismatch on mark-play-list-as-failed).

Build: 0 warnings, 0 errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 14:55:40 +02:00
AdminandClaude Opus 4.8 8664bfb800 feat(infra): track saga failure handling + cleanup (phase 2)
On definitive failure of the picture or audio slip, the saga now reaches a
Failed state and recovers end-to-end:
- Picture/audio track slips carry TrackId + ProcessKind variables and a
  subscription to a fault translator (TrackProcessingSlipFaultConsumer) that
  turns RoutingSlipFaulted into a typed Track{Picture,Audio}ProcessingFailed
- The saga stores the final object keys from the start event and, on failure,
  transitions to Failed and publishes TrackProcessingFailed
- TrackProcessingFailedConsumer runs a cleanup slip that removes the orphaned
  final picture/audio copies and marks the track LifeCycleStatus=Failed
  (MarkTrackAsFailedActivity) — the track stays as a visible, recoverable record
- Migration for the new saga columns

Verified: Worker boots against RabbitMQ + Postgres in Docker; the new
endpoints (fault translator, failed consumer, mark-track-as-failed) configure
and the bus starts clean.

Build: 0 warnings, 0 errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 14:49:33 +02:00
AdminandClaude Opus 4.8 986941166c feat(infra): add Track processing saga (state machine, phase 1)
Introduce a MassTransit saga state machine that correlates by TrackId and
tracks the two parallel processing slips (picture + audio):
- TrackProcessingStateMachine + EF-persisted TrackProcessingState
  (pessimistic concurrency, EntityFrameworkRepository), migration added
- Starts on CreateTrackResourcesEvent; UpdateTrack{Picture,Audio}Activity now
  publish TrackPictureProcessed / TrackAudioProcessed on success; when both
  arrive the saga finalizes (Ready). Failure transitions to a Failed state
  (cleanup wired in the next phase)
- Add LifeCycleStatus.Failed and the four outcome events

Verified: booted the Worker against RabbitMQ + migrated Postgres in Docker;
the saga endpoint 'track-processing-state' is configured and the bus starts
clean.

Build: 0 warnings, 0 errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 14:41:19 +02:00
AdminandClaude Opus 4.8 3545d71016 refactor(infra): auto-configure MassTransit endpoints via ConfigureEndpoints
Replace ~240 lines of hand-written per-endpoint wiring with MassTransit's
ConfigureEndpoints + KebabCaseEndpointNameFormatter, and apply retry + EF
outbox globally through AddConfigureEndpointsCallback. Adding a consumer or
activity is now a single AddConsumer/AddActivity line.

- Normalize the 4 mismatched activity endpoint names to kebab-case so the
  routing-slip addressing keeps resolving (update-play-list-picture,
  delete/mark/publish play-list variants); cleanup consumer queue is now
  routing-slip-clean-up
- Drop the now-unused QueueName consts from event consumers and trim
  EndpointHelper / delete the manual endpoint-config partial

Verified end-to-end: booted the Worker against RabbitMQ in Docker and
confirmed all 38 endpoints are configured with the exact names the builders
address (19 execute queues + compensations + consumers + routing-slip-clean-up).

Build: 0 warnings, 0 errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 14:22:26 +02:00
AdminandClaude Opus 4.8 d08d82a483 fix(infra): repair TransferFiles compensation + tidy MassTransit consistency
Fix (recoverability bug):
- TransferFilesToBucketActivity returned Completed() with no log, so its
  compensation could never delete the transferred files (orphaned objects on
  fault). IStorageService.TransferFilesAsync now returns the real uploaded
  keys; the activity logs them so Compensate can remove them. Also drops the
  Path.Combine key recomputation (produced backslash keys on Windows).

Consistency / DRY:
- Normalize all courier activities to internal + folder-based namespaces
  (several were public and in the flat .Activities namespace)
- Extract the duplicated exponential retry into UseStandardRetry
- Unify endpoint-name logic into a single EndpointHelper (remove the parallel
  MassTransitEndpointNames helper)

Build: 0 warnings, 0 errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 04:58:27 +02:00
AdminandClaude Opus 4.8 423e06baf9 refactor(application): fold Pagination into Shared, rename assembly marker
- Move PaginatedResponse from the single-file Pagination/ folder into Shared/
  (namespace Musify.Application.Pagination -> Musify.Application.Shared)
- Rename MusifyApplication.cs -> AssemblyInfo.cs (it only holds the
  [assembly: MediatorOptions] attribute)

Build: 0 warnings, 0 errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 04:38:12 +02:00
AdminandClaude Opus 4.8 38f7094fb0 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.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 04:36:46 +02:00
AdminandClaude Opus 4.8 e802c8565d 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.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 04:12:59 +02:00
AdminandClaude Opus 4.8 6e469dbb4a 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.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 04:05:43 +02:00
AdminandClaude Opus 4.8 a3bf796f17 chore(backend): install AI agent skills for the .NET stack
Run autoskills in backend/: detects .NET/C#/ASP.NET Core/Minimal API and
installs 13 skills for universal (.agents) and claude-code (.claude) agents,
with backend/skills-lock.json. Adds ASP.NET Core, Minimal API + OpenAPI,
file-upload and containerization skills on top of the prior C#/.NET set.
Removes the stale root skills from the old layout.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 03:48:31 +02:00
AdminandClaude Opus 4.8 8f34ed4874 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.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 03:43:52 +02:00
AdminandClaude Opus 4.8 d9c8c17b21 refactor: central package management, shared build props, security fix
- Add Directory.Packages.props (CPM): all package versions centralized,
  remove Version attributes from every PackageReference
- Add Directory.Build.props: shared TargetFramework/Nullable/ImplicitUsings
- Drop redundant per-project RootNamespace/AssemblyName (default = project name)
  and stale NuGet metadata (PackageId/Version/Authors/RepositoryUrl)
- Bump Microsoft.OpenApi to 2.9.0 (CVE-2026-49451, was transitive 2.0.0);
  add explicit reference in Musify.Api which uses it directly
- Add repo-scoped nuget.config pinning nuget.org for reproducible restore

Build: 0 warnings, 0 errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 03:40:05 +02:00
AdminandClaude Opus 4.8 f6d668d201 refactor: standardize project names to Musify.* and flatten layout
- Flatten nested per-repo folders into flat Musify.* projects at root
- Rename assemblies/csproj: Domain->Musify.Domain, Application->Musify.Application,
  Infrastructure->Musify.Infrastructure, WebApi->Musify.Api, Worker->Musify.Worker,
  StreamingGateway->Musify.StreamingGateway
- Rename WebApi.* namespaces to Musify.Api.*
- Update all ProjectReference paths and the solution file
- Consolidate stray per-repo dotfiles; add root .gitattributes
- Move flutter client out to _archive

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 03:32:48 +02:00
AdminandClaude Opus 4.8 8ab4d27287 chore: move flutter client out of monorepo into _archive
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 03:26:36 +02:00
AdminandClaude Opus 4.8 4b80c7dbb0 chore: bring flutter client, docs, deploy and tools into monorepo
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 03:22:24 +02:00
AdminandClaude Opus 4.8 8c0519d125 feat: add unified Musify solution spanning all projects
Groups Domain/Application/Infrastructure under Core and
WebApi/Worker/StreamingGateway under Hosts. Removes the per-repo
.slnx files now superseded by the single solution.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 03:21:32 +02:00
Admin 27922f2d14 chore: import Musify.StreamingGateway into monorepo (preserving history)
git-subtree-dir: Musify.StreamingGateway
git-subtree-mainline: 28426571e6
git-subtree-split: a8ff05892d
2026-07-05 03:20:50 +02:00
Admin 28426571e6 chore: import Musify.Worker into monorepo (preserving history)
git-subtree-dir: Musify.Worker
git-subtree-mainline: c3cdd3bc0f
git-subtree-split: 868860fff9
2026-07-05 03:20:48 +02:00
Admin c3cdd3bc0f chore: import Musify.WebApi into monorepo (preserving history)
git-subtree-dir: Musify.WebApi
git-subtree-mainline: 9d433868cc
git-subtree-split: ca8750c3b4
2026-07-05 03:20:47 +02:00
Admin 9d433868cc chore: import MusifyBackend into monorepo (preserving history)
git-subtree-dir: MusifyBackend
git-subtree-mainline: 6829e769ed
git-subtree-split: ed7b00c2cc
2026-07-05 03:20:43 +02:00
AdminandClaude Opus 4.8 6829e769ed chore: initialize Musify monorepo
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 03:20:11 +02:00
AdminandClaude Opus 4.8 ca8750c3b4 chore: preserve local dev config before monorepo import
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 03:19:56 +02:00
Admin ed7b00c2cc Adjust 2026-06-03 00:32:37 +02:00
Admin e3b7a0353e Set Content-Type on transferred objects so .m4a is served as audio/mp4 2026-06-02 19:26:45 +02:00
Admin a8ff05892d Serve audio .m4a by range; remove DASH manifest rewriting 2026-06-02 19:05:19 +02:00
Admin 47c3a431c2 Point streaming config to single .m4a; drop DASH ffmpeg settings 2026-06-02 19:05:18 +02:00
Admin b737d59cbe Migrate audio transcoding from DASH to a single AAC (.m4a) file 2026-06-02 19:05:11 +02:00
Admin 2978b69654 Fix bugs 2026-06-01 22:48:42 +02:00
Admin 69eeefd58f Simplify user sync: rely on EF change tracking instead of manual hasChanges flag 2026-06-01 22:11:48 +02:00
Admin 30f57ff50e Auto-set CreatedAt/UpdatedAt via EF interceptor; standardize timestamp names across entities 2026-06-01 22:04:52 +02:00
Admin 55c73cbb3d Changes 2026-06-01 20:50:46 +02:00
Admin e59a5fa8ef Remove checks 2026-06-01 20:41:34 +02:00
Admin bd010e0330 Link created track to its owner via UserHasTrack 2026-06-01 19:07:33 +02:00
Admin 45999af9f8 Add endpoint to list paginated tracks of a playlist 2026-06-01 18:54:26 +02:00
Admin ca4d6c5ed2 Add paginated query for tracks of a playlist; make PlayListHasTrack.Track navigation non-nullable 2026-06-01 18:54:25 +02:00
Admin 58fda0ba9a Extract storage key building into a shared StorageKey helper 2026-06-01 16:45:37 +02:00
Admin 032906de6b Sync user profile (incl. picture) from token claims on validation 2026-06-01 01:47:47 +02:00
Admin 5c5fab86a5 Add user profile picture URL synced from the identity provider on login 2026-06-01 01:47:47 +02:00
Admin ba093e7fd5 Add playlist endpoints to add and remove tracks 2026-06-01 01:20:18 +02:00
Admin 842dd13efa Add and remove tracks from playlists (commands + handlers with ownership checks) 2026-06-01 01:20:17 +02:00
Admin 55549818af Cleanup 2026-06-01 00:24:41 +02:00
Admin 868860fff9 Initial commit: Musify.Worker background worker (MassTransit consumers for picture/audio processing) 2026-06-01 00:19:45 +02:00
Admin 3fea58cd72 Remove unused usings 2026-05-31 19:28:08 +02:00
Admin 03d9fa054f Allow any CORS origin in Development 2026-05-31 19:25:15 +02:00
Admin c1fc0ed1a1 Return 400 for validation errors without identifier and enable permissive CORS in Development 2026-05-31 19:25:15 +02:00
Admin 253a67aabf Fix audio DASH workflow: dispose source stream before delete and store S3 folder key as AudioFolderName 2026-05-31 19:25:15 +02:00
Admin e4452843e7 Use long 2026-05-31 18:25:40 +02:00
Admin 69cc73c374 Use long 2026-05-31 18:25:39 +02:00
Admin 9772879e67 Fixes on scalar 2026-05-30 03:44:32 +02:00
Admin bd92928366 Proxy 2026-05-30 03:30:32 +02:00
Admin 46985bf062 Proxy 2026-05-30 03:29:21 +02:00
Admin 834d7a25c1 Use development 2026-05-30 02:30:18 +02:00
Admin dc1d3c2269 Remove unused using 2026-05-30 02:27:12 +02:00
Admin 67d340fcaa BugFix 2026-05-30 02:26:33 +02:00
Admin 47bff00268 Changes 2026-05-30 02:24:55 +02:00
Admin f20391391a Add project files. 2026-05-30 02:16:39 +02:00
Admin f9aaa1a1fe Add .gitattributes and .gitignore. 2026-05-30 02:16:37 +02:00
Admin b6754a0e76 Update endpoint 2026-05-29 22:42:48 +02:00
Admin 3313560e6c ?? 2026-05-29 22:37:51 +02:00
Admin 8455033e52 Use if condition 2026-05-29 22:37:32 +02:00