diff --git a/backend/src/TeleWave.Api/Program.cs b/backend/src/TeleWave.Api/Program.cs index 88d2c0f..ce1196b 100644 --- a/backend/src/TeleWave.Api/Program.cs +++ b/backend/src/TeleWave.Api/Program.cs @@ -143,7 +143,6 @@ app.UseDefaultFiles(); app.UseStaticFiles(); app.MapFallbackToFile("index.html"); +// Раньше здесь объявлялся `public partial class Program;` — чтобы WebApplicationTestFactory видела +// сгенерированный класс. В ASP.NET Core 10 он и так публичный (ASP0027), объявление стало лишним. await app.RunAsync(); - -/// Делает неявный класс Program доступным для WebApplicationFactory<Program> в интеграционных тестах. -public partial class Program; diff --git a/backend/src/TeleWave.Application/Library/Collections/ListCollections/ListCollectionsQueryHandler.cs b/backend/src/TeleWave.Application/Library/Collections/ListCollections/ListCollectionsQueryHandler.cs index 52bd584..24b3fef 100644 --- a/backend/src/TeleWave.Application/Library/Collections/ListCollections/ListCollectionsQueryHandler.cs +++ b/backend/src/TeleWave.Application/Library/Collections/ListCollections/ListCollectionsQueryHandler.cs @@ -24,7 +24,7 @@ public sealed class ListCollectionsQueryHandler(IAppDbContext dbContext) var episodeCounts = await dbContext .Shows.AsNoTracking() .Where(s => showIds.Contains(s.Id)) - .Select(s => new { s.Id, Count = s.Episodes.Count }) + .Select(s => new { s.Id, s.Episodes.Count }) .ToDictionaryAsync(x => x.Id, x => x.Count, cancellationToken); return collections diff --git a/backend/src/TeleWave.Domain/Broadcast/BumperTemplate.cs b/backend/src/TeleWave.Domain/Broadcast/BumperTemplate.cs index e2dfe6e..2cfe4e1 100644 --- a/backend/src/TeleWave.Domain/Broadcast/BumperTemplate.cs +++ b/backend/src/TeleWave.Domain/Broadcast/BumperTemplate.cs @@ -10,7 +10,7 @@ namespace TeleWave.Domain.Broadcast; /// public class BumperTemplate { - private readonly List _variants = new(); + private readonly List _variants = []; public Guid Id { get; private set; } public Guid ChannelId { get; private set; } diff --git a/backend/src/TeleWave.Domain/Broadcast/Channel.cs b/backend/src/TeleWave.Domain/Broadcast/Channel.cs index dde8590..74a5e60 100644 --- a/backend/src/TeleWave.Domain/Broadcast/Channel.cs +++ b/backend/src/TeleWave.Domain/Broadcast/Channel.cs @@ -7,7 +7,7 @@ namespace TeleWave.Domain.Broadcast; /// public class Channel { - private readonly List _bumperTemplates = new(); + private readonly List _bumperTemplates = []; public Guid Id { get; private set; } public string Name { get; private set; } = string.Empty; diff --git a/backend/src/TeleWave.Domain/Library/Collection.cs b/backend/src/TeleWave.Domain/Library/Collection.cs index 9a40875..6e626af 100644 --- a/backend/src/TeleWave.Domain/Library/Collection.cs +++ b/backend/src/TeleWave.Domain/Library/Collection.cs @@ -12,7 +12,7 @@ namespace TeleWave.Domain.Library; /// public class Collection { - private readonly List _items = new(); + private readonly List _items = []; public Guid Id { get; private set; } public string Name { get; private set; } = string.Empty; diff --git a/backend/src/TeleWave.Domain/Library/Genre.cs b/backend/src/TeleWave.Domain/Library/Genre.cs index f0b4cd2..78021f2 100644 --- a/backend/src/TeleWave.Domain/Library/Genre.cs +++ b/backend/src/TeleWave.Domain/Library/Genre.cs @@ -10,7 +10,7 @@ namespace TeleWave.Domain.Library; /// public class Genre { - private readonly List _aliases = new(); + private readonly List _aliases = []; public Guid Id { get; private set; } diff --git a/backend/src/TeleWave.Domain/Library/Show.cs b/backend/src/TeleWave.Domain/Library/Show.cs index 4497db8..0b9aeac 100644 --- a/backend/src/TeleWave.Domain/Library/Show.cs +++ b/backend/src/TeleWave.Domain/Library/Show.cs @@ -8,8 +8,8 @@ namespace TeleWave.Domain.Library; /// public class Show { - private readonly List _episodes = new(); - private readonly List _genres = new(); + private readonly List _episodes = []; + private readonly List _genres = []; public Guid Id { get; private set; } public string Name { get; private set; } = string.Empty; diff --git a/backend/src/TeleWave.Domain/Programming/GridLayer.cs b/backend/src/TeleWave.Domain/Programming/GridLayer.cs index 4e416b9..5da03af 100644 --- a/backend/src/TeleWave.Domain/Programming/GridLayer.cs +++ b/backend/src/TeleWave.Domain/Programming/GridLayer.cs @@ -9,7 +9,7 @@ namespace TeleWave.Domain.Programming; /// public class GridLayer { - private readonly List _slots = new(); + private readonly List _slots = []; public Guid Id { get; private set; } public Guid TemplateId { get; private set; } diff --git a/backend/src/TeleWave.Domain/Programming/Group.cs b/backend/src/TeleWave.Domain/Programming/Group.cs index d63e32b..a486263 100644 --- a/backend/src/TeleWave.Domain/Programming/Group.cs +++ b/backend/src/TeleWave.Domain/Programming/Group.cs @@ -11,7 +11,7 @@ namespace TeleWave.Domain.Programming; /// public class Group { - private readonly List _items = new(); + private readonly List _items = []; public Guid Id { get; private set; } public string Name { get; private set; } = string.Empty; diff --git a/backend/src/TeleWave.Domain/Programming/JunctionTemplate.cs b/backend/src/TeleWave.Domain/Programming/JunctionTemplate.cs index ccfcca5..ebeb6fd 100644 --- a/backend/src/TeleWave.Domain/Programming/JunctionTemplate.cs +++ b/backend/src/TeleWave.Domain/Programming/JunctionTemplate.cs @@ -7,7 +7,7 @@ namespace TeleWave.Domain.Programming; /// public class JunctionTemplate { - private readonly List _elements = new(); + private readonly List _elements = []; public Guid Id { get; private set; } public Guid ChannelId { get; private set; } diff --git a/backend/src/TeleWave.Domain/Programming/Planning/JunctionFiller.cs b/backend/src/TeleWave.Domain/Programming/Planning/JunctionFiller.cs index 4233d09..c3e887e 100644 --- a/backend/src/TeleWave.Domain/Programming/Planning/JunctionFiller.cs +++ b/backend/src/TeleWave.Domain/Programming/Planning/JunctionFiller.cs @@ -3,7 +3,7 @@ namespace TeleWave.Domain.Programming.Planning; /// Состояние стыков в рамках прогона: когда какая врезка ставилась последний раз. public sealed class JunctionHistory { - private readonly Dictionary _lastPlaced = new(); + private readonly Dictionary _lastPlaced = []; public bool Allows(PlanningJunctionElement element, DateTimeOffset moment) { diff --git a/backend/src/TeleWave.Domain/Programming/ScheduleTemplate.cs b/backend/src/TeleWave.Domain/Programming/ScheduleTemplate.cs index 535db57..4f2e17d 100644 --- a/backend/src/TeleWave.Domain/Programming/ScheduleTemplate.cs +++ b/backend/src/TeleWave.Domain/Programming/ScheduleTemplate.cs @@ -10,7 +10,7 @@ namespace TeleWave.Domain.Programming; /// public class ScheduleTemplate { - private readonly List _layers = new(); + private readonly List _layers = []; public Guid Id { get; private set; } public Guid ChannelId { get; private set; } diff --git a/backend/src/TeleWave.Infrastructure/Media/FfmpegBumperRenderer.cs b/backend/src/TeleWave.Infrastructure/Media/FfmpegBumperRenderer.cs index 5a07854..84870d4 100644 --- a/backend/src/TeleWave.Infrastructure/Media/FfmpegBumperRenderer.cs +++ b/backend/src/TeleWave.Infrastructure/Media/FfmpegBumperRenderer.cs @@ -109,7 +109,7 @@ public sealed class FfmpegBumperRenderer( segmentCount, spec.Width, spec.Height, - paths.AssetRelativePath(assetId) + MediaPathResolver.AssetRelativePath(assetId) ); } finally diff --git a/backend/src/TeleWave.Infrastructure/Media/FfmpegMediaProcessor.cs b/backend/src/TeleWave.Infrastructure/Media/FfmpegMediaProcessor.cs index 1888629..140791f 100644 --- a/backend/src/TeleWave.Infrastructure/Media/FfmpegMediaProcessor.cs +++ b/backend/src/TeleWave.Infrastructure/Media/FfmpegMediaProcessor.cs @@ -81,7 +81,7 @@ public sealed class FfmpegMediaProcessor( outHeight, "h264", "aac", - paths.AssetRelativePath(assetId) + MediaPathResolver.AssetRelativePath(assetId) ); } diff --git a/backend/src/TeleWave.Infrastructure/Media/MediaClaimingBackgroundService.cs b/backend/src/TeleWave.Infrastructure/Media/MediaClaimingBackgroundService.cs index 0a6b0a7..af3054b 100644 --- a/backend/src/TeleWave.Infrastructure/Media/MediaClaimingBackgroundService.cs +++ b/backend/src/TeleWave.Infrastructure/Media/MediaClaimingBackgroundService.cs @@ -26,8 +26,10 @@ internal abstract class MediaClaimingBackgroundService( ) : BackgroundService where TJob : class { - // Периодически перепроверяем БД, даже если сигнал не пришёл — страховка на любой случай. - private static readonly TimeSpan IdlePoll = TimeSpan.FromSeconds(30); + // Период опроса вынесен в неродовой класс: статическое поле обобщённого типа существует + // отдельной копией на каждую замкнутую специализацию, то есть выглядит общей константой, + // не будучи ею. Здесь значение одинаковое и вреда нет, но читателя это вводит в заблуждение. + private static TimeSpan IdlePoll => MediaClaimingDefaults.IdlePoll; /// true — воркер обслуживает только сгенерированные ассеты, false — только остальные. protected abstract bool HandlesGenerated { get; } @@ -238,3 +240,10 @@ internal abstract class MediaClaimingBackgroundService( ? x => x.Status == status && x.Source == MediaSource.Generated : x => x.Status == status && x.Source != MediaSource.Generated; } + +/// Общие для всех воркеров значения — одно на процесс, а не на специализацию. +internal static class MediaClaimingDefaults +{ + /// Периодически перепроверяем БД, даже если сигнал не пришёл — страховка на любой случай. + public static readonly TimeSpan IdlePoll = TimeSpan.FromSeconds(30); +} diff --git a/backend/src/TeleWave.Infrastructure/Media/MediaPathResolver.cs b/backend/src/TeleWave.Infrastructure/Media/MediaPathResolver.cs index 3eedf9e..ac1a4fc 100644 --- a/backend/src/TeleWave.Infrastructure/Media/MediaPathResolver.cs +++ b/backend/src/TeleWave.Infrastructure/Media/MediaPathResolver.cs @@ -64,7 +64,7 @@ public sealed class MediaPathResolver public string AssetDir(Guid assetId) => EnsureWithinRoot(Path.Combine(AssetsDir, assetId.ToString("N"))); - public string AssetRelativePath(Guid assetId) => $"assets/{assetId:N}"; + public static string AssetRelativePath(Guid assetId) => $"assets/{assetId:N}"; /// Путь к файлу сегмента внутри каталога ассета (имя файла проверяется на traversal). public string SegmentPath(Guid assetId, string fileName) diff --git a/backend/src/TeleWave.Infrastructure/Media/SignalQueue.cs b/backend/src/TeleWave.Infrastructure/Media/SignalQueue.cs index dd09e51..9dd418a 100644 --- a/backend/src/TeleWave.Infrastructure/Media/SignalQueue.cs +++ b/backend/src/TeleWave.Infrastructure/Media/SignalQueue.cs @@ -20,7 +20,10 @@ public abstract class SignalQueue public async ValueTask WaitAsync(CancellationToken cancellationToken) { await _channel.Reader.ReadAsync(cancellationToken); - // Сдренировать накопившиеся сигналы — работу всё равно берём из БД пачкой. - while (_channel.Reader.TryRead(out _)) { } + while (_channel.Reader.TryRead(out _)) + { + // Тело пустое намеренно: сигналы дренируются ради побочного эффекта чтения — работу + // обработчик всё равно берёт из БД пачкой, и сами значения не нужны. + } } } diff --git a/backend/src/TeleWave.Infrastructure/Metadata/MetadataProviderResolver.cs b/backend/src/TeleWave.Infrastructure/Metadata/MetadataProviderResolver.cs index 51e540c..4468254 100644 --- a/backend/src/TeleWave.Infrastructure/Metadata/MetadataProviderResolver.cs +++ b/backend/src/TeleWave.Infrastructure/Metadata/MetadataProviderResolver.cs @@ -7,7 +7,7 @@ namespace TeleWave.Infrastructure.Metadata; public sealed class MetadataProviderResolver : IMetadataProviderResolver { private readonly Dictionary _byKey; - private readonly List _available = new(); + private readonly List _available = []; public MetadataProviderResolver( IEnumerable providers,