diff --git a/Modix.Data/Migrations/20240326234009_RemoveDeletedFeatures.Designer.cs b/Modix.Data/Migrations/20240326234009_RemoveDeletedFeatures.Designer.cs
new file mode 100644
index 000000000..1870df911
--- /dev/null
+++ b/Modix.Data/Migrations/20240326234009_RemoveDeletedFeatures.Designer.cs
@@ -0,0 +1,1172 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Modix.Data;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace Modix.Data.Migrations
+{
+ [DbContext(typeof(ModixContext))]
+ [Migration("20240326234009_RemoveDeletedFeatures")]
+ partial class RemoveDeletedFeatures
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "8.0.3")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseSerialColumns(modelBuilder);
+
+ modelBuilder.Entity("Modix.Data.Models.Core.ClaimMappingEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseSerialColumn(b.Property("Id"));
+
+ b.Property("Claim")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("CreateActionId")
+ .HasColumnType("bigint");
+
+ b.Property("DeleteActionId")
+ .HasColumnType("bigint");
+
+ b.Property("GuildId")
+ .HasColumnType("bigint");
+
+ b.Property("RoleId")
+ .HasColumnType("bigint");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("UserId")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreateActionId")
+ .IsUnique();
+
+ b.HasIndex("DeleteActionId")
+ .IsUnique();
+
+ b.ToTable("ClaimMappings");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Core.ConfigurationActionEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseSerialColumn(b.Property("Id"));
+
+ b.Property("ClaimMappingId")
+ .HasColumnType("bigint");
+
+ b.Property("Created")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("CreatedById")
+ .HasColumnType("bigint");
+
+ b.Property("DesignatedChannelMappingId")
+ .HasColumnType("bigint");
+
+ b.Property("DesignatedRoleMappingId")
+ .HasColumnType("bigint");
+
+ b.Property("GuildId")
+ .HasColumnType("bigint");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ClaimMappingId");
+
+ b.HasIndex("DesignatedChannelMappingId");
+
+ b.HasIndex("DesignatedRoleMappingId");
+
+ b.HasIndex("GuildId", "CreatedById");
+
+ b.ToTable("ConfigurationActions");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Core.DesignatedChannelMappingEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseSerialColumn(b.Property("Id"));
+
+ b.Property("ChannelId")
+ .HasColumnType("bigint");
+
+ b.Property("CreateActionId")
+ .HasColumnType("bigint");
+
+ b.Property("DeleteActionId")
+ .HasColumnType("bigint");
+
+ b.Property("GuildId")
+ .HasColumnType("bigint");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ChannelId");
+
+ b.HasIndex("CreateActionId")
+ .IsUnique();
+
+ b.HasIndex("DeleteActionId")
+ .IsUnique();
+
+ b.ToTable("DesignatedChannelMappings");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Core.DesignatedRoleMappingEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseSerialColumn(b.Property("Id"));
+
+ b.Property("CreateActionId")
+ .HasColumnType("bigint");
+
+ b.Property("DeleteActionId")
+ .HasColumnType("bigint");
+
+ b.Property("GuildId")
+ .HasColumnType("bigint");
+
+ b.Property("RoleId")
+ .HasColumnType("bigint");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreateActionId")
+ .IsUnique();
+
+ b.HasIndex("DeleteActionId")
+ .IsUnique();
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("DesignatedRoleMappings");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Core.GuildChannelEntity", b =>
+ {
+ b.Property("ChannelId")
+ .HasColumnType("bigint");
+
+ b.Property("GuildId")
+ .HasColumnType("bigint");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("ParentChannelId")
+ .HasColumnType("bigint");
+
+ b.HasKey("ChannelId");
+
+ b.ToTable("GuildChannels");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Core.GuildRoleEntity", b =>
+ {
+ b.Property("RoleId")
+ .HasColumnType("bigint");
+
+ b.Property("GuildId")
+ .HasColumnType("bigint");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Position")
+ .HasColumnType("integer");
+
+ b.HasKey("RoleId");
+
+ b.ToTable("GuildRoles");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Core.GuildUserEntity", b =>
+ {
+ b.Property("GuildId")
+ .HasColumnType("bigint");
+
+ b.Property("UserId")
+ .HasColumnType("bigint");
+
+ b.Property("FirstSeen")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("LastSeen")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Nickname")
+ .HasColumnType("text");
+
+ b.HasKey("GuildId", "UserId");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("GuildUsers");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Core.MessageContentPatternEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseSerialColumn(b.Property("Id"));
+
+ b.Property("GuildId")
+ .HasColumnType("bigint");
+
+ b.Property("Pattern")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("PatternType")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("GuildId", "Pattern")
+ .IsUnique();
+
+ b.ToTable("MessageContentPatterns");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Core.MessageEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("bigint");
+
+ b.Property("AuthorId")
+ .HasColumnType("bigint");
+
+ b.Property("ChannelId")
+ .HasColumnType("bigint");
+
+ b.Property("GuildId")
+ .HasColumnType("bigint");
+
+ b.Property("StarboardEntryId")
+ .HasColumnType("bigint");
+
+ b.Property("Timestamp")
+ .HasColumnType("timestamp with time zone");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Timestamp");
+
+ b.HasIndex("GuildId", "AuthorId");
+
+ b.HasIndex("ChannelId", "Timestamp", "AuthorId");
+
+ b.ToTable("Messages");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Core.UserEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("bigint");
+
+ b.Property("Discriminator")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Username")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Users");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Emoji.EmojiEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseSerialColumn(b.Property("Id"));
+
+ b.Property("ChannelId")
+ .HasColumnType("bigint");
+
+ b.Property("EmojiId")
+ .HasColumnType("bigint");
+
+ b.Property("EmojiName")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("GuildId")
+ .HasColumnType("bigint");
+
+ b.Property("IsAnimated")
+ .HasColumnType("boolean");
+
+ b.Property("MessageId")
+ .HasColumnType("bigint");
+
+ b.Property("Timestamp")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("UsageType")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("UserId")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("EmojiId");
+
+ b.HasIndex("EmojiName");
+
+ b.HasIndex("GuildId");
+
+ b.HasIndex("MessageId");
+
+ b.HasIndex("Timestamp");
+
+ b.HasIndex("UsageType");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("Emoji");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Moderation.DeletedMessageBatchEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseSerialColumn(b.Property("Id"));
+
+ b.Property("CreateActionId")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreateActionId")
+ .IsUnique();
+
+ b.ToTable("DeletedMessageBatches");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Moderation.DeletedMessageEntity", b =>
+ {
+ b.Property("MessageId")
+ .HasColumnType("bigint");
+
+ b.Property("AuthorId")
+ .HasColumnType("bigint");
+
+ b.Property("BatchId")
+ .HasColumnType("bigint");
+
+ b.Property("ChannelId")
+ .HasColumnType("bigint");
+
+ b.Property("Content")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("CreateActionId")
+ .HasColumnType("bigint");
+
+ b.Property("GuildId")
+ .HasColumnType("bigint");
+
+ b.Property("Reason")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("MessageId");
+
+ b.HasIndex("BatchId");
+
+ b.HasIndex("ChannelId");
+
+ b.HasIndex("CreateActionId")
+ .IsUnique();
+
+ b.HasIndex("GuildId", "AuthorId");
+
+ b.ToTable("DeletedMessages");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Moderation.InfractionEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseSerialColumn(b.Property("Id"));
+
+ b.Property("CreateActionId")
+ .HasColumnType("bigint");
+
+ b.Property("DeleteActionId")
+ .HasColumnType("bigint");
+
+ b.Property("Duration")
+ .HasColumnType("interval");
+
+ b.Property("GuildId")
+ .HasColumnType("bigint");
+
+ b.Property("Reason")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("RescindActionId")
+ .HasColumnType("bigint");
+
+ b.Property("RescindReason")
+ .HasColumnType("text");
+
+ b.Property("SubjectId")
+ .HasColumnType("bigint");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("UpdateActionId")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreateActionId")
+ .IsUnique();
+
+ b.HasIndex("DeleteActionId")
+ .IsUnique();
+
+ b.HasIndex("RescindActionId")
+ .IsUnique();
+
+ b.HasIndex("UpdateActionId")
+ .IsUnique();
+
+ b.HasIndex("GuildId", "SubjectId");
+
+ b.ToTable("Infractions");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Moderation.ModerationActionEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseSerialColumn(b.Property("Id"));
+
+ b.Property("Created")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("CreatedById")
+ .HasColumnType("bigint");
+
+ b.Property("DeletedMessageBatchId")
+ .HasColumnType("bigint");
+
+ b.Property("DeletedMessageId")
+ .HasColumnType("bigint");
+
+ b.Property("GuildId")
+ .HasColumnType("bigint");
+
+ b.Property("InfractionId")
+ .HasColumnType("bigint");
+
+ b.Property("OriginalInfractionReason")
+ .HasColumnType("text");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DeletedMessageBatchId");
+
+ b.HasIndex("DeletedMessageId");
+
+ b.HasIndex("InfractionId");
+
+ b.HasIndex("GuildId", "CreatedById");
+
+ b.ToTable("ModerationActions");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Promotions.PromotionActionEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseSerialColumn(b.Property("Id"));
+
+ b.Property("CampaignId")
+ .HasColumnType("bigint");
+
+ b.Property("Created")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("CreatedById")
+ .HasColumnType("bigint");
+
+ b.Property("GuildId")
+ .HasColumnType("bigint");
+
+ b.Property("NewCommentId")
+ .HasColumnType("bigint");
+
+ b.Property("OldCommentId")
+ .HasColumnType("bigint");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CampaignId");
+
+ b.HasIndex("NewCommentId")
+ .IsUnique();
+
+ b.HasIndex("OldCommentId")
+ .IsUnique();
+
+ b.HasIndex("GuildId", "CreatedById");
+
+ b.ToTable("PromotionActions");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Promotions.PromotionCampaignEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseSerialColumn(b.Property("Id"));
+
+ b.Property("CloseActionId")
+ .HasColumnType("bigint");
+
+ b.Property("CreateActionId")
+ .HasColumnType("bigint");
+
+ b.Property("GuildId")
+ .HasColumnType("bigint");
+
+ b.Property("Outcome")
+ .HasColumnType("text");
+
+ b.Property("SubjectId")
+ .HasColumnType("bigint");
+
+ b.Property("TargetRoleId")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CloseActionId")
+ .IsUnique();
+
+ b.HasIndex("CreateActionId")
+ .IsUnique();
+
+ b.HasIndex("GuildId");
+
+ b.HasIndex("Outcome");
+
+ b.HasIndex("SubjectId");
+
+ b.HasIndex("TargetRoleId");
+
+ b.HasIndex("GuildId", "SubjectId");
+
+ b.ToTable("PromotionCampaigns");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Promotions.PromotionCommentEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseSerialColumn(b.Property("Id"));
+
+ b.Property("CampaignId")
+ .HasColumnType("bigint");
+
+ b.Property("Content")
+ .HasColumnType("text");
+
+ b.Property("CreateActionId")
+ .HasColumnType("bigint");
+
+ b.Property("ModifyActionId")
+ .HasColumnType("bigint");
+
+ b.Property("Sentiment")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CampaignId");
+
+ b.HasIndex("CreateActionId")
+ .IsUnique();
+
+ b.HasIndex("ModifyActionId")
+ .IsUnique();
+
+ b.ToTable("PromotionComments");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Tags.TagActionEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseSerialColumn(b.Property("Id"));
+
+ b.Property("Created")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("CreatedById")
+ .HasColumnType("bigint");
+
+ b.Property("GuildId")
+ .HasColumnType("bigint");
+
+ b.Property("NewTagId")
+ .HasColumnType("bigint");
+
+ b.Property("OldTagId")
+ .HasColumnType("bigint");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NewTagId")
+ .IsUnique();
+
+ b.HasIndex("OldTagId")
+ .IsUnique();
+
+ b.HasIndex("GuildId", "CreatedById");
+
+ b.ToTable("TagActions");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Tags.TagEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseSerialColumn(b.Property("Id"));
+
+ b.Property("Content")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("CreateActionId")
+ .HasColumnType("bigint");
+
+ b.Property("DeleteActionId")
+ .HasColumnType("bigint");
+
+ b.Property("GuildId")
+ .HasColumnType("bigint");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("OwnerRoleId")
+ .HasColumnType("bigint");
+
+ b.Property("OwnerUserId")
+ .HasColumnType("bigint");
+
+ b.Property("Uses")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreateActionId")
+ .IsUnique();
+
+ b.HasIndex("DeleteActionId")
+ .IsUnique();
+
+ b.HasIndex("GuildId");
+
+ b.HasIndex("Name");
+
+ b.HasIndex("OwnerRoleId");
+
+ b.HasIndex("OwnerUserId");
+
+ b.HasIndex("GuildId", "OwnerUserId");
+
+ b.ToTable("Tags");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Core.ClaimMappingEntity", b =>
+ {
+ b.HasOne("Modix.Data.Models.Core.ConfigurationActionEntity", "CreateAction")
+ .WithOne()
+ .HasForeignKey("Modix.Data.Models.Core.ClaimMappingEntity", "CreateActionId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Modix.Data.Models.Core.ConfigurationActionEntity", "DeleteAction")
+ .WithOne()
+ .HasForeignKey("Modix.Data.Models.Core.ClaimMappingEntity", "DeleteActionId");
+
+ b.Navigation("CreateAction");
+
+ b.Navigation("DeleteAction");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Core.ConfigurationActionEntity", b =>
+ {
+ b.HasOne("Modix.Data.Models.Core.ClaimMappingEntity", "ClaimMapping")
+ .WithMany()
+ .HasForeignKey("ClaimMappingId");
+
+ b.HasOne("Modix.Data.Models.Core.DesignatedChannelMappingEntity", "DesignatedChannelMapping")
+ .WithMany()
+ .HasForeignKey("DesignatedChannelMappingId");
+
+ b.HasOne("Modix.Data.Models.Core.DesignatedRoleMappingEntity", "DesignatedRoleMapping")
+ .WithMany()
+ .HasForeignKey("DesignatedRoleMappingId");
+
+ b.HasOne("Modix.Data.Models.Core.GuildUserEntity", "CreatedBy")
+ .WithMany()
+ .HasForeignKey("GuildId", "CreatedById")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("ClaimMapping");
+
+ b.Navigation("CreatedBy");
+
+ b.Navigation("DesignatedChannelMapping");
+
+ b.Navigation("DesignatedRoleMapping");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Core.DesignatedChannelMappingEntity", b =>
+ {
+ b.HasOne("Modix.Data.Models.Core.GuildChannelEntity", "Channel")
+ .WithMany("DesignatedChannelMappings")
+ .HasForeignKey("ChannelId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Modix.Data.Models.Core.ConfigurationActionEntity", "CreateAction")
+ .WithOne()
+ .HasForeignKey("Modix.Data.Models.Core.DesignatedChannelMappingEntity", "CreateActionId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Modix.Data.Models.Core.ConfigurationActionEntity", "DeleteAction")
+ .WithOne()
+ .HasForeignKey("Modix.Data.Models.Core.DesignatedChannelMappingEntity", "DeleteActionId");
+
+ b.Navigation("Channel");
+
+ b.Navigation("CreateAction");
+
+ b.Navigation("DeleteAction");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Core.DesignatedRoleMappingEntity", b =>
+ {
+ b.HasOne("Modix.Data.Models.Core.ConfigurationActionEntity", "CreateAction")
+ .WithOne()
+ .HasForeignKey("Modix.Data.Models.Core.DesignatedRoleMappingEntity", "CreateActionId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Modix.Data.Models.Core.ConfigurationActionEntity", "DeleteAction")
+ .WithOne()
+ .HasForeignKey("Modix.Data.Models.Core.DesignatedRoleMappingEntity", "DeleteActionId");
+
+ b.HasOne("Modix.Data.Models.Core.GuildRoleEntity", "Role")
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("CreateAction");
+
+ b.Navigation("DeleteAction");
+
+ b.Navigation("Role");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Core.GuildUserEntity", b =>
+ {
+ b.HasOne("Modix.Data.Models.Core.UserEntity", "User")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Core.MessageEntity", b =>
+ {
+ b.HasOne("Modix.Data.Models.Core.GuildChannelEntity", "Channel")
+ .WithMany()
+ .HasForeignKey("ChannelId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Modix.Data.Models.Core.GuildUserEntity", "Author")
+ .WithMany("Messages")
+ .HasForeignKey("GuildId", "AuthorId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Author");
+
+ b.Navigation("Channel");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Moderation.DeletedMessageBatchEntity", b =>
+ {
+ b.HasOne("Modix.Data.Models.Moderation.ModerationActionEntity", "CreateAction")
+ .WithOne()
+ .HasForeignKey("Modix.Data.Models.Moderation.DeletedMessageBatchEntity", "CreateActionId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("CreateAction");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Moderation.DeletedMessageEntity", b =>
+ {
+ b.HasOne("Modix.Data.Models.Moderation.DeletedMessageBatchEntity", "Batch")
+ .WithMany("DeletedMessages")
+ .HasForeignKey("BatchId");
+
+ b.HasOne("Modix.Data.Models.Core.GuildChannelEntity", "Channel")
+ .WithMany()
+ .HasForeignKey("ChannelId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Modix.Data.Models.Moderation.ModerationActionEntity", "CreateAction")
+ .WithOne()
+ .HasForeignKey("Modix.Data.Models.Moderation.DeletedMessageEntity", "CreateActionId");
+
+ b.HasOne("Modix.Data.Models.Core.GuildUserEntity", "Author")
+ .WithMany()
+ .HasForeignKey("GuildId", "AuthorId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Author");
+
+ b.Navigation("Batch");
+
+ b.Navigation("Channel");
+
+ b.Navigation("CreateAction");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Moderation.InfractionEntity", b =>
+ {
+ b.HasOne("Modix.Data.Models.Moderation.ModerationActionEntity", "CreateAction")
+ .WithOne()
+ .HasForeignKey("Modix.Data.Models.Moderation.InfractionEntity", "CreateActionId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Modix.Data.Models.Moderation.ModerationActionEntity", "DeleteAction")
+ .WithOne()
+ .HasForeignKey("Modix.Data.Models.Moderation.InfractionEntity", "DeleteActionId");
+
+ b.HasOne("Modix.Data.Models.Moderation.ModerationActionEntity", "RescindAction")
+ .WithOne()
+ .HasForeignKey("Modix.Data.Models.Moderation.InfractionEntity", "RescindActionId");
+
+ b.HasOne("Modix.Data.Models.Moderation.ModerationActionEntity", "UpdateAction")
+ .WithOne()
+ .HasForeignKey("Modix.Data.Models.Moderation.InfractionEntity", "UpdateActionId");
+
+ b.HasOne("Modix.Data.Models.Core.GuildUserEntity", "Subject")
+ .WithMany("Infractions")
+ .HasForeignKey("GuildId", "SubjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("CreateAction");
+
+ b.Navigation("DeleteAction");
+
+ b.Navigation("RescindAction");
+
+ b.Navigation("Subject");
+
+ b.Navigation("UpdateAction");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Moderation.ModerationActionEntity", b =>
+ {
+ b.HasOne("Modix.Data.Models.Moderation.DeletedMessageBatchEntity", "DeletedMessageBatch")
+ .WithMany()
+ .HasForeignKey("DeletedMessageBatchId");
+
+ b.HasOne("Modix.Data.Models.Moderation.DeletedMessageEntity", "DeletedMessage")
+ .WithMany()
+ .HasForeignKey("DeletedMessageId");
+
+ b.HasOne("Modix.Data.Models.Moderation.InfractionEntity", "Infraction")
+ .WithMany()
+ .HasForeignKey("InfractionId");
+
+ b.HasOne("Modix.Data.Models.Core.GuildUserEntity", "CreatedBy")
+ .WithMany()
+ .HasForeignKey("GuildId", "CreatedById")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("CreatedBy");
+
+ b.Navigation("DeletedMessage");
+
+ b.Navigation("DeletedMessageBatch");
+
+ b.Navigation("Infraction");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Promotions.PromotionActionEntity", b =>
+ {
+ b.HasOne("Modix.Data.Models.Promotions.PromotionCampaignEntity", "Campaign")
+ .WithMany()
+ .HasForeignKey("CampaignId");
+
+ b.HasOne("Modix.Data.Models.Promotions.PromotionCommentEntity", "NewComment")
+ .WithOne()
+ .HasForeignKey("Modix.Data.Models.Promotions.PromotionActionEntity", "NewCommentId");
+
+ b.HasOne("Modix.Data.Models.Promotions.PromotionCommentEntity", "OldComment")
+ .WithOne()
+ .HasForeignKey("Modix.Data.Models.Promotions.PromotionActionEntity", "OldCommentId");
+
+ b.HasOne("Modix.Data.Models.Core.GuildUserEntity", "CreatedBy")
+ .WithMany()
+ .HasForeignKey("GuildId", "CreatedById")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Campaign");
+
+ b.Navigation("CreatedBy");
+
+ b.Navigation("NewComment");
+
+ b.Navigation("OldComment");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Promotions.PromotionCampaignEntity", b =>
+ {
+ b.HasOne("Modix.Data.Models.Promotions.PromotionActionEntity", "CloseAction")
+ .WithOne()
+ .HasForeignKey("Modix.Data.Models.Promotions.PromotionCampaignEntity", "CloseActionId");
+
+ b.HasOne("Modix.Data.Models.Promotions.PromotionActionEntity", "CreateAction")
+ .WithOne()
+ .HasForeignKey("Modix.Data.Models.Promotions.PromotionCampaignEntity", "CreateActionId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Modix.Data.Models.Core.GuildRoleEntity", "TargetRole")
+ .WithMany()
+ .HasForeignKey("TargetRoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Modix.Data.Models.Core.GuildUserEntity", "Subject")
+ .WithMany("PromotionCampaigns")
+ .HasForeignKey("GuildId", "SubjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("CloseAction");
+
+ b.Navigation("CreateAction");
+
+ b.Navigation("Subject");
+
+ b.Navigation("TargetRole");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Promotions.PromotionCommentEntity", b =>
+ {
+ b.HasOne("Modix.Data.Models.Promotions.PromotionCampaignEntity", "Campaign")
+ .WithMany("Comments")
+ .HasForeignKey("CampaignId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Modix.Data.Models.Promotions.PromotionActionEntity", "CreateAction")
+ .WithOne()
+ .HasForeignKey("Modix.Data.Models.Promotions.PromotionCommentEntity", "CreateActionId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Modix.Data.Models.Promotions.PromotionActionEntity", "ModifyAction")
+ .WithOne()
+ .HasForeignKey("Modix.Data.Models.Promotions.PromotionCommentEntity", "ModifyActionId");
+
+ b.Navigation("Campaign");
+
+ b.Navigation("CreateAction");
+
+ b.Navigation("ModifyAction");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Tags.TagActionEntity", b =>
+ {
+ b.HasOne("Modix.Data.Models.Tags.TagEntity", "NewTag")
+ .WithOne()
+ .HasForeignKey("Modix.Data.Models.Tags.TagActionEntity", "NewTagId");
+
+ b.HasOne("Modix.Data.Models.Tags.TagEntity", "OldTag")
+ .WithOne()
+ .HasForeignKey("Modix.Data.Models.Tags.TagActionEntity", "OldTagId");
+
+ b.HasOne("Modix.Data.Models.Core.GuildUserEntity", "CreatedBy")
+ .WithMany()
+ .HasForeignKey("GuildId", "CreatedById")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("CreatedBy");
+
+ b.Navigation("NewTag");
+
+ b.Navigation("OldTag");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Tags.TagEntity", b =>
+ {
+ b.HasOne("Modix.Data.Models.Tags.TagActionEntity", "CreateAction")
+ .WithOne()
+ .HasForeignKey("Modix.Data.Models.Tags.TagEntity", "CreateActionId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Modix.Data.Models.Tags.TagActionEntity", "DeleteAction")
+ .WithOne()
+ .HasForeignKey("Modix.Data.Models.Tags.TagEntity", "DeleteActionId");
+
+ b.HasOne("Modix.Data.Models.Core.GuildRoleEntity", "OwnerRole")
+ .WithMany()
+ .HasForeignKey("OwnerRoleId");
+
+ b.HasOne("Modix.Data.Models.Core.GuildUserEntity", "OwnerUser")
+ .WithMany()
+ .HasForeignKey("GuildId", "OwnerUserId");
+
+ b.Navigation("CreateAction");
+
+ b.Navigation("DeleteAction");
+
+ b.Navigation("OwnerRole");
+
+ b.Navigation("OwnerUser");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Core.GuildChannelEntity", b =>
+ {
+ b.Navigation("DesignatedChannelMappings");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Core.GuildUserEntity", b =>
+ {
+ b.Navigation("Infractions");
+
+ b.Navigation("Messages");
+
+ b.Navigation("PromotionCampaigns");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Moderation.DeletedMessageBatchEntity", b =>
+ {
+ b.Navigation("DeletedMessages");
+ });
+
+ modelBuilder.Entity("Modix.Data.Models.Promotions.PromotionCampaignEntity", b =>
+ {
+ b.Navigation("Comments");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Modix.Data/Migrations/20240326234009_RemoveDeletedFeatures.cs b/Modix.Data/Migrations/20240326234009_RemoveDeletedFeatures.cs
new file mode 100644
index 000000000..bdf7c3c26
--- /dev/null
+++ b/Modix.Data/Migrations/20240326234009_RemoveDeletedFeatures.cs
@@ -0,0 +1,28 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace Modix.Data.Migrations
+{
+ ///
+ public partial class RemoveDeletedFeatures : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.Sql(@"delete from ""ConfigurationActions"" where ""DesignatedChannelMappingId"" in (select ""Id"" from ""DesignatedChannelMappings"" where ""Type"" = 'GiveawayLog')");
+ migrationBuilder.Sql(@"delete from ""DesignatedChannelMappings"" where ""Type"" = 'GiveawayLog'");
+
+ migrationBuilder.Sql(@"delete from ""ConfigurationActions"" where ""DesignatedRoleMappingId"" in (select ""Id"" from ""DesignatedRoleMappings"" where ""Type"" = 'RestrictedMentionability')");
+ migrationBuilder.Sql(@"delete from ""DesignatedRoleMappings"" where ""Type"" = 'RestrictedMentionability'");
+
+ migrationBuilder.Sql(@"delete from ""ConfigurationActions"" where ""DesignatedRoleMappingId"" in (select ""Id"" from ""DesignatedRoleMappings"" where ""Type"" = 'ResctrictedMentionability')");
+ migrationBuilder.Sql(@"delete from ""DesignatedRoleMappings"" where ""Type"" = 'ResctrictedMentionability'");
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ }
+ }
+}
diff --git a/Modix.Data/Migrations/ModixContextModelSnapshot.cs b/Modix.Data/Migrations/ModixContextModelSnapshot.cs
index 171ebc209..5585aaa28 100644
--- a/Modix.Data/Migrations/ModixContextModelSnapshot.cs
+++ b/Modix.Data/Migrations/ModixContextModelSnapshot.cs
@@ -17,7 +17,7 @@ protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
- .HasAnnotation("ProductVersion", "8.0.0-preview.4.23259.3")
+ .HasAnnotation("ProductVersion", "8.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseSerialColumns(modelBuilder);
diff --git a/Modix.Data/Models/Core/DesignatedRoleType.cs b/Modix.Data/Models/Core/DesignatedRoleType.cs
index 511b66c6a..416922084 100644
--- a/Modix.Data/Models/Core/DesignatedRoleType.cs
+++ b/Modix.Data/Models/Core/DesignatedRoleType.cs
@@ -14,10 +14,6 @@ public enum DesignatedRoleType
///
ModerationMute,
///
- /// Defines a role whose mentionability is restricted in MODiX.
- ///
- RestrictedMentionability,
- ///
/// Defines a role whose mentionability is allowed throughout the guild.
///
Pingable,
diff --git a/Modix.Services.Test/Core/DesignatedRoleServiceTests.cs b/Modix.Services.Test/Core/DesignatedRoleServiceTests.cs
index 467c29543..0dc9b0493 100644
--- a/Modix.Services.Test/Core/DesignatedRoleServiceTests.cs
+++ b/Modix.Services.Test/Core/DesignatedRoleServiceTests.cs
@@ -52,8 +52,7 @@ public static readonly ImmutableArray RoleHasDesignationAsync_Test
new TestCaseData( ulong.MinValue, ulong.MinValue, DesignatedRoleType.Rank, false ).SetName("{m}(Min Values)"),
new TestCaseData( ulong.MaxValue, ulong.MaxValue, DesignatedRoleType.Pingable, true ).SetName("{m}(Max Values)"),
new TestCaseData( 1UL, 2UL, DesignatedRoleType.Rank, false ).SetName("{m}(Unique Values 1)"),
- new TestCaseData( 3UL, 4UL, DesignatedRoleType.ModerationMute, true ).SetName("{m}(Unique Values 2)"),
- new TestCaseData( 5UL, 6UL, DesignatedRoleType.RestrictedMentionability, false ).SetName("{m}(Unique Values 3)"));
+ new TestCaseData( 3UL, 4UL, DesignatedRoleType.ModerationMute, true ).SetName("{m}(Unique Values 2)"));
[TestCaseSource(nameof(RoleHasDesignationAsync_TestCaseData))]
public async Task RoleHasDesignationAsync_Always_ReturnsDesignatedRoleMappingRepositoryAnyAsync(
@@ -109,8 +108,7 @@ public static readonly ImmutableArray RolesHaveDesignationAsync_Te
new TestCaseData( ulong.MinValue, new[] { ulong.MinValue }, DesignatedRoleType.Rank, false ).SetName("{m}(Min Values)"),
new TestCaseData( ulong.MaxValue, new[] { ulong.MaxValue }, DesignatedRoleType.Pingable, true ).SetName("{m}(Max Values)"),
new TestCaseData( 1UL, Array.Empty(), DesignatedRoleType.Rank, false ).SetName("{m}(Unique Values 1)"),
- new TestCaseData( 2UL, new[] { 3UL }, DesignatedRoleType.ModerationMute, true ).SetName("{m}(Unique Values 2)"),
- new TestCaseData( 4UL, new[] { 5UL, 6UL }, DesignatedRoleType.RestrictedMentionability, false ).SetName("{m}(Unique Values 3)"));
+ new TestCaseData( 2UL, new[] { 3UL }, DesignatedRoleType.ModerationMute, true ).SetName("{m}(Unique Values 2)"));
[TestCaseSource(nameof(RolesHaveDesignationAsync_TestCaseData))]
public async Task RolesHaveDesignationAsync_Always_ReturnsDesignatedRoleMappingRepositoryAnyAsync(
diff --git a/Modix.Services/Moderation/ModerationService.cs b/Modix.Services/Moderation/ModerationService.cs
index fde15d6aa..93efa6a26 100644
--- a/Modix.Services/Moderation/ModerationService.cs
+++ b/Modix.Services/Moderation/ModerationService.cs
@@ -121,45 +121,6 @@ public async Task AutoConfigureGuildAsync(IGuild guild)
_authorizationService.RequireClaims(AuthorizationClaim.DesignatedRoleMappingCreate);
await SetUpMuteRole(guild);
- await SetUpMentionableRoles(guild);
- }
-
- private async Task SetUpMentionableRoles(IGuild guild)
- {
- var mentionableRoleMappings = await _designatedRoleMappingRepository.SearchBriefsAsync(
- new DesignatedRoleMappingSearchCriteria
- {
- GuildId = guild.Id, Type = DesignatedRoleType.RestrictedMentionability, IsDeleted = false
- });
-
- Log.Information("Roles with RestrictedMentionability are: {Roles}",
- mentionableRoleMappings.Select(d => d.Role.Name));
-
- //Get the actual roles that correspond to our mappings
- var mentionableRoles = mentionableRoleMappings
- .Join(guild.Roles, d => d.Role.Id, d => d.Id, (map, role) => role)
- .Where(d => d.IsMentionable);
-
- try
- {
- //Ensure all roles with restricted mentionability are not mentionable
- foreach (var role in mentionableRoles)
- {
- Log.Information("Role @{Role} has RestrictedMentionability but was marked as Mentionable.",
- role.Name);
- await role.ModifyAsync(d => d.Mentionable = false);
- Log.Information("Role @{Role} was set to unmentionable.", role.Name);
- }
- }
- catch (HttpException ex)
- {
- var errorTemplate =
- "An exception was thrown when attempting to set up mention-restricted roles for {Guild}. " +
- "This is likely due to Modix not having the \"Manage Roles\" permission, or Modix's role being below one of " +
- "the mention-restricted roles in your server's Role list - please check your server settings.";
-
- Log.Error(ex, errorTemplate, guild.Name);
- }
}
private async Task SetUpMuteRole(IGuild guild)