Refine admin workflows and team access
This commit is contained in:
+1471
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,135 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Backend.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddVoteBallotSubmitterUniqueIndex : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_VoteBallots_SeasonId",
|
||||
table: "VoteBallots");
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "TwitchAuthManagedByDatabase",
|
||||
table: "SiteSettings",
|
||||
type: "boolean",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "TwitchClientId",
|
||||
table: "SiteSettings",
|
||||
type: "character varying(120)",
|
||||
maxLength: 120,
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "TwitchClientSecret",
|
||||
table: "SiteSettings",
|
||||
type: "character varying(180)",
|
||||
maxLength: 180,
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "TwitchRedirectUri",
|
||||
table: "SiteSettings",
|
||||
type: "character varying(400)",
|
||||
maxLength: 400,
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "TwitchScope",
|
||||
table: "SiteSettings",
|
||||
type: "character varying(300)",
|
||||
maxLength: 300,
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "SiteSettings",
|
||||
keyColumn: "Id",
|
||||
keyValue: 1,
|
||||
columns: new[] { "TwitchAuthManagedByDatabase", "TwitchClientId", "TwitchClientSecret", "TwitchRedirectUri", "TwitchScope" },
|
||||
values: new object[] { false, "", "", "", "" });
|
||||
|
||||
migrationBuilder.Sql("""
|
||||
DELETE FROM "VoteEntries"
|
||||
WHERE "BallotId" IN (
|
||||
SELECT "Id"
|
||||
FROM (
|
||||
SELECT
|
||||
"Id",
|
||||
ROW_NUMBER() OVER (
|
||||
PARTITION BY "SeasonId", "SubmittedByTwitchId"
|
||||
ORDER BY "SubmittedAt" DESC, "Id" DESC
|
||||
) AS duplicate_rank
|
||||
FROM "VoteBallots"
|
||||
) ranked_ballots
|
||||
WHERE duplicate_rank > 1
|
||||
);
|
||||
|
||||
DELETE FROM "VoteBallots"
|
||||
WHERE "Id" IN (
|
||||
SELECT "Id"
|
||||
FROM (
|
||||
SELECT
|
||||
"Id",
|
||||
ROW_NUMBER() OVER (
|
||||
PARTITION BY "SeasonId", "SubmittedByTwitchId"
|
||||
ORDER BY "SubmittedAt" DESC, "Id" DESC
|
||||
) AS duplicate_rank
|
||||
FROM "VoteBallots"
|
||||
) ranked_ballots
|
||||
WHERE duplicate_rank > 1
|
||||
);
|
||||
""");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_VoteBallots_SeasonId_SubmittedByTwitchId",
|
||||
table: "VoteBallots",
|
||||
columns: new[] { "SeasonId", "SubmittedByTwitchId" },
|
||||
unique: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_VoteBallots_SeasonId_SubmittedByTwitchId",
|
||||
table: "VoteBallots");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "TwitchAuthManagedByDatabase",
|
||||
table: "SiteSettings");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "TwitchClientId",
|
||||
table: "SiteSettings");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "TwitchClientSecret",
|
||||
table: "SiteSettings");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "TwitchRedirectUri",
|
||||
table: "SiteSettings");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "TwitchScope",
|
||||
table: "SiteSettings");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_VoteBallots_SeasonId",
|
||||
table: "VoteBallots",
|
||||
column: "SeasonId");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -966,6 +966,29 @@ namespace Backend.Migrations
|
||||
.HasMaxLength(400)
|
||||
.HasColumnType("character varying(400)");
|
||||
|
||||
b.Property<bool>("TwitchAuthManagedByDatabase")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("TwitchClientId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(120)
|
||||
.HasColumnType("character varying(120)");
|
||||
|
||||
b.Property<string>("TwitchClientSecret")
|
||||
.IsRequired()
|
||||
.HasMaxLength(180)
|
||||
.HasColumnType("character varying(180)");
|
||||
|
||||
b.Property<string>("TwitchRedirectUri")
|
||||
.IsRequired()
|
||||
.HasMaxLength(400)
|
||||
.HasColumnType("character varying(400)");
|
||||
|
||||
b.Property<string>("TwitchScope")
|
||||
.IsRequired()
|
||||
.HasMaxLength(300)
|
||||
.HasColumnType("character varying(300)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("SiteSettings");
|
||||
@@ -999,7 +1022,12 @@ namespace Backend.Migrations
|
||||
RiskRulesJson = "[{\"key\":\"resubmitted_ballot\",\"label\":\"Ballot erneut gespeichert\",\"enabled\":true,\"threshold\":1,\"windowMinutes\":360,\"severity\":\"low\",\"description\":\"Erstellt einen Hinweis, wenn ein User sein Voting erneut speichert.\"},{\"key\":\"rapid_vote_updates\",\"label\":\"Voting-Burst\",\"enabled\":true,\"threshold\":3,\"windowMinutes\":10,\"severity\":\"high\",\"description\":\"Erstellt einen Hinweis, wenn ein User sehr schnell mehrere Voting-Aenderungen ausloest.\"},{\"key\":\"resubmitted_nomination\",\"label\":\"Nominierung erneut eingereicht\",\"enabled\":true,\"threshold\":1,\"windowMinutes\":360,\"severity\":\"low\",\"description\":\"Erstellt einen Hinweis, wenn ein User in derselben Kategorie erneut nominiert.\"},{\"key\":\"rapid_nomination_burst\",\"label\":\"Nominierungs-Burst\",\"enabled\":true,\"threshold\":10,\"windowMinutes\":10,\"severity\":\"high\",\"description\":\"Erstellt einen Hinweis, wenn ein User sehr viele Nominierungen in kurzer Zeit sendet.\"},{\"key\":\"duplicate_clip_submission\",\"label\":\"Doppelter Clip\",\"enabled\":true,\"threshold\":1,\"windowMinutes\":360,\"severity\":\"medium\",\"description\":\"Erstellt einen Hinweis, wenn ein User denselben Clip erneut einreicht.\"},{\"key\":\"rapid_clip_burst\",\"label\":\"Clip-Burst\",\"enabled\":true,\"threshold\":5,\"windowMinutes\":10,\"severity\":\"high\",\"description\":\"Erstellt einen Hinweis, wenn ein User sehr viele Clips in kurzer Zeit sendet.\"},{\"key\":\"rapid_login_ip\",\"label\":\"Login-Burst pro IP\",\"enabled\":true,\"threshold\":3,\"windowMinutes\":15,\"severity\":\"medium\",\"description\":\"Erstellt einen Hinweis, wenn mehrere neue Sessions von derselben IP entstehen.\"},{\"key\":\"rapid_demo_login_ip\",\"label\":\"Demo-Login-Burst pro IP\",\"enabled\":true,\"threshold\":3,\"windowMinutes\":15,\"severity\":\"medium\",\"description\":\"Erstellt einen Hinweis, wenn mehrere Demo-Admin-Sessions von derselben IP entstehen.\"}]",
|
||||
SocialLinksJson = "[{\"label\":\"Twitch\",\"platform\":\"twitch\",\"url\":\"https://twitch.tv/jayuhime\",\"icon\":\"twitch\",\"showOnHost\":true,\"showOnCommunity\":true},{\"label\":\"YouTube\",\"platform\":\"youtube\",\"url\":\"https://youtube.com/c/Jayuhime\",\"icon\":\"youtube\",\"showOnHost\":true,\"showOnCommunity\":true},{\"label\":\"X\",\"platform\":\"x\",\"url\":\"https://x.com/jayuhime\",\"icon\":\"x\",\"showOnHost\":true,\"showOnCommunity\":true},{\"label\":\"Instagram\",\"platform\":\"instagram\",\"url\":\"https://instagram.com/jayuhime\",\"icon\":\"instagram\",\"showOnHost\":true,\"showOnCommunity\":true},{\"label\":\"Discord\",\"platform\":\"discord\",\"url\":\"https://discord.gg/jayuhime\",\"icon\":\"discord\",\"showOnHost\":true,\"showOnCommunity\":true}]",
|
||||
SponsorsContent = "Sponsoren & Partner\nHier koennen Sponsor:innen, Medienpartner, Community-Partner und Supporter des VTuber Star Awards vorgestellt werden.\n\nPartner werden im Rahmen der Show und auf den oeffentlichen Kontaktflaechen genannt, sobald sie final bestaetigt sind.",
|
||||
SponsorsUrl = "https://vtuber-star-awards.de/partner"
|
||||
SponsorsUrl = "https://vtuber-star-awards.de/partner",
|
||||
TwitchAuthManagedByDatabase = false,
|
||||
TwitchClientId = "",
|
||||
TwitchClientSecret = "",
|
||||
TwitchRedirectUri = "",
|
||||
TwitchScope = ""
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1011,14 +1039,6 @@ namespace Backend.Migrations
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTimeOffset>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("CreatedByTwitchId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(120)
|
||||
.HasColumnType("character varying(120)");
|
||||
|
||||
b.Property<string>("BoundTwitchDisplayName")
|
||||
.HasMaxLength(120)
|
||||
.HasColumnType("character varying(120)");
|
||||
@@ -1027,6 +1047,14 @@ namespace Backend.Migrations
|
||||
.HasMaxLength(120)
|
||||
.HasColumnType("character varying(120)");
|
||||
|
||||
b.Property<DateTimeOffset>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("CreatedByTwitchId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(120)
|
||||
.HasColumnType("character varying(120)");
|
||||
|
||||
b.Property<string>("DisplayName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(120)
|
||||
@@ -1076,10 +1104,10 @@ namespace Backend.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Login")
|
||||
b.HasIndex("BoundTwitchUserId")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("BoundTwitchUserId")
|
||||
b.HasIndex("Login")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("TeamMembers");
|
||||
@@ -1197,7 +1225,8 @@ namespace Backend.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("SeasonId");
|
||||
b.HasIndex("SeasonId", "SubmittedByTwitchId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("VoteBallots");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user