Review round on #568 found the branch changed builtIn identity from a bare filename comparison to the full seeded path (GraphicsElementDefaults. OnNowNextSeededPath) but left several places still asserting the old rule: - docs/decisions/records/graphics/channel-level-attachment.md and on-now-next-on-by-default.md (both status: active) still described a filename-only match; corrected in place and cross-referenced. - docs/api-conventions.md §8 quoted the retired `Path.GetFileName(element.Path) == OnNowNextFileName` expression verbatim; replaced with the current OnNowNextSeededPath comparison and a note on the UpdateChannelHandler 422 hardening. - Three in-code comments (GraphicsElementDefaults.cs, GraphicsElementSeeder.cs, ChannelGraphicsDefaults.cs) still said "identity is the filename". - docs/graphics-elements.md's mutation-coverage table (row 10, row 18) named clauses that no longer exist or no longer redden any test post-#568; re-measured directly (removing the seeded-path check reddens Ignores_A_Non_Built_In_Element_With_A_Different_Filename and Ignores_A_Same_Named_Same_Kind_Element_Outside_The_Seeded_Folder; removing the Kind==Text filter alone reddens nothing, so it moves to the "known clauses with no red" list with that measurement dated). Also closed the should-fix twin: UpdateDecoHandler's graphicsElementIds and watermarkIds are top-level ReplaceDecoRequest fields in the same position as UpdateChannelRequest.graphicsElementIds (not the deep-FK-in-a-nested-list carve-out), and the reconcile in ApplyUpdateRequest blindly Added a join row for any incoming id -- the identical FK-constraint-to-500 defect #568 fixed on the channel path. Added GraphicsElementIdsMustExist/WatermarkIdsMustExist validators mirroring UpdateChannelHandler's, pinned by UpdateDecoGraphicsElementsTests (reddens when either validator alone is removed -- verified). Decisions-Edit: yes Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015QqCpYFsKgnAnx6jVwrKiV
45 lines
2.1 KiB
C#
45 lines
2.1 KiB
C#
using ErsatzTV.Core.Domain;
|
|
using ErsatzTV.FFmpeg.State;
|
|
using ErsatzTV.Infrastructure.Data;
|
|
using ErsatzTV.Infrastructure.Streaming.Graphics;
|
|
|
|
namespace ErsatzTV.Application.Channels;
|
|
|
|
/// <summary>
|
|
/// #732: the On Now / Next overlay is a default rather than an opt-in, so every newly created channel
|
|
/// gets the built-in element attached.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This lives in one place because there is more than one channel-creation path and they diverged
|
|
/// once already: <c>CreateChannelHandler</c> had it and <c>CreateChannelFromLineupHandler</c> -- the
|
|
/// SPA's primary "Add Channel" flow, and the one Auto-Tune bulk-creates through -- did not. Any new
|
|
/// site that persists a <c>Channel</c> must call this. The third site, <c>DbInitializer</c>'s default
|
|
/// channel, needs no call: it runs before <c>AttachOnNowNextByDefault</c> in the same startup, so the
|
|
/// backfill covers it.
|
|
/// </remarks>
|
|
public static class ChannelGraphicsDefaults
|
|
{
|
|
public static async Task Attach(TvContext dbContext, Channel channel, CancellationToken cancellationToken)
|
|
{
|
|
// HLS Direct is skipped because ErsatzTV is not transcoding there -- there is no frame
|
|
// pipeline to draw into, and the editor disables the toggle for the same reason. Identity is
|
|
// the element's full seeded path (`GraphicsElementDefaults.OnNowNextSeededPath`), never its
|
|
// user-editable Name (the #67 lesson, sharpened from filename to full path by #568).
|
|
if (channel.StreamingMode is StreamingMode.HttpLiveStreamingDirect)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Option<int> maybeElementId =
|
|
await GraphicsElementSeeder.GetBuiltInElementId(dbContext, cancellationToken);
|
|
|
|
foreach (int elementId in maybeElementId)
|
|
{
|
|
// Add rather than assign: a future create path that carries graphics ids would otherwise
|
|
// be silently discarded here.
|
|
channel.ChannelGraphicsElements ??= [];
|
|
channel.ChannelGraphicsElements.Add(new ChannelGraphicsElement { GraphicsElementId = elementId });
|
|
}
|
|
}
|
|
}
|