Implement BumperEndpoints and remove deprecated bumper-related functionality
ci / build-backend (push) Successful in 1m39s
ci / build-frontend (push) Failing after 26s
ci / tests (push) Skipped
ci / sonar (push) Skipped

Added new BumperEndpoints to the API for managing bumper templates and variants, enhancing the channel management capabilities. Removed outdated bumper-related commands and handlers from the application, streamlining the codebase and improving maintainability. Updated ChannelEndpoints to reflect these changes and ensure proper routing for the new endpoints.
This commit is contained in:
Leonid Pershin
2026-07-27 22:01:56 +03:00
parent ee0b4d2d01
commit ba3721eb92
140 changed files with 7326 additions and 3609 deletions
@@ -0,0 +1,465 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace TeleWave.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class SharedJunctionsAndBumperLines : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
// Перенос данных идёт до всех схемных операций: старые колонки ещё на месте.
// Текст подблоков превращается в строки, «Сейчас/Далее» — в четыре строки с
// плейсхолдерами, свободный текст — в две.
migrationBuilder.Sql("""ALTER TABLE "BumperTextVariants" ADD COLUMN "Lines" jsonb;""");
migrationBuilder.Sql(
"""
UPDATE "BumperTextVariants" SET "Lines" = CASE WHEN "Kind" = 1 THEN
jsonb_build_array(
jsonb_build_object('Position', 0, 'Style', 0, 'Color', 0, 'Text', COALESCE("Line1", '')),
jsonb_build_object('Position', 1, 'Style', 1, 'Color', 1, 'Text', COALESCE("Line2", ''))
)
ELSE
jsonb_build_array(
jsonb_build_object('Position', 0, 'Style', 0, 'Color', 0, 'Text', COALESCE("NowLabel", '')),
jsonb_build_object('Position', 1, 'Style', 1, 'Color', 1, 'Text', '{now.title}'),
jsonb_build_object('Position', 2, 'Style', 0, 'Color', 0, 'Text', COALESCE("NextLabel", '')),
jsonb_build_object('Position', 3, 'Style', 1, 'Color', 1, 'Text', '{next.title}')
)
END;
"""
);
// Пустые строки выбрасываем и перенумеровываем — иначе в кадре останутся дыры.
migrationBuilder.Sql(
"""
UPDATE "BumperTextVariants" v SET "Lines" = f.lines
FROM (
SELECT id, COALESCE(jsonb_agg(jsonb_set(elem, '{Position}', to_jsonb(rn - 1)) ORDER BY rn), '[]'::jsonb) AS lines
FROM (
SELECT t."Id" AS id, e.elem AS elem,
row_number() OVER (PARTITION BY t."Id" ORDER BY e.ord) AS rn
FROM "BumperTextVariants" t,
LATERAL jsonb_array_elements(t."Lines") WITH ORDINALITY AS e(elem, ord)
WHERE COALESCE(e.elem->>'Text', '') <> ''
) x GROUP BY id
) f WHERE v."Id" = f.id;
"""
);
// Фон: «Сейчас/Далее» показывал постер следующего шоу, свободный текст — фон блока.
migrationBuilder.Sql(
"""ALTER TABLE "BumperTextVariants" ADD COLUMN "Background" integer NOT NULL DEFAULT 0;"""
);
migrationBuilder.Sql(
"""UPDATE "BumperTextVariants" SET "Background" = CASE WHEN "Kind" = 1 THEN 0 ELSE 1 END;"""
);
// Шрифт переезжает с канала на блок — у блока он был канальным.
migrationBuilder.Sql(
"""ALTER TABLE "BumperTemplate" ADD COLUMN "Font" integer NOT NULL DEFAULT 0;"""
);
migrationBuilder.Sql(
"""UPDATE "BumperTemplate" t SET "Font" = c."BumperFont" FROM "Channels" c WHERE c."Id" = t."ChannelId";"""
);
// Кэш заставок: сигнатура теперь считается по содержимому, а подставленного текста
// у старых записей нет. Это кэш — он пересоберётся при ближайшей генерации.
migrationBuilder.Sql("""DELETE FROM "BumperAssets";""");
migrationBuilder.DropForeignKey(
name: "FK_BumperTemplate_Channels_ChannelId",
table: "BumperTemplate"
);
migrationBuilder.DropForeignKey(
name: "FK_BumperTextVariants_BumperTemplate_BumperTemplateId",
table: "BumperTextVariants"
);
migrationBuilder.DropIndex(
name: "IX_JunctionTemplates_ChannelId",
table: "JunctionTemplates"
);
migrationBuilder.DropIndex(
name: "IX_BumperAssets_FromShowId_ToShowId_Signature",
table: "BumperAssets"
);
migrationBuilder.DropPrimaryKey(name: "PK_BumperTemplate", table: "BumperTemplate");
migrationBuilder.DropIndex(
name: "IX_BumperTemplate_ChannelId_Position",
table: "BumperTemplate"
);
migrationBuilder.DropColumn(name: "ChannelId", table: "JunctionTemplates");
migrationBuilder.DropColumn(name: "BumperFont", table: "Channels");
migrationBuilder.DropColumn(name: "BumperSelection", table: "Channels");
migrationBuilder.DropColumn(name: "BumpersEnabled", table: "Channels");
migrationBuilder.DropColumn(name: "Line1", table: "BumperTextVariants");
migrationBuilder.DropColumn(name: "Line2", table: "BumperTextVariants");
migrationBuilder.DropColumn(name: "NextLabel", table: "BumperTextVariants");
migrationBuilder.DropColumn(name: "NowLabel", table: "BumperTextVariants");
migrationBuilder.DropColumn(name: "ChannelId", table: "BumperAssets");
migrationBuilder.DropColumn(name: "FromShowId", table: "BumperAssets");
migrationBuilder.DropColumn(name: "ToShowId", table: "BumperAssets");
migrationBuilder.DropColumn(name: "ChannelId", table: "BumperTemplate");
migrationBuilder.RenameTable(name: "BumperTemplate", newName: "BumperTemplates");
migrationBuilder.DropColumn(name: "Kind", table: "BumperTextVariants");
migrationBuilder.DropColumn(name: "Position", table: "BumperTemplates");
migrationBuilder.AddColumn<int>(
name: "MaxTotalSeconds",
table: "JunctionTemplates",
type: "integer",
nullable: true
);
migrationBuilder.AddColumn<Guid>(
name: "BumperVariantId",
table: "JunctionElements",
type: "uuid",
nullable: true
);
migrationBuilder.AddColumn<string>(
name: "ChoiceKey",
table: "JunctionElements",
type: "character varying(64)",
maxLength: 64,
nullable: true
);
migrationBuilder.AddColumn<int>(
name: "ChoiceWeight",
table: "JunctionElements",
type: "integer",
nullable: false,
defaultValue: 1
);
migrationBuilder.AddColumn<Guid>(
name: "PosterShowId",
table: "BumperAssets",
type: "uuid",
nullable: true
);
migrationBuilder.AddColumn<string>(
name: "RenderedLinesJson",
table: "BumperAssets",
type: "jsonb",
nullable: false,
defaultValue: "[]"
);
migrationBuilder.AddPrimaryKey(
name: "PK_BumperTemplates",
table: "BumperTemplates",
column: "Id"
);
migrationBuilder.CreateIndex(
name: "IX_JunctionTemplates_Name",
table: "JunctionTemplates",
column: "Name"
);
migrationBuilder.CreateIndex(
name: "IX_JunctionElements_BumperTemplateId",
table: "JunctionElements",
column: "BumperTemplateId"
);
migrationBuilder.CreateIndex(
name: "IX_JunctionElements_BumperVariantId",
table: "JunctionElements",
column: "BumperVariantId"
);
migrationBuilder.CreateIndex(
name: "IX_BumperAssets_MediaAssetId",
table: "BumperAssets",
column: "MediaAssetId"
);
migrationBuilder.CreateIndex(
name: "IX_BumperAssets_Signature",
table: "BumperAssets",
column: "Signature",
unique: true
);
migrationBuilder.CreateIndex(
name: "IX_BumperTemplates_Name",
table: "BumperTemplates",
column: "Name"
);
migrationBuilder.AddForeignKey(
name: "FK_BumperTextVariants_BumperTemplates_BumperTemplateId",
table: "BumperTextVariants",
column: "BumperTemplateId",
principalTable: "BumperTemplates",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade
);
migrationBuilder.AddForeignKey(
name: "FK_JunctionElements_BumperTemplates_BumperTemplateId",
table: "JunctionElements",
column: "BumperTemplateId",
principalTable: "BumperTemplates",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict
);
migrationBuilder.AddForeignKey(
name: "FK_JunctionElements_BumperTextVariants_BumperVariantId",
table: "JunctionElements",
column: "BumperVariantId",
principalTable: "BumperTextVariants",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict
);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_BumperTextVariants_BumperTemplates_BumperTemplateId",
table: "BumperTextVariants"
);
migrationBuilder.DropForeignKey(
name: "FK_JunctionElements_BumperTemplates_BumperTemplateId",
table: "JunctionElements"
);
migrationBuilder.DropForeignKey(
name: "FK_JunctionElements_BumperTextVariants_BumperVariantId",
table: "JunctionElements"
);
migrationBuilder.DropIndex(
name: "IX_JunctionTemplates_Name",
table: "JunctionTemplates"
);
migrationBuilder.DropIndex(
name: "IX_JunctionElements_BumperTemplateId",
table: "JunctionElements"
);
migrationBuilder.DropIndex(
name: "IX_JunctionElements_BumperVariantId",
table: "JunctionElements"
);
migrationBuilder.DropIndex(name: "IX_BumperAssets_MediaAssetId", table: "BumperAssets");
migrationBuilder.DropIndex(name: "IX_BumperAssets_Signature", table: "BumperAssets");
migrationBuilder.DropPrimaryKey(name: "PK_BumperTemplates", table: "BumperTemplates");
migrationBuilder.DropIndex(name: "IX_BumperTemplates_Name", table: "BumperTemplates");
migrationBuilder.DropColumn(name: "MaxTotalSeconds", table: "JunctionTemplates");
migrationBuilder.DropColumn(name: "BumperVariantId", table: "JunctionElements");
migrationBuilder.DropColumn(name: "ChoiceKey", table: "JunctionElements");
migrationBuilder.DropColumn(name: "ChoiceWeight", table: "JunctionElements");
migrationBuilder.DropColumn(name: "Lines", table: "BumperTextVariants");
migrationBuilder.DropColumn(name: "PosterShowId", table: "BumperAssets");
migrationBuilder.DropColumn(name: "RenderedLinesJson", table: "BumperAssets");
migrationBuilder.RenameTable(name: "BumperTemplates", newName: "BumperTemplate");
migrationBuilder.DropColumn(name: "Background", table: "BumperTextVariants");
migrationBuilder.AddColumn<int>(
name: "Kind",
table: "BumperTextVariants",
type: "integer",
nullable: false,
defaultValue: 0
);
migrationBuilder.DropColumn(name: "Font", table: "BumperTemplate");
migrationBuilder.AddColumn<int>(
name: "Position",
table: "BumperTemplate",
type: "integer",
nullable: false,
defaultValue: 0
);
migrationBuilder.AddColumn<Guid>(
name: "ChannelId",
table: "JunctionTemplates",
type: "uuid",
nullable: false,
defaultValue: new Guid("00000000-0000-0000-0000-000000000000")
);
migrationBuilder.AddColumn<int>(
name: "BumperFont",
table: "Channels",
type: "integer",
nullable: false,
defaultValue: 0
);
migrationBuilder.AddColumn<int>(
name: "BumperSelection",
table: "Channels",
type: "integer",
nullable: false,
defaultValue: 0
);
migrationBuilder.AddColumn<bool>(
name: "BumpersEnabled",
table: "Channels",
type: "boolean",
nullable: false,
defaultValue: false
);
migrationBuilder.AddColumn<string>(
name: "Line1",
table: "BumperTextVariants",
type: "character varying(120)",
maxLength: 120,
nullable: false,
defaultValue: ""
);
migrationBuilder.AddColumn<string>(
name: "Line2",
table: "BumperTextVariants",
type: "character varying(120)",
maxLength: 120,
nullable: false,
defaultValue: ""
);
migrationBuilder.AddColumn<string>(
name: "NextLabel",
table: "BumperTextVariants",
type: "character varying(64)",
maxLength: 64,
nullable: false,
defaultValue: ""
);
migrationBuilder.AddColumn<string>(
name: "NowLabel",
table: "BumperTextVariants",
type: "character varying(64)",
maxLength: 64,
nullable: false,
defaultValue: ""
);
migrationBuilder.AddColumn<Guid>(
name: "ChannelId",
table: "BumperAssets",
type: "uuid",
nullable: false,
defaultValue: new Guid("00000000-0000-0000-0000-000000000000")
);
migrationBuilder.AddColumn<Guid>(
name: "FromShowId",
table: "BumperAssets",
type: "uuid",
nullable: false,
defaultValue: new Guid("00000000-0000-0000-0000-000000000000")
);
migrationBuilder.AddColumn<Guid>(
name: "ToShowId",
table: "BumperAssets",
type: "uuid",
nullable: false,
defaultValue: new Guid("00000000-0000-0000-0000-000000000000")
);
migrationBuilder.AddColumn<Guid>(
name: "ChannelId",
table: "BumperTemplate",
type: "uuid",
nullable: false,
defaultValue: new Guid("00000000-0000-0000-0000-000000000000")
);
migrationBuilder.AddPrimaryKey(
name: "PK_BumperTemplate",
table: "BumperTemplate",
column: "Id"
);
migrationBuilder.CreateIndex(
name: "IX_JunctionTemplates_ChannelId",
table: "JunctionTemplates",
column: "ChannelId"
);
migrationBuilder.CreateIndex(
name: "IX_BumperAssets_FromShowId_ToShowId_Signature",
table: "BumperAssets",
columns: new[] { "FromShowId", "ToShowId", "Signature" }
);
migrationBuilder.CreateIndex(
name: "IX_BumperTemplate_ChannelId_Position",
table: "BumperTemplate",
columns: new[] { "ChannelId", "Position" }
);
migrationBuilder.AddForeignKey(
name: "FK_BumperTemplate_Channels_ChannelId",
table: "BumperTemplate",
column: "ChannelId",
principalTable: "Channels",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade
);
migrationBuilder.AddForeignKey(
name: "FK_BumperTextVariants_BumperTemplate_BumperTemplateId",
table: "BumperTextVariants",
column: "BumperTemplateId",
principalTable: "BumperTemplate",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade
);
}
}
}
@@ -164,18 +164,19 @@ namespace TeleWave.Infrastructure.Migrations
b.Property<Guid>("Id")
.HasColumnType("uuid");
b.Property<Guid>("ChannelId")
.HasColumnType("uuid");
b.Property<DateTimeOffset>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<Guid>("FromShowId")
.HasColumnType("uuid");
b.Property<Guid>("MediaAssetId")
.HasColumnType("uuid");
b.Property<Guid?>("PosterShowId")
.HasColumnType("uuid");
b.Property<string>("RenderedLinesJson")
.IsRequired()
.HasColumnType("jsonb");
b.Property<string>("Signature")
.IsRequired()
.HasMaxLength(128)
@@ -184,15 +185,15 @@ namespace TeleWave.Infrastructure.Migrations
b.Property<Guid>("TemplateId")
.HasColumnType("uuid");
b.Property<Guid>("ToShowId")
.HasColumnType("uuid");
b.Property<Guid>("VariantId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("FromShowId", "ToShowId", "Signature");
b.HasIndex("MediaAssetId");
b.HasIndex("Signature")
.IsUnique();
b.ToTable("BumperAssets");
});
@@ -227,20 +228,17 @@ namespace TeleWave.Infrastructure.Migrations
b.Property<Guid?>("BackgroundImageId")
.HasColumnType("uuid");
b.Property<Guid>("ChannelId")
.HasColumnType("uuid");
b.Property<DateTimeOffset>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<int>("Font")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)");
b.Property<int>("Position")
.HasColumnType("integer");
b.Property<int>("Revision")
.HasColumnType("integer");
@@ -251,9 +249,9 @@ namespace TeleWave.Infrastructure.Migrations
b.HasKey("Id");
b.HasIndex("ChannelId", "Position");
b.HasIndex("Name");
b.ToTable("BumperTemplate");
b.ToTable("BumperTemplates");
});
modelBuilder.Entity("TeleWave.Domain.Broadcast.BumperTextVariant", b =>
@@ -261,40 +259,20 @@ namespace TeleWave.Infrastructure.Migrations
b.Property<Guid>("Id")
.HasColumnType("uuid");
b.Property<int>("Background")
.HasColumnType("integer");
b.Property<Guid>("BumperTemplateId")
.HasColumnType("uuid");
b.Property<DateTimeOffset>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<int>("Kind")
.HasColumnType("integer");
b.Property<string>("Line1")
.IsRequired()
.HasMaxLength(120)
.HasColumnType("character varying(120)");
b.Property<string>("Line2")
.IsRequired()
.HasMaxLength(120)
.HasColumnType("character varying(120)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)");
b.Property<string>("NextLabel")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)");
b.Property<string>("NowLabel")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)");
b.Property<int>("Position")
.HasColumnType("integer");
@@ -321,15 +299,6 @@ namespace TeleWave.Infrastructure.Migrations
b.Property<double>("AnalogFilterStrength")
.HasColumnType("double precision");
b.Property<int>("BumperFont")
.HasColumnType("integer");
b.Property<int>("BumperSelection")
.HasColumnType("integer");
b.Property<bool>("BumpersEnabled")
.HasColumnType("boolean");
b.Property<DateTimeOffset>("CreatedAt")
.HasColumnType("timestamp with time zone");
@@ -886,6 +855,18 @@ namespace TeleWave.Infrastructure.Migrations
b.Property<Guid?>("BumperTemplateId")
.HasColumnType("uuid");
b.Property<Guid?>("BumperVariantId")
.HasColumnType("uuid");
b.Property<string>("ChoiceKey")
.HasMaxLength(64)
.HasColumnType("character varying(64)");
b.Property<int>("ChoiceWeight")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasDefaultValue(1);
b.Property<string>("ConditionsJson")
.HasColumnType("jsonb");
@@ -906,6 +887,10 @@ namespace TeleWave.Infrastructure.Migrations
b.HasKey("Id");
b.HasIndex("BumperTemplateId");
b.HasIndex("BumperVariantId");
b.HasIndex("GroupId");
b.HasIndex("JunctionTemplateId", "Position");
@@ -918,12 +903,12 @@ namespace TeleWave.Infrastructure.Migrations
b.Property<Guid>("Id")
.HasColumnType("uuid");
b.Property<Guid>("ChannelId")
.HasColumnType("uuid");
b.Property<DateTimeOffset>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<int?>("MaxTotalSeconds")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
@@ -931,7 +916,7 @@ namespace TeleWave.Infrastructure.Migrations
b.HasKey("Id");
b.HasIndex("ChannelId");
b.HasIndex("Name");
b.ToTable("JunctionTemplates");
});
@@ -1234,15 +1219,6 @@ namespace TeleWave.Infrastructure.Migrations
.IsRequired();
});
modelBuilder.Entity("TeleWave.Domain.Broadcast.BumperTemplate", b =>
{
b.HasOne("TeleWave.Domain.Broadcast.Channel", null)
.WithMany("BumperTemplates")
.HasForeignKey("ChannelId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("TeleWave.Domain.Broadcast.BumperTextVariant", b =>
{
b.HasOne("TeleWave.Domain.Broadcast.BumperTemplate", null)
@@ -1250,6 +1226,37 @@ namespace TeleWave.Infrastructure.Migrations
.HasForeignKey("BumperTemplateId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.OwnsMany("TeleWave.Domain.Broadcast.BumperLine", "Lines", b1 =>
{
b1.Property<Guid>("BumperTextVariantId");
b1.Property<int>("__synthesizedOrdinal")
.ValueGeneratedOnAdd();
b1.Property<int>("Color");
b1.Property<int>("Position");
b1.Property<int>("Style");
b1.Property<string>("Text")
.IsRequired()
.HasMaxLength(120);
b1.HasKey("BumperTextVariantId", "__synthesizedOrdinal");
b1.ToTable("BumperTextVariants");
b1
.ToJson("Lines")
.HasColumnType("jsonb");
b1.WithOwner()
.HasForeignKey("BumperTextVariantId");
});
b.Navigation("Lines");
});
modelBuilder.Entity("TeleWave.Domain.Library.CollectionItem", b =>
@@ -1320,6 +1327,16 @@ namespace TeleWave.Infrastructure.Migrations
modelBuilder.Entity("TeleWave.Domain.Programming.JunctionElement", b =>
{
b.HasOne("TeleWave.Domain.Broadcast.BumperTemplate", null)
.WithMany()
.HasForeignKey("BumperTemplateId")
.OnDelete(DeleteBehavior.Restrict);
b.HasOne("TeleWave.Domain.Broadcast.BumperTextVariant", null)
.WithMany()
.HasForeignKey("BumperVariantId")
.OnDelete(DeleteBehavior.Restrict);
b.HasOne("TeleWave.Domain.Programming.Group", null)
.WithMany()
.HasForeignKey("GroupId")
@@ -1360,11 +1377,6 @@ namespace TeleWave.Infrastructure.Migrations
b.Navigation("Variants");
});
modelBuilder.Entity("TeleWave.Domain.Broadcast.Channel", b =>
{
b.Navigation("BumperTemplates");
});
modelBuilder.Entity("TeleWave.Domain.Library.Collection", b =>
{
b.Navigation("Items");