Files
Musify/docs/projects.md
T

4.0 KiB

Proyectos

Cada carpeta de nivel superior es una solución/repo independiente.

Musify.WebApi/WebApi (:5111)

API REST pública (Minimal APIs, .NET 10). Es la fachada fina del sistema.

  • Endpoints: UserEndpoints, TrackEndpoints, PlayListEndpoints.
  • Autenticación: JWT Bearer contra Zitadel (Authentication/), con JwtBearerEventsHandler que sincroniza el usuario en cada token validado.
  • CurrentUser: abstracción que se enlaza como parámetro de endpoint (IBindableFromHttpContext) y expone los claims básicos (Id como long?, RequiredId, nombre, etc.) sin tener que leer ClaimsPrincipal a mano.
  • Emite: presigned URLs de subida (vía IStorageService) y stream-tickets (vía IStreamTicketService, RS256).
  • OpenAPI + Scalar para documentación/prueba; OAuth2 (PKCE) configurado para login desde Scalar.
  • CORS totalmente abierto solo en Development (para el player.html y front local).
  • Traduce Ardalis.Result → HTTP en ResultHttpExtensions.

Propósito/porqué: separar la cara pública (autorización + metadatos) del procesado y del servido de bytes.

MusifyBackend (Domain + Application + Infrastructure)

El núcleo, en tres proyectos (clean architecture):

Domain

Entidades (Entities/) y value objects/enums (ValueObjects/: ProcessingStatus, LifeCycleStatus, UploadIntentStatus, …). Sin dependencias de infraestructura.

Application

Casos de uso (CQRS con Mediator):

  • Tracks/, PlayLists/, Users/ → Commands, Queries, Handlers, Responses.
  • Contracts/ → interfaces que implementa la infraestructura (IDatabase, IStorageService, IAudioTranscoderService, IPictureService, IEventBus, IStreamTicketService).
  • Configuration/ → opciones tipadas (Track, PlayList, ApplicationStorage, UploadIntent…) bindeadas y validadas al arranque.
  • Shared/ → helpers transversales (StorageKey.Combine, ImageSize).
  • Pagination/ → PaginatedResponse<T>.

Porqué: la lógica de negocio no conoce EF, S3 ni RabbitMQ; solo interfaces. Reutilizable por WebApi y Worker.

Infrastructure

Implementaciones concretas:

  • Persistence/ → Database (EF Core/Npgsql), migraciones.
  • Services/ → StorageService (AWSSDK.S3 contra SeaweedFS), AudioTranscoderService (ffmpeg → .m4a), PictureService (ImageSharp), StreamTicketService (firma RS256).
  • MassTransit/ → consumers, activities y routing slips (ver media-processing.md).
  • Jobs/ → UploadIntentExpirationJob, TemporalUploadsCleanUpJob.

Musify.StreamingGateway/StreamingGateway (:8081)

Reverse proxy (ASP.NET + YARP) que sirve el audio (.m4a) desde SeaweedFS. Valida el stream-ticket (RS256, clave pública) y, si el objeto pedido cae bajo el prefijo autorizado, reenvía al filer.

Porqué un proyecto aparte: escala con el tráfico de bytes independientemente de la API, tiene superficie mínima (solo sabe validar un JWT y proxiar) y permite que SeaweedFS quede en red privada. Ver streaming.md.

Musify.Worker/Worker

Worker Service (host de fondo) que consume los eventos de MassTransit y ejecuta el procesado pesado: transcode de audio a .m4a (ffmpeg), generación de miniaturas (ImageSharp), transferencias de ficheros en el bucket, y los jobs de expiración/limpieza de upload intents.

Porqué aparte: el trabajo CPU/IO no debe ocurrir dentro de un request HTTP; se escala y reinicia por separado. (Antes se llamaba Musify.PictureWorker; se renombró porque hace más que imágenes.)

Raíz del workspace (no versionada)

  • deploy/seaweedfs/ — docker-compose.yml + s3.conf para levantar SeaweedFS.
  • player.html — consola de pruebas (un solo archivo): login con token, CRUD de playlists, añadir/quitar canciones, listar y reproducir. Ver development.md. (Pendiente: hoy usa dash.js; con el cambio a .m4a debe reproducir el fichero directo por <audio>/range.)
  • docs/ — esta documentación.