8.2 KiB
8.2 KiB
Tech stack y arquitectura (MusifyBackend)
Este documento describe qué tecnologías usa este repo y cómo encajan (capas, workers, mensajería, storage, observabilidad). Está pensado para alguien que llega de cero o para una IA que necesita contexto.
Foto rápida
- Runtime: .NET 10 (C#)
- Estilo: Clean Architecture (capas
Domain/Application/Infrastructure) - Casos de uso: CQRS con DispatchR (similar a MediatR)
- Persistencia: Entity Framework Core + PostgreSQL (provider
Npgsql) - Workers / mensajería: MassTransit + RabbitMQ
- Orquestación de workflows: MassTransit Courier / RoutingSlip (Activities)
- Storage de objetos: SeaweedFS expuesto como S3-compatible (vía AWS SDK
IAmazonS3) - Observabilidad: OpenTelemetry (traces + metrics, export OTLP)
- Procesado multimedia:
- Imágenes: SixLabors.ImageSharp (resize, WebP)
- Audio: ffmpeg (transcode a DASH)
Estructura del repo (capas)
Domain/ (núcleo de negocio)
- Entidades puras (sin dependencias de infraestructura).
- Ejemplos:
Track,PlayList,Upload, etc. - Estados de negocio relevantes:
ProcessingStatus(procesado en curso/finalizado, etc.).LifeCycleStatus(p.ej.Active,Removing) para deletes asíncronos.
Application/ (casos de uso + contratos)
- Contiene comandos/queries/handlers por feature.
- CQRS:
Commands/yQueries/por feature (PlayLists,Tracks,Users, ...).Handlers/ejecutan la lógica de aplicación (coordinar DB + eventos), pero no implementan detalles de infraestructura.
- Contratos con infraestructura:
Application/Abstractions/Infrastructure/*IDatabase(abstracto de EF DbContext)IEventBus(publicación de eventos)IStorageService,IPictureService,IAudioTranscoderService, etc.
- Eventos de integración:
Application/Events/*- Se publican desde
Applicationy se consumen enInfrastructure.
- Se publican desde
Infrastructure/ (implementaciones + integraciones)
- Implementa las abstracciones de
Application. - Contiene:
- EF Core DbContext y migraciones
- MassTransit (consumers, activities, routing slips, outbox)
- Integración S3 (SeaweedFS) mediante AWS SDK
- Observabilidad OpenTelemetry
- Servicios de procesado (ImageSharp/ffmpeg)
CQRS con DispatchR
- Los “use cases” se modelan como:
- Commands: mutaciones (crear/actualizar/borrar).
- Queries: lecturas.
- Los handlers viven en
Application/*/Handlers/y dependen de:IDatabasepara persistencia (sin acoplarse al DbContext concreto).IEventBuspara emitir eventos cuando hay trabajo asíncrono.
Persistencia (EF Core + PostgreSQL)
- DbContext:
Infrastructure/Persistence/Database.cs- Usa
UseNpgsql(connectionString). - Incluye tablas de MassTransit Outbox/Inbox (ver sección de mensajería).
- Usa
- DI:
Infrastructure/Persistence/DatabaseDependencyInjection.cs - Config:
Infrastructure/Configuration/DatabaseConfiguration.cs(secciónDatabase)ConnectionString
Mensajería y workers (MassTransit + RabbitMQ)
Qué se usa
- Broker: RabbitMQ (
MassTransit.RabbitMQ). - MassTransit está configurado en dos modos:
- Cliente (publica eventos):
Infrastructure/MassTransit/DependencyInjection/MassTransitDependencyInjection.cs→AddMassTransitClient() - Workers (consumen y ejecutan activities):
AddMassTransitConsumers()
- Cliente (publica eventos):
Outbox / Inbox (robustez)
- Se usa EntityFramework Outbox (
AddEntityFrameworkOutbox<Database>()) con:UsePostgres()UseBusOutbox()QueryDelay = 1sDuplicateDetectionWindow = 30m
- En el DbContext se registran entidades de MassTransit:
AddInboxStateEntity()AddOutboxMessageEntity()AddOutboxStateEntity()
Idea clave:
- La outbox asegura que, tras confirmar la transacción de DB, los mensajes/eventos pendientes se publican de forma fiable.
Courier / RoutingSlip (workflows asíncronos)
Para operaciones multi-paso (p.ej. imagen/audio y deletes), se usa MassTransit Courier:
- Un “RoutingSlip” es una lista de pasos.
- Cada paso es una Activity (con args + log opcional).
- Existen dos tipos que aparecen en este repo:
ExecuteActivity(endpoint<name>_execute), típicamente acciones atómicas.Activity(con compensación/log), típico para pasos de workflow.
Dónde mirar:
- Builders:
Infrastructure/MassTransit/RoutingSlip/Builders/* - Activities:
Infrastructure/MassTransit/Activities/* - Consumers (punto de entrada del workflow):
Infrastructure/MassTransit/Consumers/* - Registro de endpoints:
Infrastructure/MassTransit/DependencyInjection/*
Ejemplos de workflows presentes:
- Procesado de imagen (resize + upload + update DB)
- Procesado de audio (transcode DASH + upload + update DB)
- Deletes asíncronos (marcar “removing”, borrar objetos, borrar filas)
Config de MassTransit
Infrastructure/Configuration/MassTransitConfiguration.cs(secciónMassTransit)AddressUsernamePassword
Storage de objetos (SeaweedFS como S3-compatible)
Qué se usa
- SDK:
Amazon.S3(IAmazonS3). - Implementación:
Infrastructure/Services/StorageService.cs(usaIAmazonS3). - DI:
Infrastructure/Services/ServicesDependencyInjection.cs→AddStorageService()
Config
Infrastructure/Configuration/InfrastructureStorageConfiguration.cs(secciónInfrastructureStorage)Address(ServiceURL)AccessKey/SecretAccessKeyForcePathStyle(útil en S3-compatibles)UseHttp
Notas prácticas (S3-compatible):
- Algunas features avanzadas de AWS S3 pueden no comportarse igual (depende de SeaweedFS). Diseñar workflows para que sean correctos con el subconjunto básico: PUT/GET/HEAD/LIST/DELETE y paths bien definidos.
Procesado multimedia
Imágenes
- Librería:
SixLabors.ImageSharp - Servicio:
Infrastructure/Services/PictureService.cs - Contrato:
Application/Abstractions/Infrastructure/IPictureService.cs - Patrón: workers descargan/transforman/suben; la app coordina por eventos.
Audio
- Herramienta:
ffmpeg(binario externo) - Config:
Infrastructure/Configuration/AudioTranscoderConfiguration.cs(secciónAudioTranscoder)- Timeout, codec/bitrate/channels/sample-rate, segmentación DASH, etc.
- Servicio:
Infrastructure/Services/AudioTranscoderService.cs - Contrato:
Application/Abstractions/Infrastructure/IAudioTranscoderService.cs
Directorio temporal (workers)
- Config:
Infrastructure/Configuration/WorkerConfiguration.cs(secciónWorkers)Routes.TemporaryFilesDirectory
Observabilidad (OpenTelemetry)
- DI:
Infrastructure/Observability/OpenTelemetryDependencyInjection.cs - Config:
Infrastructure/Configuration/OpenTelemetryConfiguration.cs(secciónOpenTelemetry)OtlpEndpoint
Qué instrumenta:
- Tracing:
MassTransit- ASP.NET Core
- HttpClient
- EF Core
- Exporter OTLP
- Métricas:
MassTransit- ASP.NET Core
- HttpClient
- Runtime + Process
- Exporter OTLP
Identidad (Keycloak)
- El repo asume integración con Keycloak (ver
AGENTS.mdy nombres comoGetUserByKeycloakQuery). - La capa
Applicationtrata el “Keycloak Id” como identificador de usuario en algunos casos de uso. - La integración concreta (tokens, validación, etc.) puede vivir fuera de estas 3 capas o en otro proyecto/host.
Glosario rápido
- Command / Query: operación de escritura / lectura.
- Handler: clase que ejecuta el caso de uso (CQRS).
- EventBus: abstracción para publicar eventos (MassTransit por debajo).
- Consumer: “listener” de mensajes en una cola.
- RoutingSlip: workflow compuesto por Activities.
- Activity: paso del workflow (puede tener log/compensación).
- Outbox: patrón para publicar eventos de forma fiable tras commit de DB.
“Dónde empiezo a leer” (ruta recomendada)
- Arquitectura general:
AGENTS.md - Casos de uso:
Application/*/Commands,Application/*/Queriesy susHandlers/ - Persistencia:
Infrastructure/Persistence/Database.cs+ migraciones - Mensajería/workflows:
Infrastructure/MassTransit/* - Integraciones:
Infrastructure/Services/*(S3, imagen, audio) - Observabilidad:
Infrastructure/Observability/OpenTelemetryDependencyInjection.cs