diff --git a/backend/src/TeleWave.Application/Programming/Planning/DebugExport/ChannelDebugCollector.cs b/backend/src/TeleWave.Application/Programming/Planning/DebugExport/ChannelDebugCollector.cs index 45713c9..d2dcd23 100644 --- a/backend/src/TeleWave.Application/Programming/Planning/DebugExport/ChannelDebugCollector.cs +++ b/backend/src/TeleWave.Application/Programming/Planning/DebugExport/ChannelDebugCollector.cs @@ -33,6 +33,17 @@ public sealed class ChannelDebugCollector( /// Сколько прошлого класть в дамп: сдвиги и повторы объясняются вчерашним эфиром. private const int PastDays = 2; + /// + /// Координаты прогона: чей канал, по какому шаблону, на какой момент и на сколько суток вперёд. + /// Ездят вместе через всю сборку, поэтому и передаются вместе. + /// + private sealed record RunScope( + Channel Channel, + ScheduleTemplate Template, + DateTimeOffset Now, + int HorizonDays + ); + public async Task> CollectAsync( Channel channel, ScheduleTemplate template, @@ -41,6 +52,7 @@ public sealed class ChannelDebugCollector( ) { var horizonDays = Math.Max(1, _options.HorizonDays); + var scope = new RunScope(channel, template, now, horizonDays); var from = now.AddDays(-PastDays); var to = now.AddDays(horizonDays); @@ -108,11 +120,8 @@ public sealed class ChannelDebugCollector( return [ - new DebugFile("README.md", Readme(channel, now, horizonDays)), - new DebugFile( - "summary.json", - Summary(channel, template, now, horizonDays, grid, entries, preview, drift) - ), + new DebugFile("README.md", Readme(scope)), + new DebugFile("summary.json", Summary(scope, grid, entries, preview, drift)), new DebugFile("drift.json", DriftFacts(drift)), new DebugFile("channel.json", ChannelFacts(channel)), new DebugFile("template.json", TemplateFacts(template, groupNames, junctionNames)), @@ -239,11 +248,11 @@ public sealed class ChannelDebugCollector( }; } - private static string Readme(Channel channel, DateTimeOffset now, int horizonDays) => + private static string Readme(RunScope scope) => $""" - # Отладочный дамп канала «{channel.Name}» + # Отладочный дамп канала «{scope.Channel.Name}» - Собран: {now:yyyy-MM-dd HH:mm:ss} UTC. Горизонт планирования: {horizonDays} сут., + Собран: {scope.Now:yyyy-MM-dd HH:mm:ss} UTC. Горизонт планирования: {scope.HorizonDays} сут., прошлое в дампе: {PastDays} сут. - `summary.json` — что за канал, сколько чего собралось, свод предупреждений. @@ -276,16 +285,13 @@ public sealed class ChannelDebugCollector( пошло меньше». `groups.json` рядом — только те группы, что участвуют в этом канале. Времена везде UTC. Время канала = UTC{( - channel.UtcOffsetMinutes < 0 ? "-" : "+" - )}{Math.Abs(channel.UtcOffsetMinutes) / 60:00}:{Math.Abs(channel.UtcOffsetMinutes) + scope.Channel.UtcOffsetMinutes < 0 ? "-" : "+" + )}{Math.Abs(scope.Channel.UtcOffsetMinutes) / 60:00}:{Math.Abs(scope.Channel.UtcOffsetMinutes) % 60:00}. """; private object Summary( - Channel channel, - ScheduleTemplate template, - DateTimeOffset now, - int horizonDays, + RunScope scope, EffectiveGrid grid, IReadOnlyList entries, PlanningResult? preview, @@ -293,27 +299,27 @@ public sealed class ChannelDebugCollector( ) => new { - CollectedAtUtc = now, + CollectedAtUtc = scope.Now, Channel = new { - channel.Id, - channel.Name, - channel.Slug, - channel.IsEnabled, + scope.Channel.Id, + scope.Channel.Name, + scope.Channel.Slug, + scope.Channel.IsEnabled, }, Scheduler = new { - HorizonDays = horizonDays, + scope.HorizonDays, _options.RetentionDays, _options.TickMinutes, }, Template = new { - template.Id, - template.Revision, - template.HasPendingChanges, - Layers = template.Layers.Count, - Slots = template.Layers.Sum(l => l.Slots.Count), + scope.Template.Id, + scope.Template.Revision, + scope.Template.HasPendingChanges, + Layers = scope.Template.Layers.Count, + Slots = scope.Template.Layers.Sum(l => l.Slots.Count), }, Grid = new { Instances = grid.Slots.Count, Background = grid.Background.Count }, Drift = DriftSummary(drift), @@ -436,7 +442,7 @@ public sealed class ChannelDebugCollector( scheduled.Slot.Id, scheduled.Slot.Title, scheduled.BroadcastDate, - StartUtc = scheduled.StartUtc, + scheduled.StartUtc, EndUtc = scheduled.StartUtc.AddMinutes(scheduled.Slot.TargetDurationMinutes), scheduled.Slot.TargetDurationMinutes, scheduled.Slot.SlotKind, @@ -561,7 +567,7 @@ public sealed class ChannelDebugCollector( Slot = w.SlotId is { } id ? slotTitles.GetValueOrDefault(id) : null, w.Details, }), - Cursors = preview.Cursors, + preview.Cursors, Items = preview.Items.Select(item => new { item.StartsAtUtc, diff --git a/backend/src/TeleWave.Application/Programming/Planning/DebugExport/LibraryDebugCollector.cs b/backend/src/TeleWave.Application/Programming/Planning/DebugExport/LibraryDebugCollector.cs index 0335dd7..6d4430a 100644 --- a/backend/src/TeleWave.Application/Programming/Planning/DebugExport/LibraryDebugCollector.cs +++ b/backend/src/TeleWave.Application/Programming/Planning/DebugExport/LibraryDebugCollector.cs @@ -24,10 +24,13 @@ public sealed class LibraryDebugCollector( { public async Task> CollectAsync(CancellationToken cancellationToken) { + // Раздельными запросами: у шоу и серии, и жанры, и в одном join строки перемножились бы — + // 788 серий на три жанра дают 2364 строки вместо 791 на одном только сериале. var shows = await dbContext .Shows.AsNoTracking() .Include(s => s.Episodes) .Include(s => s.Genres) + .AsSplitQuery() .ToListAsync(cancellationToken); var genres = await dbContext @@ -42,8 +45,6 @@ public sealed class LibraryDebugCollector( a.Status, a.Duration, a.SegmentCount, - a.Width, - a.Height, a.ErrorMessage )) .ToDictionaryAsync(a => a.Id, cancellationToken); @@ -168,7 +169,7 @@ public sealed class LibraryDebugCollector( s.Group.Name, CachedUnits = s.Group.UnitCount, ActualUnits = s.Units, - PlayableUnits = s.PlayableUnits, + s.PlayableUnits, s.Group.StatsComputedAt, }), }; @@ -181,8 +182,6 @@ public sealed class LibraryDebugCollector( MediaAssetStatus Status, TimeSpan? Duration, int? SegmentCount, - int? Width, - int? Height, string? ErrorMessage ); @@ -251,7 +250,7 @@ public sealed class LibraryDebugCollector( episode.AirDate, episode.MediaAssetId, File = asset?.OriginalFileName, - Status = asset?.Status, + asset?.Status, Minutes = asset?.Duration is { } duration ? Math.Round(duration.TotalMinutes, 2) : (double?)null, @@ -334,7 +333,7 @@ public sealed class LibraryDebugCollector( Seconds = asset?.Duration is { } duration ? Math.Round(duration.TotalSeconds, 1) : (double?)null, - Status = asset?.Status, + asset?.Status, File = asset?.OriginalFileName, }; });