diff --git a/Backend/Migrations/20260627163650_AddClipAdminMenuVisible.cs b/Backend/Migrations/20260627163650_AddClipAdminMenuVisible.cs index a3d84d8..892b213 100644 --- a/Backend/Migrations/20260627163650_AddClipAdminMenuVisible.cs +++ b/Backend/Migrations/20260627163650_AddClipAdminMenuVisible.cs @@ -12,111 +12,89 @@ namespace Backend.Migrations /// protected override void Up(MigrationBuilder migrationBuilder) { - migrationBuilder.AddColumn( - name: "ClipAdminMenuVisible", - table: "SiteSettings", - type: "boolean", - nullable: false, - defaultValue: false); + migrationBuilder.Sql(""" + ALTER TABLE "SiteSettings" + ADD COLUMN IF NOT EXISTS "ClipAdminMenuVisible" boolean NOT NULL DEFAULT FALSE; - migrationBuilder.AddColumn( - name: "ShowactApplicationDisabledMessage", - table: "SiteSettings", - type: "character varying(240)", - maxLength: 240, - nullable: false, - defaultValue: ""); + ALTER TABLE "SiteSettings" + ADD COLUMN IF NOT EXISTS "ShowactApplicationDisabledMessage" character varying(240) NOT NULL DEFAULT ''; - migrationBuilder.AddColumn( - name: "ShowactApplicationsEnabled", - table: "SiteSettings", - type: "boolean", - nullable: false, - defaultValue: false); + ALTER TABLE "SiteSettings" + ADD COLUMN IF NOT EXISTS "ShowactApplicationsEnabled" boolean NOT NULL DEFAULT FALSE; - migrationBuilder.AddColumn( - name: "ShowactsContent", - table: "SiteSettings", - type: "text", - nullable: false, - defaultValue: ""); + ALTER TABLE "SiteSettings" + ADD COLUMN IF NOT EXISTS "ShowactsContent" text NOT NULL DEFAULT ''; - migrationBuilder.AddColumn( - name: "ShowactsUrl", - table: "SiteSettings", - type: "character varying(400)", - maxLength: 400, - nullable: false, - defaultValue: ""); + ALTER TABLE "SiteSettings" + ADD COLUMN IF NOT EXISTS "ShowactsUrl" character varying(400) NOT NULL DEFAULT ''; - migrationBuilder.AddColumn( - name: "SponsorsVisible", - table: "SiteSettings", - type: "boolean", - nullable: false, - defaultValue: true); + ALTER TABLE "SiteSettings" + ADD COLUMN IF NOT EXISTS "SponsorsVisible" boolean NOT NULL DEFAULT TRUE; + """); - migrationBuilder.CreateTable( - name: "ShowactApplications", - columns: table => new - { - Id = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - SeasonId = table.Column(type: "integer", nullable: false), - ArtistName = table.Column(type: "character varying(120)", maxLength: 120, nullable: false), - ContactEmail = table.Column(type: "character varying(180)", maxLength: 180, nullable: false), - ContactDiscord = table.Column(type: "character varying(120)", maxLength: 120, nullable: false), - PlatformUrl = table.Column(type: "character varying(500)", maxLength: 500, nullable: false), - PerformanceType = table.Column(type: "character varying(80)", maxLength: 80, nullable: false), - Description = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: false), - TechnicalNotes = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: false), - ReferenceUrl = table.Column(type: "character varying(500)", maxLength: 500, nullable: false), - Status = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), - ReviewNote = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), - ReviewedByTwitchId = table.Column(type: "character varying(120)", maxLength: 120, nullable: true), - CreatedFromIp = table.Column(type: "character varying(80)", maxLength: 80, nullable: false), - UserAgent = table.Column(type: "character varying(400)", maxLength: 400, nullable: false), - CreatedAt = table.Column(type: "timestamp with time zone", nullable: false), - ReviewedAt = table.Column(type: "timestamp with time zone", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_ShowactApplications", x => x.Id); - table.ForeignKey( - name: "FK_ShowactApplications_Seasons_SeasonId", - column: x => x.SeasonId, - principalTable: "Seasons", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); + migrationBuilder.Sql(""" + CREATE TABLE IF NOT EXISTS "ShowactApplications" ( + "Id" integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + "SeasonId" integer NOT NULL, + "ArtistName" character varying(120) NOT NULL, + "ContactEmail" character varying(180) NOT NULL, + "ContactDiscord" character varying(120) NOT NULL, + "PlatformUrl" character varying(500) NOT NULL, + "PerformanceType" character varying(80) NOT NULL, + "Description" character varying(1000) NOT NULL, + "TechnicalNotes" character varying(1000) NOT NULL, + "ReferenceUrl" character varying(500) NOT NULL, + "Status" character varying(20) NOT NULL, + "ReviewNote" character varying(500) NULL, + "ReviewedByTwitchId" character varying(120) NULL, + "CreatedFromIp" character varying(80) NOT NULL, + "UserAgent" character varying(400) NOT NULL, + "CreatedAt" timestamp with time zone NOT NULL, + "ReviewedAt" timestamp with time zone NULL + ); - migrationBuilder.CreateTable( - name: "Sponsors", - columns: table => new - { - Id = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - SeasonId = table.Column(type: "integer", nullable: false), - Name = table.Column(type: "character varying(120)", maxLength: 120, nullable: false), - WebsiteUrl = table.Column(type: "character varying(500)", maxLength: 500, nullable: false), - LogoUrl = table.Column(type: "character varying(500)", maxLength: 500, nullable: false), - Description = table.Column(type: "character varying(500)", maxLength: 500, nullable: false), - Tier = table.Column(type: "character varying(80)", maxLength: 80, nullable: false), - SortOrder = table.Column(type: "integer", nullable: false), - IsVisible = table.Column(type: "boolean", nullable: false), - CreatedAt = table.Column(type: "timestamp with time zone", nullable: false), - UpdatedAt = table.Column(type: "timestamp with time zone", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Sponsors", x => x.Id); - table.ForeignKey( - name: "FK_Sponsors_Seasons_SeasonId", - column: x => x.SeasonId, - principalTable: "Seasons", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); + CREATE TABLE IF NOT EXISTS "Sponsors" ( + "Id" integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + "SeasonId" integer NOT NULL, + "Name" character varying(120) NOT NULL, + "WebsiteUrl" character varying(500) NOT NULL, + "LogoUrl" character varying(500) NOT NULL, + "Description" character varying(500) NOT NULL, + "Tier" character varying(80) NOT NULL, + "SortOrder" integer NOT NULL, + "IsVisible" boolean NOT NULL, + "CreatedAt" timestamp with time zone NOT NULL, + "UpdatedAt" timestamp with time zone NULL + ); + + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 + FROM pg_constraint + WHERE conname = 'FK_ShowactApplications_Seasons_SeasonId' + ) THEN + ALTER TABLE "ShowactApplications" + ADD CONSTRAINT "FK_ShowactApplications_Seasons_SeasonId" + FOREIGN KEY ("SeasonId") REFERENCES "Seasons" ("Id") + ON DELETE CASCADE; + END IF; + END $$; + + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 + FROM pg_constraint + WHERE conname = 'FK_Sponsors_Seasons_SeasonId' + ) THEN + ALTER TABLE "Sponsors" + ADD CONSTRAINT "FK_Sponsors_Seasons_SeasonId" + FOREIGN KEY ("SeasonId") REFERENCES "Seasons" ("Id") + ON DELETE CASCADE; + END IF; + END $$; + """); migrationBuilder.UpdateData( table: "SiteSettings", @@ -125,49 +103,43 @@ namespace Backend.Migrations columns: new[] { "ClipAdminMenuVisible", "ShowactApplicationDisabledMessage", "ShowactsContent", "ShowactsUrl", "SponsorsVisible", "WorkflowRulesJson" }, values: new object[] { true, "Showact-Bewerbungen sind aktuell geschlossen.", "Informationen zu Showact-Bewerbungen, Ablauf und Kontakt fuer die Award-Show.", "https://vtuber-star-awards.de/showacts", true, "[{\"key\":\"max_finalists_per_category\",\"label\":\"Finale Kandidat:innen pro Kategorie\",\"enabled\":true,\"limit\":4,\"mode\":\"block\",\"description\":\"Begrenzt, wie viele finale Kandidat:innen in einer Kategorie vorbereitet werden.\"},{\"key\":\"max_candidate_appearances\",\"label\":\"Kandidaturen pro Person\",\"enabled\":true,\"limit\":2,\"mode\":\"warn\",\"description\":\"Warnt oder blockiert, wenn dieselbe Person in zu vielen Kategorien final auftaucht.\"},{\"key\":\"max_winner_placements\",\"label\":\"Gewinnerpl\\u00E4tze pro Person\",\"enabled\":true,\"limit\":1,\"mode\":\"block\",\"description\":\"Verhindert oder warnt, wenn dieselbe Person mehrfach als Gewinner:in gesetzt wird.\"},{\"key\":\"winner_requires_clip\",\"label\":\"Gewinner braucht Clip-Link\",\"enabled\":true,\"limit\":1,\"mode\":\"block\",\"description\":\"Verhindert oder warnt, wenn ein Gewinner ohne gepflegten YouTube-/Twitch-Clip gesetzt wird.\"}]" }); - migrationBuilder.CreateIndex( - name: "IX_ShowactApplications_SeasonId_Status", - table: "ShowactApplications", - columns: new[] { "SeasonId", "Status" }); + migrationBuilder.Sql(""" + CREATE INDEX IF NOT EXISTS "IX_ShowactApplications_SeasonId_Status" + ON "ShowactApplications" ("SeasonId", "Status"); - migrationBuilder.CreateIndex( - name: "IX_Sponsors_SeasonId_IsVisible_SortOrder", - table: "Sponsors", - columns: new[] { "SeasonId", "IsVisible", "SortOrder" }); + CREATE INDEX IF NOT EXISTS "IX_Sponsors_SeasonId_IsVisible_SortOrder" + ON "Sponsors" ("SeasonId", "IsVisible", "SortOrder"); + """); } /// protected override void Down(MigrationBuilder migrationBuilder) { - migrationBuilder.DropTable( - name: "ShowactApplications"); + migrationBuilder.Sql(""" + DROP TABLE IF EXISTS "ShowactApplications"; - migrationBuilder.DropTable( - name: "Sponsors"); + DROP TABLE IF EXISTS "Sponsors"; + """); - migrationBuilder.DropColumn( - name: "ClipAdminMenuVisible", - table: "SiteSettings"); + migrationBuilder.Sql(""" + ALTER TABLE "SiteSettings" + DROP COLUMN IF EXISTS "ClipAdminMenuVisible"; - migrationBuilder.DropColumn( - name: "ShowactApplicationDisabledMessage", - table: "SiteSettings"); + ALTER TABLE "SiteSettings" + DROP COLUMN IF EXISTS "ShowactApplicationDisabledMessage"; - migrationBuilder.DropColumn( - name: "ShowactApplicationsEnabled", - table: "SiteSettings"); + ALTER TABLE "SiteSettings" + DROP COLUMN IF EXISTS "ShowactApplicationsEnabled"; - migrationBuilder.DropColumn( - name: "ShowactsContent", - table: "SiteSettings"); + ALTER TABLE "SiteSettings" + DROP COLUMN IF EXISTS "ShowactsContent"; - migrationBuilder.DropColumn( - name: "ShowactsUrl", - table: "SiteSettings"); + ALTER TABLE "SiteSettings" + DROP COLUMN IF EXISTS "ShowactsUrl"; - migrationBuilder.DropColumn( - name: "SponsorsVisible", - table: "SiteSettings"); + ALTER TABLE "SiteSettings" + DROP COLUMN IF EXISTS "SponsorsVisible"; + """); migrationBuilder.UpdateData( table: "SiteSettings",