18b61bed52
- Widen AdminCandidateEditorModal to size lg for better readability - Rename "Clip-Compilation" section to "Clip / Compilation", update copy to reflect single clips too, drop upload hint and Clip-Plattform field, rename label to "Link" - Fix NativeSelect dropdown clipping inside overflow-y-auto modals by teleporting the menu to body with fixed positioning, flip-up logic, and dynamic maxHeight capped to viewport - Add ClipAdminMenuVisible setting (backend domain, contracts, endpoint, migration) with matching frontend types, defaults, form wiring, and toggle in the Clip-Workflow modal — hides the Clips nav item from the admin sidebar when disabled Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
320 lines
14 KiB
C#
320 lines
14 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace Backend.Data;
|
|
|
|
public static class OperationalTablesBootstrapper
|
|
{
|
|
public static Task EnsureAsync(AwardsDbContext db) =>
|
|
db.Database.ExecuteSqlRawAsync(
|
|
"""
|
|
ALTER TABLE "UserSessions"
|
|
ADD COLUMN IF NOT EXISTS "CreatedFromIp" character varying(80) NOT NULL DEFAULT '';
|
|
|
|
ALTER TABLE "UserSessions"
|
|
ADD COLUMN IF NOT EXISTS "UserAgent" character varying(400) NOT NULL DEFAULT '';
|
|
|
|
ALTER TABLE "SiteSettings"
|
|
ADD COLUMN IF NOT EXISTS "RiskRulesJson" text NOT NULL DEFAULT '[]';
|
|
|
|
ALTER TABLE "SiteSettings"
|
|
ADD COLUMN IF NOT EXISTS "WorkflowRulesJson" text NOT NULL DEFAULT '[]';
|
|
|
|
ALTER TABLE "SiteSettings"
|
|
ADD COLUMN IF NOT EXISTS "NominationLinkBlacklistJson" text NOT NULL DEFAULT '[]';
|
|
|
|
ALTER TABLE "SiteSettings"
|
|
ADD COLUMN IF NOT EXISTS "ClipSubmissionsEnabled" boolean NOT NULL DEFAULT false;
|
|
|
|
ALTER TABLE "SiteSettings"
|
|
ADD COLUMN IF NOT EXISTS "ClipReviewEnabled" boolean NOT NULL DEFAULT true;
|
|
|
|
ALTER TABLE "SiteSettings"
|
|
ADD COLUMN IF NOT EXISTS "ClipSubmissionDisabledMessage" character varying(240) NOT NULL DEFAULT 'Clip-Einreichungen sind aktuell geschlossen.';
|
|
|
|
ALTER TABLE "SiteSettings"
|
|
ADD COLUMN IF NOT EXISTS "ShowactApplicationsEnabled" boolean NOT NULL DEFAULT false;
|
|
|
|
ALTER TABLE "SiteSettings"
|
|
ADD COLUMN IF NOT EXISTS "ShowactApplicationDisabledMessage" character varying(240) NOT NULL DEFAULT 'Showact-Bewerbungen sind aktuell geschlossen.';
|
|
|
|
ALTER TABLE "SiteSettings"
|
|
ADD COLUMN IF NOT EXISTS "SponsorsVisible" boolean NOT NULL DEFAULT true;
|
|
|
|
ALTER TABLE "SiteSettings"
|
|
ADD COLUMN IF NOT EXISTS "TwitchAuthManagedByDatabase" boolean NOT NULL DEFAULT false;
|
|
|
|
ALTER TABLE "SiteSettings"
|
|
ADD COLUMN IF NOT EXISTS "TwitchClientId" character varying(120) NOT NULL DEFAULT '';
|
|
|
|
ALTER TABLE "SiteSettings"
|
|
ADD COLUMN IF NOT EXISTS "TwitchClientSecret" character varying(180) NOT NULL DEFAULT '';
|
|
|
|
ALTER TABLE "SiteSettings"
|
|
ADD COLUMN IF NOT EXISTS "TwitchRedirectUri" character varying(400) NOT NULL DEFAULT '';
|
|
|
|
ALTER TABLE "SiteSettings"
|
|
ADD COLUMN IF NOT EXISTS "TwitchScope" character varying(300) NOT NULL DEFAULT '';
|
|
|
|
ALTER TABLE "SiteSettings"
|
|
ADD COLUMN IF NOT EXISTS "ImprintContent" text NOT NULL DEFAULT '';
|
|
|
|
ALTER TABLE "SiteSettings"
|
|
ADD COLUMN IF NOT EXISTS "ContactContent" text NOT NULL DEFAULT '';
|
|
|
|
ALTER TABLE "SiteSettings"
|
|
ADD COLUMN IF NOT EXISTS "SponsorsContent" text NOT NULL DEFAULT '';
|
|
|
|
ALTER TABLE "SiteSettings"
|
|
ADD COLUMN IF NOT EXISTS "ShowactsUrl" character varying(400) NOT NULL DEFAULT '';
|
|
|
|
ALTER TABLE "SiteSettings"
|
|
ADD COLUMN IF NOT EXISTS "ShowactsContent" text NOT NULL DEFAULT '';
|
|
|
|
CREATE TABLE IF NOT EXISTS "RiskFlags" (
|
|
"Id" integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
"SeasonId" integer NULL,
|
|
"TwitchUserId" character varying(120) NULL,
|
|
"Source" character varying(80) NOT NULL,
|
|
"Type" character varying(80) NOT NULL,
|
|
"Severity" character varying(20) NOT NULL,
|
|
"Status" character varying(20) NOT NULL,
|
|
"Summary" character varying(240) NOT NULL,
|
|
"CreatedFromIp" character varying(80) NOT NULL,
|
|
"UserAgent" character varying(400) NOT NULL,
|
|
"MetadataJson" text NOT NULL,
|
|
"ReviewNote" character varying(500) NULL,
|
|
"ReviewedByTwitchId" character varying(120) NULL,
|
|
"CreatedAt" timestamp with time zone NOT NULL,
|
|
"ReviewedAt" timestamp with time zone NULL
|
|
);
|
|
|
|
ALTER TABLE "RiskFlags"
|
|
ADD COLUMN IF NOT EXISTS "ReviewNote" character varying(500) NULL;
|
|
|
|
CREATE INDEX IF NOT EXISTS "IX_RiskFlags_Status_CreatedAt"
|
|
ON "RiskFlags" ("Status", "CreatedAt" DESC);
|
|
|
|
CREATE INDEX IF NOT EXISTS "IX_RiskFlags_SeasonId"
|
|
ON "RiskFlags" ("SeasonId");
|
|
|
|
CREATE TABLE IF NOT EXISTS "AdminAuditEntries" (
|
|
"Id" integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
"AdminTwitchUserId" character varying(120) NOT NULL,
|
|
"ActionType" character varying(80) NOT NULL,
|
|
"EntityType" character varying(80) NOT NULL,
|
|
"EntityId" character varying(120) NOT NULL,
|
|
"Summary" character varying(240) NOT NULL,
|
|
"MetadataJson" text NOT NULL,
|
|
"CreatedFromIp" character varying(80) NOT NULL DEFAULT '',
|
|
"UserAgent" character varying(400) NOT NULL DEFAULT '',
|
|
"CreatedAt" timestamp with time zone NOT NULL
|
|
);
|
|
|
|
ALTER TABLE "AdminAuditEntries"
|
|
ADD COLUMN IF NOT EXISTS "CreatedFromIp" character varying(80) NOT NULL DEFAULT '';
|
|
|
|
ALTER TABLE "AdminAuditEntries"
|
|
ADD COLUMN IF NOT EXISTS "UserAgent" character varying(400) NOT NULL DEFAULT '';
|
|
|
|
CREATE INDEX IF NOT EXISTS "IX_AdminAuditEntries_CreatedAt"
|
|
ON "AdminAuditEntries" ("CreatedAt" DESC);
|
|
|
|
CREATE TABLE IF NOT EXISTS "ClipSubmissions" (
|
|
"Id" integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
"SeasonId" integer NOT NULL,
|
|
"CategoryId" integer NULL,
|
|
"SubmittedByTwitchId" character varying(120) NOT NULL,
|
|
"ClipUrl" character varying(500) NOT NULL,
|
|
"Title" character varying(200) NOT NULL,
|
|
"Creator" character varying(120) NOT NULL,
|
|
"Platform" character varying(40) NOT NULL,
|
|
"Status" character varying(20) NOT NULL,
|
|
"CreatedFromIp" character varying(80) NOT NULL,
|
|
"CreatedAt" timestamp with time zone NOT NULL
|
|
);
|
|
|
|
ALTER TABLE "ClipSubmissions"
|
|
ADD COLUMN IF NOT EXISTS "CandidateId" integer NULL;
|
|
|
|
ALTER TABLE "ClipSubmissions"
|
|
ADD COLUMN IF NOT EXISTS "ReviewNote" character varying(500) NULL;
|
|
|
|
ALTER TABLE "ClipSubmissions"
|
|
ADD COLUMN IF NOT EXISTS "ReviewedByTwitchId" character varying(120) NULL;
|
|
|
|
ALTER TABLE "ClipSubmissions"
|
|
ADD COLUMN IF NOT EXISTS "ReviewedAt" timestamp with time zone NULL;
|
|
|
|
CREATE INDEX IF NOT EXISTS "IX_ClipSubmissions_SeasonId_Status"
|
|
ON "ClipSubmissions" ("SeasonId", "Status");
|
|
|
|
CREATE INDEX IF NOT EXISTS "IX_ClipSubmissions_CandidateId"
|
|
ON "ClipSubmissions" ("CandidateId");
|
|
|
|
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
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS "IX_ShowactApplications_SeasonId_Status"
|
|
ON "ShowactApplications" ("SeasonId", "Status");
|
|
|
|
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
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS "IX_Sponsors_SeasonId_IsVisible_SortOrder"
|
|
ON "Sponsors" ("SeasonId", "IsVisible", "SortOrder");
|
|
|
|
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 $$;
|
|
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (
|
|
SELECT 1
|
|
FROM pg_constraint
|
|
WHERE conname = 'FK_ClipSubmissions_Candidates_CandidateId'
|
|
) THEN
|
|
ALTER TABLE "ClipSubmissions"
|
|
ADD CONSTRAINT "FK_ClipSubmissions_Candidates_CandidateId"
|
|
FOREIGN KEY ("CandidateId") REFERENCES "Candidates" ("Id")
|
|
ON DELETE SET NULL;
|
|
END IF;
|
|
END $$;
|
|
|
|
ALTER TABLE "Nominations"
|
|
ADD COLUMN IF NOT EXISTS "StreamUrl" character varying(300) NULL;
|
|
|
|
ALTER TABLE "Candidates"
|
|
ADD COLUMN IF NOT EXISTS "AcceptanceStatus" character varying(30) NOT NULL DEFAULT 'open';
|
|
|
|
ALTER TABLE "Candidates"
|
|
ADD COLUMN IF NOT EXISTS "AcceptanceNote" character varying(500) NULL;
|
|
|
|
ALTER TABLE "Candidates"
|
|
ADD COLUMN IF NOT EXISTS "ClipCompilationUrl" character varying(500) NULL;
|
|
|
|
ALTER TABLE "Candidates"
|
|
ADD COLUMN IF NOT EXISTS "ClipCompilationTitle" character varying(200) NULL;
|
|
|
|
ALTER TABLE "Candidates"
|
|
ADD COLUMN IF NOT EXISTS "ClipCompilationPlatform" character varying(40) NULL;
|
|
|
|
ALTER TABLE "Candidates"
|
|
ADD COLUMN IF NOT EXISTS "ClipEmbedStatus" character varying(30) NOT NULL DEFAULT 'unchecked';
|
|
|
|
ALTER TABLE "Nominations"
|
|
ADD COLUMN IF NOT EXISTS "Status" character varying(20) NOT NULL DEFAULT 'pending';
|
|
|
|
ALTER TABLE "Nominations"
|
|
ADD COLUMN IF NOT EXISTS "ReviewNote" character varying(500) NULL;
|
|
|
|
ALTER TABLE "Nominations"
|
|
ADD COLUMN IF NOT EXISTS "ReviewedByTwitchId" character varying(120) NULL;
|
|
|
|
ALTER TABLE "Nominations"
|
|
ADD COLUMN IF NOT EXISTS "ReviewedAt" timestamp with time zone NULL;
|
|
|
|
CREATE INDEX IF NOT EXISTS "IX_Nominations_SeasonId_Status"
|
|
ON "Nominations" ("SeasonId", "Status");
|
|
|
|
CREATE TABLE IF NOT EXISTS "TeamMembers" (
|
|
"Id" integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
"Login" character varying(80) NOT NULL,
|
|
"DisplayName" character varying(120) NOT NULL,
|
|
"Role" character varying(40) NOT NULL,
|
|
"PasswordHash" character varying(120) NOT NULL,
|
|
"PasswordSalt" character varying(80) NOT NULL,
|
|
"BoundTwitchUserId" character varying(120) NULL,
|
|
"BoundTwitchDisplayName" character varying(120) NULL,
|
|
"MustChangePassword" boolean NOT NULL,
|
|
"IsActive" boolean NOT NULL,
|
|
"CreatedByTwitchId" character varying(120) NOT NULL,
|
|
"UpdatedByTwitchId" character varying(120) NULL,
|
|
"CreatedAt" timestamp with time zone NOT NULL,
|
|
"UpdatedAt" timestamp with time zone NULL,
|
|
"LastLoginAt" timestamp with time zone NULL,
|
|
"TwitchBoundAt" timestamp with time zone NULL,
|
|
"PasswordResetAt" timestamp with time zone NULL
|
|
);
|
|
|
|
ALTER TABLE "TeamMembers"
|
|
ADD COLUMN IF NOT EXISTS "BoundTwitchUserId" character varying(120) NULL;
|
|
|
|
ALTER TABLE "TeamMembers"
|
|
ADD COLUMN IF NOT EXISTS "BoundTwitchDisplayName" character varying(120) NULL;
|
|
|
|
ALTER TABLE "TeamMembers"
|
|
ADD COLUMN IF NOT EXISTS "TwitchBoundAt" timestamp with time zone NULL;
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS "IX_TeamMembers_Login"
|
|
ON "TeamMembers" ("Login");
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS "IX_TeamMembers_BoundTwitchUserId"
|
|
ON "TeamMembers" ("BoundTwitchUserId")
|
|
WHERE "BoundTwitchUserId" IS NOT NULL;
|
|
|
|
CREATE TABLE IF NOT EXISTS "TeamRolePermissions" (
|
|
"Id" integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
"Role" character varying(40) NOT NULL,
|
|
"PermissionsJson" text NOT NULL,
|
|
"UpdatedByTwitchId" character varying(120) NOT NULL,
|
|
"UpdatedAt" timestamp with time zone NOT NULL
|
|
);
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS "IX_TeamRolePermissions_Role"
|
|
ON "TeamRolePermissions" ("Role");
|
|
""");
|
|
}
|