07e1daf2ce76c5062845cb23d4a7be5038ee1b52
Two read-only endpoints: the album search and the album detail with its tracklist. Both go through the same single-flight cache as the song search, and the detail one especially benefits since it costs two upstream calls, the browse id lookup and the album itself, for metadata that never changes. Paginator handling is now shared between the song and album searches.
Musify
Music streaming platform: upload your own tracks (or import them from YouTube),
process them asynchronously (audio transcoded to .m4a, thumbnails generated)
and stream them without the bytes ever going through the API.
backend/ .NET 10 — Domain / Application / Infrastructure / Api / Worker / StreamingGateway
web-player/ SvelteKit 2 + Svelte 5 + Tailwind 4 web client
deploy/ Docker Compose stacks and the scripts that bootstrap them
docs/ What each piece does and why (in Spanish)
Run it
Development (Windows, Docker Desktop):
./deploy/up.ps1 # infrastructure; the apps run from the IDE
./deploy/up.ps1 -Apps # everything in Docker
Production, on a server with a domain:
./deploy/up.sh # fill in deploy/.env.prod and the TLS certs when it asks
Both are idempotent and print what they did. See deploy/README.md for the details, the port map and the production prerequisites.
Components
| Service | Port (dev) | Role |
|---|---|---|
Musify.Api |
5111 | REST API, issues presigned upload URLs and stream tickets |
Musify.StreamingGateway |
8081 | YARP proxy that validates the stream ticket and serves the audio |
Musify.Worker |
— | MassTransit consumers: transcoding, thumbnails, YouTube downloads |
web-player |
5173 / 3000 | Web client (SvelteKit, server-side OIDC session) |
| Zitadel | 8080 | Identity (OIDC/OAuth2) |
| PostgreSQL / RabbitMQ / SeaweedFS / Jaeger | 59000 / 5672 / 8333 / 16686 | Metadata, messaging, object storage, traces |
More in docs/: architecture, authentication, storage, streaming, media processing, development.
Languages
C#
73.1%
Svelte
12.1%
TypeScript
9%
Kotlin
4.1%
CSS
1.1%
Other
0.6%