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.
This commit is contained in:
2026-09-24 17:30:40 +02:00
444 changed files with 14432 additions and 9275 deletions
+14 -37
View File
@@ -1,51 +1,28 @@
using Hangfire;
using Musify.Application.Configuration;
using Musify.Infrastructure.Jobs;
using Musify.Application;
using Musify.Infrastructure.MassTransit;
using Musify.Infrastructure.Observability;
using Musify.Infrastructure.Persistence;
using Musify.Infrastructure.Services;
var builder = Host.CreateApplicationBuilder();
var builder = Host.CreateApplicationBuilder(args);
builder.ConfigureContainer(new DefaultServiceProviderFactory(new ServiceProviderOptions
{
ValidateOnBuild = false,
ValidateOnBuild = true,
ValidateScopes = true
}));
var configuration = builder.Configuration;
var services = builder.Services;
services.AddValidatedOptions<ApplicationStorageConfiguration>(configuration, ApplicationStorageConfiguration.SectionName);
services.AddValidatedOptions<PlayListConfiguration>(configuration, PlayListConfiguration.SectionName);
services.AddValidatedOptions<TrackConfiguration>(configuration, TrackConfiguration.SectionName);
services.AddValidatedOptions<MixConfiguration>(configuration, MixConfiguration.SectionName);
services.AddStorageService(configuration);
services.AddAudioTranscoder(configuration);
services.AddHttpClient();
services.AddPictureService(configuration);
services.AddDatabase(configuration);
services.AddMassTransitConsumers(configuration);
services.AddUploadIntentJobs(configuration);
services.AddMediator();
services.AddDailyMixGenerationJob(configuration);
builder.Services
.AddApplication(builder.Configuration)
.AddObservability(builder.Configuration)
.AddDatabase(builder.Configuration)
.AddStorageService(builder.Configuration)
.AddAudioTranscoder(builder.Configuration)
.AddStreamTicketService(builder.Configuration)
.AddPictureService()
.AddMassTransitConsumers(builder.Configuration)
.AddJobs();
var host = builder.Build();
using (var scope = host.Services.CreateScope())
{
var recurringJobManager = scope.ServiceProvider.GetRequiredService<IRecurringJobManager>();
recurringJobManager.AddOrUpdate<DailyMixGenerationJob>(
"daily-mix-generation",
job => job.RunAsync(CancellationToken.None),
Cron.Daily(),
new RecurringJobOptions { TimeZone = TimeZoneInfo.Utc });
recurringJobManager.AddOrUpdate<ListeningHistoryCleanupJob>(
"listening-history-cleanup",
job => job.RunAsync(CancellationToken.None),
Cron.Daily(3),
new RecurringJobOptions { TimeZone = TimeZoneInfo.Utc });
}
host.Run();
@@ -7,17 +7,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AWSSDK.S3" />
<PackageReference Include="MassTransit" />
<PackageReference Include="MassTransit.RabbitMQ" />
<PackageReference Include="Microsoft.EntityFrameworkCore" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" />
<PackageReference Include="Microsoft.Extensions.Hosting" />
<PackageReference Include="Microsoft.Extensions.Options.DataAnnotations" />
<PackageReference Include="MimeMapping" />
<PackageReference Include="Newtonsoft.Json" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" />
<PackageReference Include="SixLabors.ImageSharp" />
</ItemGroup>
<ItemGroup>
@@ -26,10 +26,11 @@
"ApplicationStorage": {
"Bucket": "webapi-storage"
},
"AudioTranscoder": {
"Routes": {
"WorkingDirectory": "../../../deploy/.tmp"
}
"StreamGateway": {
"PublicBaseUrl": "http://localhost:8081"
},
"StreamTicket": {
"PrivateKeyPath": "../../../deploy/keys/stream_private.pem"
},
"Workers": {
"Routes": {
+49 -17
View File
@@ -26,28 +26,63 @@
"ApplicationStorage": {
"Bucket": ""
},
"StreamGateway": {
"PublicBaseUrl": "",
"AudioFileName": "audio.m4a"
},
"StreamTicket": {
"PrivateKeyPath": "",
"Audience": "media-gateway",
"Issuer": "musify-webapi",
"TicketTtlSeconds": 3600
},
"Playback": {
"AllowAnonymousListening": false,
"AnonymousFragmentSeconds": 0,
"EstimatedAudioBytesPerSecond": 16000
},
"Mix": {
"ItemsPerMix": 12
},
"PlayList": {
"Routes": {
"ParentFolders": "PlayLists",
"UploadsFolder": "uploads",
"ParentFolder": "PlayLists",
"OriginalPicturesFolder": "OriginalPictures",
"SmallPicturesFolder": "SmallPictures",
"MediumPicturesFolder": "MediumPictures",
"LargePicturesFolder": "LargePictures"
},
"PicturesSizes": {
"SmallPictureWidth": 128,
"SmallPictureHeight": 128,
"MediumPictureWidth": 256,
"MediumPictureHeight": 256,
"LargePictureWidth": 512,
"LargePictureHeight": 512
"SmallWidth": 128,
"SmallHeight": 128,
"MediumWidth": 256,
"MediumHeight": 256,
"LargeWidth": 512,
"LargeHeight": 512
}
},
"Album": {
"Routes": {
"UploadsFolder": "uploads",
"ParentFolder": "Albums",
"OriginalPicturesFolder": "OriginalPictures",
"SmallPicturesFolder": "SmallPictures",
"MediumPicturesFolder": "MediumPictures",
"LargePicturesFolder": "LargePictures"
},
"PicturesSizes": {
"SmallWidth": 128,
"SmallHeight": 128,
"MediumWidth": 256,
"MediumHeight": 256,
"LargeWidth": 512,
"LargeHeight": 512
}
},
"Track": {
"Routes": {
"UploadsFolder": "uploads",
"ParentFolder": "Tracks",
"OriginalPicturesFolder": "OriginalPictures",
"SmallPicturesFolder": "SmallPictures",
@@ -58,21 +93,18 @@
"PresetMediumPicture": "PresetMediumPicture.webp",
"PresetLargePicture": "PresetLargePicture.webp",
"OriginalAudiosFolder": "OriginalAudios",
"ProcessedAudioFolder": "ProcessedAudios"
"ProcessedAudiosFolder": "ProcessedAudios"
},
"PicturesSizes": {
"SmallPictureWidth": 128,
"SmallPictureHeight": 128,
"MediumPictureWidth": 256,
"MediumPictureHeight": 256,
"LargePictureWidth": 512,
"LargePictureHeight": 512
"SmallWidth": 128,
"SmallHeight": 128,
"MediumWidth": 256,
"MediumHeight": 256,
"LargeWidth": 512,
"LargeHeight": 512
}
},
"AudioTranscoder": {
"Routes": {
"WorkingDirectory": ""
},
"TranscodingTimeout": "00:05:00"
},
"Workers": {