b53c7fb736
Features: - Category viewer ranges + subcategory templates (admin group modal, tree workspace) - Nomination enrichment via TwitchTracker API (NominationEnrichmentService, TwitchTrackerViewerStatsProvider) with admin tracking rules editor - Nomination group tracker: CategoryGroupName as primary identifier, CategoryId stays as nullable legacy field; StreamerIdentity table - Dynamic showact application form builder (AdminShowactFormBuilder, ShowactApplicationSchedule) - Session idle timeout setting (AdminSessionTimeoutCard) - Share URLs for X and Discord (SiteSettings, public extras) - Workflow rules now stored per season (falls back to global SiteSettings) - New admin routes: settings/access, settings/workflows, tracking-rules - New admin review workspace with subcategory tabs - AdminCategoriesView rebuilt with group/subcategory modals Migrations (all additive): - AddShareUrls, AddShowactDynamicForm, AddCategoryViewerRanges, AddSessionIdleTimeoutSettings, AddSeasonSubcategoryTemplates, AddNominationGroupTrackerIdentity, AddShowactApplicationSchedule, AddSeasonWorkflowRulesJson Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
472 lines
20 KiB
C#
472 lines
20 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 "TrackingRulesJson" text NOT NULL DEFAULT '[]';
|
|
|
|
ALTER TABLE "SiteSettings"
|
|
ADD COLUMN IF NOT EXISTS "ViewerStatsProviderBaseUrl" character varying(400) NOT NULL DEFAULT '';
|
|
|
|
ALTER TABLE "SiteSettings"
|
|
ADD COLUMN IF NOT EXISTS "TrackingReviewNotes" 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 "ShowactApplicationStartsAt" date NULL;
|
|
|
|
ALTER TABLE "SiteSettings"
|
|
ADD COLUMN IF NOT EXISTS "ShowactApplicationEndsAt" date NULL;
|
|
|
|
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 "Nominations"
|
|
ADD COLUMN IF NOT EXISTS "HoursStreamed" integer NULL;
|
|
|
|
ALTER TABLE "Nominations"
|
|
ADD COLUMN IF NOT EXISTS "HoursWatched" integer NULL;
|
|
|
|
ALTER TABLE "Nominations"
|
|
ADD COLUMN IF NOT EXISTS "PeakViewers" integer NULL;
|
|
|
|
ALTER TABLE "Nominations"
|
|
ADD COLUMN IF NOT EXISTS "FollowersGained" integer NULL;
|
|
|
|
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 "SessionIdleTimeoutHours" integer NOT NULL DEFAULT 3;
|
|
|
|
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 '';
|
|
|
|
ALTER TABLE "Seasons"
|
|
ADD COLUMN IF NOT EXISTS "SubcategoryTemplatesJson" 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 "Categories"
|
|
ADD COLUMN IF NOT EXISTS "ViewerRangeMin" integer NULL;
|
|
|
|
ALTER TABLE "Categories"
|
|
ADD COLUMN IF NOT EXISTS "ViewerRangeMax" integer NULL;
|
|
|
|
CREATE TABLE IF NOT EXISTS "StreamerIdentities" (
|
|
"Id" integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
"Platform" character varying(40) NOT NULL,
|
|
"Login" character varying(120) NOT NULL,
|
|
"NormalizedKey" character varying(180) NOT NULL,
|
|
"DisplayName" character varying(120) NOT NULL,
|
|
"ProfileUrl" character varying(500) NULL,
|
|
"LastResolvedAt" timestamp with time zone NULL
|
|
);
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS "IX_StreamerIdentities_NormalizedKey"
|
|
ON "StreamerIdentities" ("NormalizedKey");
|
|
|
|
ALTER TABLE "Candidates"
|
|
ADD COLUMN IF NOT EXISTS "StreamerIdentityId" integer NULL;
|
|
|
|
ALTER TABLE "Candidates"
|
|
ADD COLUMN IF NOT EXISTS "NominationTally" integer NOT NULL DEFAULT 0;
|
|
|
|
CREATE INDEX IF NOT EXISTS "IX_Candidates_StreamerIdentityId"
|
|
ON "Candidates" ("StreamerIdentityId");
|
|
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (
|
|
SELECT 1
|
|
FROM pg_constraint
|
|
WHERE conname = 'FK_Candidates_StreamerIdentities_StreamerIdentityId'
|
|
) THEN
|
|
ALTER TABLE "Candidates"
|
|
ADD CONSTRAINT "FK_Candidates_StreamerIdentities_StreamerIdentityId"
|
|
FOREIGN KEY ("StreamerIdentityId") REFERENCES "StreamerIdentities" ("Id");
|
|
END IF;
|
|
END $$;
|
|
|
|
ALTER TABLE "Nominations"
|
|
ALTER COLUMN "CategoryId" DROP NOT NULL;
|
|
|
|
ALTER TABLE "Nominations"
|
|
ADD COLUMN IF NOT EXISTS "CategoryGroupName" character varying(80) NOT NULL DEFAULT '';
|
|
|
|
UPDATE "Nominations" n
|
|
SET "CategoryGroupName" = c."GroupName"
|
|
FROM "Categories" c
|
|
WHERE n."CategoryId" = c."Id"
|
|
AND COALESCE(n."CategoryGroupName", '') = '';
|
|
|
|
ALTER TABLE "Nominations"
|
|
ADD COLUMN IF NOT EXISTS "StreamerIdentityId" integer NULL;
|
|
|
|
ALTER TABLE "Nominations"
|
|
ADD COLUMN IF NOT EXISTS "SuggestedCategoryId" integer NULL;
|
|
|
|
ALTER TABLE "Nominations"
|
|
ADD COLUMN IF NOT EXISTS "ResolvedChannel" character varying(120) NULL;
|
|
|
|
ALTER TABLE "Nominations"
|
|
ADD COLUMN IF NOT EXISTS "ResolvedPlatform" character varying(40) NULL;
|
|
|
|
ALTER TABLE "Nominations"
|
|
ADD COLUMN IF NOT EXISTS "AvgViewers" integer NULL;
|
|
|
|
ALTER TABLE "Nominations"
|
|
ADD COLUMN IF NOT EXISTS "TrackerStatus" character varying(40) NOT NULL DEFAULT 'pending';
|
|
|
|
ALTER TABLE "Nominations"
|
|
ADD COLUMN IF NOT EXISTS "TrackerCheckedAt" timestamp with time zone NULL;
|
|
|
|
ALTER TABLE "Nominations"
|
|
ADD COLUMN IF NOT EXISTS "TrackingReviewStatus" character varying(30) NOT NULL DEFAULT 'clear';
|
|
|
|
ALTER TABLE "Nominations"
|
|
ADD COLUMN IF NOT EXISTS "TrackingFlagsJson" text NOT NULL DEFAULT '[]';
|
|
|
|
ALTER TABLE "Nominations"
|
|
ADD COLUMN IF NOT EXISTS "TrackingReviewNote" character varying(1000) NULL;
|
|
|
|
ALTER TABLE "Nominations"
|
|
ADD COLUMN IF NOT EXISTS "TrackingReviewedByTwitchId" character varying(120) NULL;
|
|
|
|
ALTER TABLE "Nominations"
|
|
ADD COLUMN IF NOT EXISTS "TrackingReviewedAt" timestamp with time zone NULL;
|
|
|
|
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 INDEX IF NOT EXISTS "IX_Nominations_SeasonId_CategoryGroupName_Status"
|
|
ON "Nominations" ("SeasonId", "CategoryGroupName", "Status");
|
|
|
|
CREATE INDEX IF NOT EXISTS "IX_Nominations_SeasonId_StreamerIdentityId_CategoryGroupName"
|
|
ON "Nominations" ("SeasonId", "StreamerIdentityId", "CategoryGroupName");
|
|
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (
|
|
SELECT 1
|
|
FROM pg_constraint
|
|
WHERE conname = 'FK_Nominations_StreamerIdentities_StreamerIdentityId'
|
|
) THEN
|
|
ALTER TABLE "Nominations"
|
|
ADD CONSTRAINT "FK_Nominations_StreamerIdentities_StreamerIdentityId"
|
|
FOREIGN KEY ("StreamerIdentityId") REFERENCES "StreamerIdentities" ("Id");
|
|
END IF;
|
|
|
|
IF NOT EXISTS (
|
|
SELECT 1
|
|
FROM pg_constraint
|
|
WHERE conname = 'FK_Nominations_Categories_SuggestedCategoryId'
|
|
) THEN
|
|
ALTER TABLE "Nominations"
|
|
ADD CONSTRAINT "FK_Nominations_Categories_SuggestedCategoryId"
|
|
FOREIGN KEY ("SuggestedCategoryId") REFERENCES "Categories" ("Id")
|
|
ON DELETE SET NULL;
|
|
END IF;
|
|
END $$;
|
|
|
|
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");
|
|
""");
|
|
}
|