From 8c3c970e74849478e16243e5a7979c3ca79bd685 Mon Sep 17 00:00:00 2001 From: ptlthg <24925519+ptlthg@users.noreply.github.com> Date: Tue, 13 Jan 2026 21:27:38 -0500 Subject: [PATCH 1/2] Fix guild stat queries not using good indexes --- ...2911_AddLatestFlagToGuildStats.Designer.cs | 5405 +++++++++++++++++ ...0260114012911_AddLatestFlagToGuildStats.cs | 48 + 2 files changed, 5453 insertions(+) create mode 100644 EliteAPI/Data/Migrations/20260114012911_AddLatestFlagToGuildStats.Designer.cs create mode 100644 EliteAPI/Data/Migrations/20260114012911_AddLatestFlagToGuildStats.cs diff --git a/EliteAPI/Data/Migrations/20260114012911_AddLatestFlagToGuildStats.Designer.cs b/EliteAPI/Data/Migrations/20260114012911_AddLatestFlagToGuildStats.Designer.cs new file mode 100644 index 00000000..e40aeac5 --- /dev/null +++ b/EliteAPI/Data/Migrations/20260114012911_AddLatestFlagToGuildStats.Designer.cs @@ -0,0 +1,5405 @@ +// +using System; +using System.Collections.Generic; +using EliteAPI.Data; +using EliteAPI.Features.Account.DTOs; +using EliteAPI.Features.Account.Models; +using EliteAPI.Features.Guides.Models; +using EliteAPI.Features.Leaderboards.Models; +using EliteAPI.Features.Profiles.Models; +using EliteAPI.Features.Recap.Models; +using EliteAPI.Features.Resources.Bazaar; +using EliteAPI.Models.DTOs.Outgoing; +using EliteAPI.Models.Entities.Discord; +using EliteAPI.Models.Entities.Events; +using EliteAPI.Models.Entities.Farming; +using EliteAPI.Models.Entities.Hypixel; +using EliteAPI.Models.Entities.Monetization; +using EliteFarmers.HypixelAPI.DTOs; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace EliteAPI.Data.Migrations +{ + [DbContext(typeof(DataContext))] + [Migration("20260114012911_AddLatestFlagToGuildStats")] + partial class AddLatestFlagToGuildStats + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:CollationDefinition:case_insensitive", "en-u-ks-primary,en-u-ks-primary,icu,False") + .HasAnnotation("ProductVersion", "10.0.1") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("EliteAPI.Features.Account.Models.Badge", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Description") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("ImageId") + .HasMaxLength(48) + .HasColumnType("character varying(48)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Requirements") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("TieToAccount") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("ImageId"); + + b.ToTable("Badges"); + }); + + modelBuilder.Entity("EliteAPI.Features.Account.Models.EliteAccount", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("ActiveRewards") + .HasColumnType("boolean"); + + b.Property("Avatar") + .HasColumnType("text"); + + b.Property("Data") + .HasColumnType("jsonb"); + + b.Property("Discriminator") + .HasColumnType("text"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Locale") + .HasColumnType("text"); + + b.Property("Permissions") + .HasColumnType("integer"); + + b.Property("UserSettingsId") + .HasColumnType("integer"); + + b.Property("Username") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("UserSettingsId"); + + b.ToTable("Accounts"); + }); + + modelBuilder.Entity("EliteAPI.Features.Account.Models.MinecraftAccount", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("AccountId") + .HasColumnType("numeric(20,0)"); + + b.Property("Face") + .HasColumnType("bytea"); + + b.Property>("FlagReasons") + .HasColumnType("jsonb"); + + b.Property("Flags") + .HasColumnType("integer"); + + b.Property("GuildLastUpdated") + .HasColumnType("bigint"); + + b.Property("Hat") + .HasColumnType("bytea"); + + b.Property("LastUpdated") + .HasColumnType("bigint"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .UseCollation("case_insensitive"); + + b.Property("PlayerDataLastUpdated") + .HasColumnType("bigint"); + + b.Property("ProfilesLastUpdated") + .HasColumnType("bigint"); + + b.Property("Selected") + .HasColumnType("boolean"); + + b.Property("TextureId") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex(new[] { "Name" }, "idx_minecraft_accounts_name"); + + b.ToTable("MinecraftAccounts"); + }); + + modelBuilder.Entity("EliteAPI.Features.Account.Models.UserBadge", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BadgeId") + .HasColumnType("integer"); + + b.Property("MinecraftAccountId") + .IsRequired() + .HasMaxLength(36) + .HasColumnType("character varying(36)"); + + b.Property("Order") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.Property("Visible") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("BadgeId"); + + b.HasIndex("MinecraftAccountId"); + + b.ToTable("UserBadges"); + }); + + modelBuilder.Entity("EliteAPI.Features.Account.Models.UserSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CustomLeaderboardStyle") + .HasColumnType("jsonb"); + + b.Property("EmojiUrl") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Features") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Fortune") + .HasColumnType("jsonb"); + + b.Property("LeaderboardStyleId") + .HasColumnType("integer"); + + b.Property("NameStyleId") + .HasColumnType("integer"); + + b.Property("Prefix") + .HasMaxLength(16) + .HasColumnType("character varying(16)"); + + b.Property("Suffix") + .HasMaxLength(16) + .HasColumnType("character varying(16)"); + + b.Property("WeightStyleId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("LeaderboardStyleId"); + + b.HasIndex("NameStyleId"); + + b.HasIndex("WeightStyleId"); + + b.ToTable("UserSettings"); + }); + + modelBuilder.Entity("EliteAPI.Features.Announcements.Models.Announcement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Content") + .IsRequired() + .HasMaxLength(8192) + .HasColumnType("character varying(8192)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ExpiresAt") + .HasColumnType("timestamp with time zone"); + + b.Property("TargetEndsAt") + .HasColumnType("timestamp with time zone"); + + b.Property("TargetLabel") + .HasColumnType("text"); + + b.Property("TargetStartsAt") + .HasColumnType("timestamp with time zone"); + + b.Property("TargetUrl") + .HasColumnType("text"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("Announcements"); + }); + + modelBuilder.Entity("EliteAPI.Features.Announcements.Models.DismissedAnnouncement", b => + { + b.Property("AnnouncementId") + .HasColumnType("uuid"); + + b.Property("AccountId") + .HasColumnType("numeric(20,0)"); + + b.HasKey("AnnouncementId", "AccountId"); + + b.HasIndex("AccountId"); + + b.ToTable("DismissedAnnouncements"); + }); + + modelBuilder.Entity("EliteAPI.Features.AuditLogs.Models.AdminAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("AdminUserId") + .HasColumnType("numeric(20,0)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property>("Data") + .HasColumnType("jsonb"); + + b.Property("Details") + .HasMaxLength(2048) + .HasColumnType("character varying(2048)"); + + b.Property("TargetId") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("TargetType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.HasKey("Id"); + + b.HasIndex("Action"); + + b.HasIndex("AdminUserId"); + + b.HasIndex("CreatedAt"); + + b.HasIndex("TargetType"); + + b.ToTable("AdminAuditLogs"); + }); + + modelBuilder.Entity("EliteAPI.Features.Auth.Models.ApiUser", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("AccessFailedCount") + .HasColumnType("integer"); + + b.Property("AccountId") + .HasColumnType("numeric(20,0)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("DiscordAccessToken") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("DiscordAccessTokenExpires") + .HasColumnType("timestamp with time zone"); + + b.Property("DiscordRefreshToken") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("DiscordRefreshTokenExpires") + .HasColumnType("timestamp with time zone"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("boolean"); + + b.Property("GuildsLastUpdated") + .HasColumnType("timestamp with time zone"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordHash") + .HasColumnType("text"); + + b.Property("PhoneNumber") + .HasColumnType("text"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean"); + + b.Property("SecurityStamp") + .HasColumnType("text"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("EliteAPI.Features.Auth.Models.RefreshToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityAlwaysColumn(b.Property("Id")); + + b.Property("CreatedUtc") + .HasColumnType("timestamp with time zone"); + + b.Property("ExpiresUtc") + .HasColumnType("timestamp with time zone"); + + b.Property("RevokedUtc") + .HasColumnType("timestamp with time zone"); + + b.Property("Token") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("UserId", "Token"); + + b.ToTable("RefreshTokens"); + }); + + modelBuilder.Entity("EliteAPI.Features.Confirmations.Models.Confirmation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Content") + .HasColumnType("text"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("Title") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Confirmations"); + }); + + modelBuilder.Entity("EliteAPI.Features.Confirmations.Models.UserConfirmation", b => + { + b.Property("UserId") + .HasColumnType("text"); + + b.Property("ConfirmationId") + .HasColumnType("integer"); + + b.Property("ConfirmedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("UserId", "ConfirmationId"); + + b.HasIndex("ConfirmationId"); + + b.ToTable("UserConfirmations"); + }); + + modelBuilder.Entity("EliteAPI.Features.Guides.Models.Comment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AuthorId") + .HasColumnType("numeric(20,0)"); + + b.Property("Content") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("character varying(2048)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DraftContent") + .HasMaxLength(2048) + .HasColumnType("character varying(2048)"); + + b.Property("EditedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("EditedByAdminId") + .HasColumnType("numeric(20,0)"); + + b.Property("IsApproved") + .HasColumnType("boolean"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("LiftedElementId") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ParentId") + .HasColumnType("integer"); + + b.Property("Score") + .HasColumnType("integer"); + + b.Property("TargetId") + .HasColumnType("integer"); + + b.Property("TargetType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.HasIndex("ParentId"); + + b.ToTable("Comments"); + }); + + modelBuilder.Entity("EliteAPI.Features.Guides.Models.CommentVote", b => + { + b.Property("CommentId") + .HasColumnType("integer"); + + b.Property("UserId") + .HasColumnType("numeric(20,0)"); + + b.Property("Value") + .HasColumnType("smallint"); + + b.Property("VotedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("CommentId", "UserId"); + + b.HasIndex("UserId"); + + b.ToTable("CommentVotes"); + }); + + modelBuilder.Entity("EliteAPI.Features.Guides.Models.Guide", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ActiveVersionId") + .HasColumnType("integer"); + + b.Property("AuthorId") + .HasColumnType("numeric(20,0)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DraftVersionId") + .HasColumnType("integer"); + + b.Property("IconSkyblockId") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("RejectionReason") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("Score") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("Type") + .HasColumnType("integer"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ViewCount") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ActiveVersionId") + .IsUnique(); + + b.HasIndex("AuthorId"); + + b.HasIndex("DraftVersionId") + .IsUnique(); + + b.ToTable("Guides"); + }); + + modelBuilder.Entity("EliteAPI.Features.Guides.Models.GuideBookmark", b => + { + b.Property("UserId") + .HasColumnType("numeric(20,0)"); + + b.Property("GuideId") + .HasColumnType("integer"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("UserId", "GuideId"); + + b.HasIndex("GuideId"); + + b.ToTable("GuideBookmarks"); + }); + + modelBuilder.Entity("EliteAPI.Features.Guides.Models.GuideTag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Category") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.Property("HexColor") + .IsRequired() + .HasMaxLength(7) + .HasColumnType("character varying(7)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.HasKey("Id"); + + b.ToTable("GuideTags"); + }); + + modelBuilder.Entity("EliteAPI.Features.Guides.Models.GuideTagMapping", b => + { + b.Property("GuideId") + .HasColumnType("integer"); + + b.Property("TagId") + .HasColumnType("integer"); + + b.HasKey("GuideId", "TagId"); + + b.HasIndex("TagId"); + + b.ToTable("GuideTagMapping"); + }); + + modelBuilder.Entity("EliteAPI.Features.Guides.Models.GuideVersion", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("GuideId") + .HasColumnType("integer"); + + b.Property("IconItemName") + .HasColumnType("text"); + + b.Property("MarkdownContent") + .IsRequired() + .HasColumnType("text"); + + b.Property("RichBlocks") + .HasColumnType("jsonb"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.HasKey("Id"); + + b.HasIndex("GuideId"); + + b.ToTable("GuideVersions"); + }); + + modelBuilder.Entity("EliteAPI.Features.Guides.Models.GuideVote", b => + { + b.Property("GuideId") + .HasColumnType("integer"); + + b.Property("UserId") + .HasColumnType("numeric(20,0)"); + + b.Property("Value") + .HasColumnType("smallint"); + + b.Property("VotedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("GuideId", "UserId"); + + b.HasIndex("UserId"); + + b.ToTable("GuideVotes"); + }); + + modelBuilder.Entity("EliteAPI.Features.HypixelGuilds.Models.HypixelGuild", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("CreatedAt") + .HasColumnType("bigint"); + + b.Property("Deleted") + .HasColumnType("boolean"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("Exp") + .HasColumnType("bigint"); + + b.Property>("GameExp") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("LastUpdated") + .HasColumnType("bigint"); + + b.Property("MemberCount") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("NameLower") + .IsRequired() + .HasColumnType("text"); + + b.PrimitiveCollection("PreferredGames") + .HasColumnType("jsonb"); + + b.Property("Public") + .HasColumnType("boolean"); + + b.Property("PubliclyListed") + .HasColumnType("boolean"); + + b.Property>("Ranks") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Tag") + .HasColumnType("text"); + + b.Property("TagColor") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("MemberCount"); + + b.HasIndex("NameLower"); + + b.ToTable("HypixelGuilds"); + }); + + modelBuilder.Entity("EliteAPI.Features.HypixelGuilds.Models.HypixelGuildLeaderboardResult", b => + { + b.Property("Amount") + .HasColumnType("double precision"); + + b.Property("CreatedAt") + .HasColumnType("bigint"); + + b.Property("Id") + .HasColumnType("text"); + + b.Property("LastUpdated") + .HasColumnType("bigint"); + + b.Property("MemberCount") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("Tag") + .HasColumnType("text"); + + b.Property("TagColor") + .HasColumnType("text"); + + b.ToTable("HypixelGuildLeaderboardResult", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("EliteAPI.Features.HypixelGuilds.Models.HypixelGuildMember", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("GuildId") + .IsRequired() + .HasColumnType("text"); + + b.Property("JoinedAt") + .HasColumnType("bigint"); + + b.Property("LeftAt") + .HasColumnType("bigint"); + + b.Property("PlayerUuid") + .IsRequired() + .HasColumnType("text"); + + b.Property("QuestParticipation") + .HasColumnType("integer"); + + b.Property("Rank") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("Active"); + + b.HasIndex("PlayerUuid"); + + b.HasIndex("GuildId", "Active"); + + b.HasIndex("GuildId", "PlayerUuid") + .IsUnique(); + + b.ToTable("HypixelGuildMembers"); + }); + + modelBuilder.Entity("EliteAPI.Features.HypixelGuilds.Models.HypixelGuildMemberExp", b => + { + b.Property("GuildMemberId") + .HasColumnType("bigint"); + + b.Property("Day") + .HasColumnType("date"); + + b.Property("Xp") + .HasColumnType("integer"); + + b.HasKey("GuildMemberId", "Day"); + + b.HasIndex("Day") + .IsDescending(); + + b.HasIndex("GuildMemberId"); + + b.ToTable("HypixelGuildMemberExps"); + }); + + modelBuilder.Entity("EliteAPI.Features.HypixelGuilds.Models.HypixelGuildStats", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property>("Collections") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("GuildId") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsLatest") + .HasColumnType("boolean"); + + b.Property("MemberCount") + .HasColumnType("integer"); + + b.Property("RecordedAt") + .HasColumnType("timestamp with time zone"); + + b.Property>("Skills") + .IsRequired() + .HasColumnType("jsonb"); + + b.HasKey("Id"); + + b.HasIndex("RecordedAt"); + + b.HasIndex("GuildId", "IsLatest") + .HasFilter("\"IsLatest\" = true"); + + b.ToTable("HypixelGuildStats"); + }); + + modelBuilder.Entity("EliteAPI.Features.HypixelGuilds.Services.GuildIdResult", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.ToTable("GuildIdResult", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("EliteAPI.Features.HypixelGuilds.Services.GuildRankResult", b => + { + b.Property("Amount") + .HasColumnType("double precision"); + + b.Property("Rank") + .HasColumnType("integer"); + + b.ToTable("GuildRankResult", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("EliteAPI.Features.Images.Models.Image", b => + { + b.Property("Id") + .HasMaxLength(48) + .HasColumnType("character varying(48)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("Hash") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property>("Metadata") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Order") + .HasColumnType("integer"); + + b.Property("Path") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("Title") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.HasKey("Id"); + + b.HasIndex("Hash"); + + b.HasIndex("Path"); + + b.ToTable("Images"); + }); + + modelBuilder.Entity("EliteAPI.Features.Leaderboards.Models.Leaderboard", b => + { + b.Property("LeaderboardId") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("LeaderboardId")); + + b.Property("EndDate") + .HasColumnType("date"); + + b.Property("EntryType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("IconId") + .HasColumnType("character varying(48)"); + + b.Property("IntervalType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("MinimumScore") + .HasColumnType("numeric"); + + b.Property("Property") + .HasColumnType("text"); + + b.Property("ScoreDataType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("ShortTitle") + .HasColumnType("text"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("text"); + + b.Property("StartDate") + .HasColumnType("date"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.HasKey("LeaderboardId"); + + b.HasIndex("IconId"); + + b.HasIndex("Slug") + .IsUnique(); + + b.ToTable("Leaderboards"); + }); + + modelBuilder.Entity("EliteAPI.Features.Leaderboards.Models.LeaderboardEntry", b => + { + b.Property("LeaderboardEntryId") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("LeaderboardEntryId")); + + b.Property("InitialScore") + .ValueGeneratedOnAdd() + .HasColumnType("decimal(24, 4)") + .HasDefaultValue(0m); + + b.Property("IntervalIdentifier") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("IsRemoved") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("LeaderboardId") + .HasColumnType("integer"); + + b.Property("ProfileId") + .HasColumnType("text"); + + b.Property("ProfileMemberId") + .HasColumnType("uuid"); + + b.Property("ProfileType") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Score") + .HasColumnType("decimal(24, 4)"); + + b.HasKey("LeaderboardEntryId"); + + b.HasIndex("IsRemoved"); + + b.HasIndex("ProfileId"); + + b.HasIndex("ProfileMemberId"); + + b.HasIndex("LeaderboardId", "IntervalIdentifier", "Score") + .IsDescending(false, false, true); + + b.HasIndex("ProfileType", "LeaderboardId", "IntervalIdentifier"); + + b.HasIndex("LeaderboardId", "IsRemoved", "Score", "LeaderboardEntryId") + .IsDescending(false, false, true, true) + .HasDatabaseName("IX_LeaderboardEntries_Rank_Subquery_AllTime") + .HasFilter("\"IntervalIdentifier\" IS NULL"); + + b.HasIndex("LeaderboardId", "IsRemoved", "IntervalIdentifier", "Score", "LeaderboardEntryId") + .IsDescending(false, false, false, true, true) + .HasDatabaseName("IX_LeaderboardEntries_Ranks_Subquery"); + + b.ToTable("LeaderboardEntries"); + }); + + modelBuilder.Entity("EliteAPI.Features.Leaderboards.Models.LeaderboardRanksQueryResult", b => + { + b.Property("InitialScore") + .HasColumnType("numeric"); + + b.Property("IntervalIdentifier") + .HasColumnType("text"); + + b.Property("Rank") + .HasColumnType("bigint"); + + b.Property("Score") + .HasColumnType("numeric"); + + b.Property("ScoreDataType") + .IsRequired() + .HasColumnType("text"); + + b.Property("ShortTitle") + .IsRequired() + .HasColumnType("text"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("text"); + + b.Property("Title") + .IsRequired() + .HasColumnType("text"); + + b.ToTable("LeaderboardRanksQueryResult", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("EliteAPI.Features.Leaderboards.Models.LeaderboardSnapshot", b => + { + b.Property("LeaderboardSnapshotId") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("LeaderboardSnapshotId")); + + b.Property("IntervalIdentifier") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("LeaderboardId") + .HasColumnType("integer"); + + b.Property("SnapshotTimestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("LeaderboardSnapshotId"); + + b.HasIndex("LeaderboardId", "IntervalIdentifier"); + + b.HasIndex(new[] { "LeaderboardId", "SnapshotTimestamp", "IntervalIdentifier" }, "IX_LeaderboardSnapshots_Definition_Timestamp_Interval") + .IsUnique(); + + b.ToTable("LeaderboardSnapshots"); + }); + + modelBuilder.Entity("EliteAPI.Features.Leaderboards.Models.LeaderboardSnapshotEntry", b => + { + b.Property("LeaderboardSnapshotEntryId") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("LeaderboardSnapshotEntryId")); + + b.Property("EntryTimestamp") + .HasColumnType("timestamp with time zone"); + + b.Property("InitialScore") + .HasColumnType("numeric"); + + b.Property("IntervalIdentifier") + .HasColumnType("text"); + + b.Property("IsRemoved") + .HasColumnType("boolean"); + + b.Property("LeaderboardSnapshotId") + .HasColumnType("integer"); + + b.Property("ProfileId") + .HasColumnType("text"); + + b.Property("ProfileMemberId") + .HasColumnType("uuid"); + + b.Property("ProfileType") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Score") + .HasColumnType("decimal(24, 4)"); + + b.HasKey("LeaderboardSnapshotEntryId"); + + b.HasIndex("LeaderboardSnapshotId", "Score"); + + b.HasIndex("ProfileType", "LeaderboardSnapshotId"); + + b.ToTable("LeaderboardSnapshotEntries", null, t => + { + t.HasCheckConstraint("CK_LeaderboardSnapshotEntries_ProfileOrMember", "((\"ProfileId\" IS NOT NULL AND \"ProfileMemberId\" IS NULL) OR (\"ProfileId\" IS NULL AND \"ProfileMemberId\" IS NOT NULL))"); + }); + }); + + modelBuilder.Entity("EliteAPI.Features.Leaderboards.Models.ProfileMemberMetadata", b => + { + b.Property("ProfileMemberId") + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("Prefix") + .HasColumnType("text"); + + b.Property("Profile") + .IsRequired() + .HasColumnType("text"); + + b.Property("ProfileUuid") + .IsRequired() + .HasColumnType("text"); + + b.Property("SkyblockExperience") + .HasColumnType("integer"); + + b.Property("Uuid") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("ProfileMemberId"); + + b.ToTable("ProfileMemberMetadata"); + }); + + modelBuilder.Entity("EliteAPI.Features.Monetization.Models.Entitlement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("Consumed") + .HasColumnType("boolean"); + + b.Property("Deleted") + .HasColumnType("boolean"); + + b.Property("EndDate") + .HasColumnType("timestamp with time zone"); + + b.Property("ProductId") + .HasColumnType("numeric(20,0)") + .HasJsonPropertyName("sku_id"); + + b.Property("StartDate") + .HasColumnType("timestamp with time zone"); + + b.Property("Target") + .HasColumnType("integer"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.ToTable("Entitlements"); + + b.HasDiscriminator("Target").HasValue(0); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("EliteAPI.Features.Monetization.Models.ProductAccess", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Consumed") + .HasColumnType("boolean"); + + b.Property("EndDate") + .HasColumnType("timestamp with time zone"); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("ProductId") + .HasColumnType("numeric(20,0)"); + + b.Property("Revoked") + .HasColumnType("boolean"); + + b.Property("SourceOrderId") + .HasColumnType("uuid"); + + b.Property("StartDate") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("numeric(20,0)"); + + b.HasKey("Id"); + + b.HasIndex("GuildId"); + + b.HasIndex("ProductId"); + + b.HasIndex("SourceOrderId"); + + b.HasIndex("UserId"); + + b.ToTable("ProductAccesses"); + }); + + modelBuilder.Entity("EliteAPI.Features.Monetization.Models.ShopOrder", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("BuyerId") + .HasColumnType("numeric(20,0)"); + + b.Property("Currency") + .IsRequired() + .HasColumnType("text"); + + b.Property("OrderDate") + .HasColumnType("timestamp with time zone"); + + b.Property("Provider") + .HasColumnType("integer"); + + b.Property("ProviderTransactionId") + .HasColumnType("text"); + + b.Property("RecipientGuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("RecipientId") + .HasColumnType("numeric(20,0)"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("TotalPrice") + .HasColumnType("numeric"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.HasIndex("RecipientGuildId"); + + b.HasIndex("RecipientId"); + + b.ToTable("ShopOrders"); + }); + + modelBuilder.Entity("EliteAPI.Features.Monetization.Models.ShopOrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("OrderId") + .HasColumnType("uuid"); + + b.Property("ProductId") + .HasColumnType("numeric(20,0)"); + + b.Property("Quantity") + .HasColumnType("integer"); + + b.Property("UnitPrice") + .HasColumnType("numeric"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.HasIndex("ProductId"); + + b.ToTable("ShopOrderItems"); + }); + + modelBuilder.Entity("EliteAPI.Features.Notifications.Models.Notification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property>("Data") + .HasColumnType("jsonb"); + + b.Property("IsRead") + .HasColumnType("boolean"); + + b.Property("Link") + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("Message") + .HasMaxLength(2048) + .HasColumnType("character varying(2048)"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Type") + .HasColumnType("integer"); + + b.Property("UserId") + .HasColumnType("numeric(20,0)"); + + b.HasKey("Id"); + + b.HasIndex("CreatedAt"); + + b.HasIndex("UserId"); + + b.HasIndex("UserId", "IsRead"); + + b.ToTable("Notifications"); + }); + + modelBuilder.Entity("EliteAPI.Features.Profiles.Models.GameModeHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ChangedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("New") + .IsRequired() + .HasColumnType("text"); + + b.Property("Old") + .IsRequired() + .HasColumnType("text"); + + b.Property("ProfileId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ProfileId"); + + b.ToTable("GameModeHistories"); + }); + + modelBuilder.Entity("EliteAPI.Features.Profiles.Models.HypixelInventory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.PrimitiveCollection("EmptySlots") + .HasColumnType("smallint[]"); + + b.Property("Hash") + .IsRequired() + .HasColumnType("text"); + + b.Property("HypixelInventoryId") + .HasColumnType("uuid"); + + b.Property>("Metadata") + .HasColumnType("jsonb"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("ProfileMemberId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("HypixelInventoryId") + .IsUnique(); + + b.HasIndex("ProfileMemberId"); + + b.ToTable("HypixelInventory"); + }); + + modelBuilder.Entity("EliteAPI.Features.Profiles.Models.HypixelItem", b => + { + b.Property("HypixelItemId") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("HypixelItemId")); + + b.Property("Attributes") + .HasColumnType("jsonb"); + + b.Property("Count") + .HasColumnType("smallint"); + + b.Property("Damage") + .HasColumnType("smallint"); + + b.Property("DonatedMuseum") + .HasColumnType("text"); + + b.Property>("Enchantments") + .HasColumnType("jsonb"); + + b.Property>("Gems") + .HasColumnType("jsonb"); + + b.Property("Id") + .HasColumnType("smallint"); + + b.Property("InventoryId") + .HasColumnType("bigint"); + + b.Property("LastUpdated") + .HasColumnType("timestamp with time zone"); + + b.Property("Lore") + .HasColumnType("text"); + + b.Property("Modifier") + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("RarityUpgrades") + .HasColumnType("text"); + + b.Property("SkyblockId") + .IsRequired() + .HasColumnType("text"); + + b.Property("Slot") + .HasColumnType("text"); + + b.Property("Timestamp") + .HasColumnType("text"); + + b.Property("Uuid") + .HasColumnType("uuid"); + + b.HasKey("HypixelItemId"); + + b.HasIndex("InventoryId"); + + b.HasIndex("SkyblockId"); + + b.ToTable("HypixelItems"); + }); + + modelBuilder.Entity("EliteAPI.Features.Recap.Models.YearlyRecap", b => + { + b.Property("ProfileMemberId") + .HasColumnType("uuid"); + + b.Property("Year") + .HasColumnType("integer"); + + b.Property("Data") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Passkey") + .HasColumnType("uuid"); + + b.Property("Public") + .HasColumnType("boolean"); + + b.Property("Views") + .HasColumnType("integer"); + + b.HasKey("ProfileMemberId", "Year"); + + b.ToTable("YearlyRecaps"); + }); + + modelBuilder.Entity("EliteAPI.Features.Recap.Models.YearlyRecapSnapshot", b => + { + b.Property("Year") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Year")); + + b.Property("Data") + .IsRequired() + .HasColumnType("jsonb"); + + b.HasKey("Year"); + + b.ToTable("YearlyRecapSnapshots"); + }); + + modelBuilder.Entity("EliteAPI.Features.Resources.Auctions.Models.Auction", b => + { + b.Property("AuctionId") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Bin") + .HasColumnType("boolean"); + + b.Property("BuyerProfileMemberId") + .HasColumnType("uuid"); + + b.Property("BuyerProfileUuid") + .HasColumnType("uuid"); + + b.Property("BuyerUuid") + .HasColumnType("uuid"); + + b.Property("Count") + .HasColumnType("smallint"); + + b.Property("End") + .HasColumnType("bigint"); + + b.Property("HighestBid") + .HasColumnType("bigint"); + + b.Property("Item") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("ItemUuid") + .HasColumnType("uuid"); + + b.Property("LastUpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Price") + .HasColumnType("bigint"); + + b.Property("SellerProfileMemberId") + .HasColumnType("uuid"); + + b.Property("SellerProfileUuid") + .HasColumnType("uuid"); + + b.Property("SellerUuid") + .HasColumnType("uuid"); + + b.Property("SkyblockId") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("SoldAt") + .HasColumnType("bigint"); + + b.Property("Start") + .HasColumnType("bigint"); + + b.Property("StartingBid") + .HasColumnType("bigint"); + + b.Property("VariantKey") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(512) + .HasColumnType("character varying(512)") + .HasDefaultValue(""); + + b.HasKey("AuctionId"); + + b.HasIndex("BuyerProfileMemberId"); + + b.HasIndex("Price"); + + b.HasIndex("SellerProfileMemberId"); + + b.HasIndex("SoldAt"); + + b.HasIndex("SkyblockId", "SoldAt"); + + b.HasIndex("SkyblockId", "VariantKey", "SoldAt"); + + b.ToTable("EndedAuctions"); + }); + + modelBuilder.Entity("EliteAPI.Features.Resources.Auctions.Models.AuctionBinPrice", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AuctionUuid") + .HasColumnType("uuid"); + + b.Property("IngestedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ListedAt") + .HasColumnType("bigint"); + + b.Property("Price") + .HasColumnType("numeric"); + + b.Property("SkyblockId") + .IsRequired() + .HasColumnType("text"); + + b.Property("VariantKey") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("AuctionUuid"); + + b.HasIndex("IngestedAt"); + + b.HasIndex("SkyblockId", "VariantKey", "ListedAt"); + + b.ToTable("AuctionBinPrices"); + }); + + modelBuilder.Entity("EliteAPI.Features.Resources.Auctions.Models.AuctionItem", b => + { + b.Property("SkyblockId") + .HasColumnType("text") + .HasColumnOrder(0); + + b.Property("VariantKey") + .HasColumnType("text") + .HasColumnOrder(1); + + b.Property("CalculatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Lowest") + .HasColumnType("numeric"); + + b.Property("Lowest3Day") + .HasColumnType("numeric"); + + b.Property("Lowest3DayVolume") + .HasColumnType("integer"); + + b.Property("Lowest7Day") + .HasColumnType("numeric"); + + b.Property("Lowest7DayVolume") + .HasColumnType("integer"); + + b.Property("LowestObservedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("LowestVolume") + .HasColumnType("integer"); + + b.HasKey("SkyblockId", "VariantKey"); + + b.HasIndex("CalculatedAt"); + + b.ToTable("AuctionItems"); + }); + + modelBuilder.Entity("EliteAPI.Features.Resources.Auctions.Models.AuctionPriceHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AverageBinPrice") + .HasColumnType("numeric"); + + b.Property("AverageSalePrice") + .HasColumnType("numeric"); + + b.Property("BinListings") + .HasColumnType("integer"); + + b.Property("BucketStart") + .HasColumnType("bigint"); + + b.Property("CalculatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ItemsSold") + .HasColumnType("integer"); + + b.Property("LowestBinPrice") + .HasColumnType("numeric"); + + b.Property("LowestSalePrice") + .HasColumnType("numeric"); + + b.Property("SaleAuctions") + .HasColumnType("integer"); + + b.Property("SkyblockId") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("VariantKey") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(512) + .HasColumnType("character varying(512)") + .HasDefaultValue(""); + + b.HasKey("Id"); + + b.HasIndex("BucketStart"); + + b.HasIndex("SkyblockId", "VariantKey", "BucketStart") + .IsUnique(); + + b.ToTable("AuctionPriceHistories"); + }); + + modelBuilder.Entity("EliteAPI.Features.Resources.Auctions.Models.AuctionSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("numeric(20,0)"); + + b.Property("PausedUntil") + .HasColumnType("timestamp with time zone"); + + b.Property("ProfileMemberId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("ProfileMemberId"); + + b.ToTable("AuctionSubscription"); + }); + + modelBuilder.Entity("EliteAPI.Features.Resources.Bazaar.BazaarProductSnapshot", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BuyOrderPrice") + .HasColumnType("double precision"); + + b.Property("InstaBuyPrice") + .HasColumnType("double precision"); + + b.Property("InstaSellPrice") + .HasColumnType("double precision"); + + b.Property("ProductId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("RecordedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("SellOrderPrice") + .HasColumnType("double precision"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.HasIndex("RecordedAt"); + + b.HasIndex("ProductId", "RecordedAt") + .IsUnique(); + + b.ToTable("BazaarProductSnapshots"); + }); + + modelBuilder.Entity("EliteAPI.Features.Resources.Bazaar.BazaarProductSummary", b => + { + b.Property("ItemId") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("AvgBuyOrderPrice") + .HasColumnType("double precision"); + + b.Property("AvgInstaBuyPrice") + .HasColumnType("double precision"); + + b.Property("AvgInstaSellPrice") + .HasColumnType("double precision"); + + b.Property("AvgSellOrderPrice") + .HasColumnType("double precision"); + + b.Property("BuyOrderPrice") + .HasColumnType("double precision"); + + b.Property("CalculationTimestamp") + .HasColumnType("timestamp with time zone"); + + b.Property("InstaBuyPrice") + .HasColumnType("double precision"); + + b.Property("InstaSellPrice") + .HasColumnType("double precision"); + + b.Property("Orders") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("SellOrderPrice") + .HasColumnType("double precision"); + + b.HasKey("ItemId"); + + b.HasIndex("CalculationTimestamp"); + + b.ToTable("BazaarProductSummaries"); + }); + + modelBuilder.Entity("EliteAPI.Features.Resources.Firesales.Models.SkyblockFiresale", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("EndsAt") + .HasColumnType("bigint"); + + b.Property("StartsAt") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("StartsAt"); + + b.ToTable("SkyblockFiresales"); + }); + + modelBuilder.Entity("EliteAPI.Features.Resources.Firesales.Models.SkyblockFiresaleItem", b => + { + b.Property("FiresaleId") + .HasColumnType("uuid"); + + b.Property("SlotId") + .HasColumnType("integer"); + + b.Property("Amount") + .HasColumnType("integer"); + + b.Property("EndsAt") + .HasColumnType("bigint"); + + b.Property("ItemId") + .IsRequired() + .HasColumnType("text"); + + b.Property("Price") + .HasColumnType("integer"); + + b.Property("StartsAt") + .HasColumnType("bigint"); + + b.HasKey("FiresaleId", "SlotId"); + + b.ToTable("SkyblockFiresaleItems"); + }); + + modelBuilder.Entity("EliteAPI.Features.Resources.Items.Models.SkyblockItem", b => + { + b.Property("ItemId") + .HasColumnType("text"); + + b.Property("Data") + .HasColumnType("jsonb"); + + b.Property("NpcSellPrice") + .HasColumnType("double precision"); + + b.HasKey("ItemId"); + + b.ToTable("SkyblockItems"); + }); + + modelBuilder.Entity("EliteAPI.Features.Textures.Models.HypixelItemTexture", b => + { + b.Property("RenderHash") + .HasColumnType("text"); + + b.Property("LastUsed") + .HasColumnType("timestamp with time zone"); + + b.Property("Url") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("RenderHash"); + + b.ToTable("HypixelItemTextures"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Discord.Guild", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("ActiveRewards") + .HasColumnType("boolean"); + + b.Property("AdminRole") + .HasColumnType("numeric(20,0)"); + + b.Property("BannerId") + .HasColumnType("character varying(48)"); + + b.Property("BotPermissions") + .HasColumnType("numeric(20,0)"); + + b.Property("Description") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.PrimitiveCollection("DiscordFeatures") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Features") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("HasBot") + .HasColumnType("boolean"); + + b.Property("IconId") + .HasColumnType("character varying(48)"); + + b.Property("InviteCode") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("IsPublic") + .HasColumnType("boolean"); + + b.Property("LastUpdated") + .HasColumnType("timestamp with time zone"); + + b.Property("MemberCount") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.HasKey("Id"); + + b.HasIndex("BannerId"); + + b.HasIndex("IconId"); + + b.ToTable("Guilds"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Discord.GuildChannel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("BotPermissions") + .HasColumnType("numeric(20,0)"); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("LastUpdated") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Position") + .HasColumnType("integer"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("GuildId"); + + b.ToTable("GuildChannels"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Discord.GuildMember", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("LastUpdated") + .HasColumnType("timestamp with time zone"); + + b.Property("Permissions") + .HasColumnType("numeric(20,0)"); + + b.PrimitiveCollection("Roles") + .IsRequired() + .HasColumnType("numeric(20,0)[]"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("GuildId"); + + b.ToTable("GuildMembers"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Discord.GuildRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("LastUpdated") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Permissions") + .HasColumnType("numeric(20,0)"); + + b.Property("Position") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("GuildId"); + + b.ToTable("GuildRoles"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.Event", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("Approved") + .HasColumnType("boolean"); + + b.Property("BannerId") + .HasMaxLength(48) + .HasColumnType("character varying(48)"); + + b.Property("BlockedRole") + .HasMaxLength(24) + .HasColumnType("character varying(24)"); + + b.Property("Description") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("DynamicStartTime") + .HasColumnType("boolean"); + + b.Property("EndTime") + .HasColumnType("timestamp with time zone"); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("JoinUntilTime") + .HasColumnType("timestamp with time zone"); + + b.Property("MaxTeamMembers") + .HasColumnType("integer"); + + b.Property("MaxTeams") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("PrizeInfo") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("Public") + .HasColumnType("boolean"); + + b.Property("RequiredRole") + .HasMaxLength(24) + .HasColumnType("character varying(24)"); + + b.Property("Rules") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("StartTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("BannerId"); + + b.HasIndex("GuildId"); + + b.ToTable("Events"); + + b.HasDiscriminator("Type").HasValue(0); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.EventMember", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("EndTime") + .HasColumnType("timestamp with time zone"); + + b.Property("EstimatedTimeActive") + .HasColumnType("bigint"); + + b.Property("EventId") + .HasColumnType("numeric(20,0)"); + + b.Property("LastUpdated") + .HasColumnType("timestamp with time zone"); + + b.Property("Notes") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ProfileMemberId") + .HasColumnType("uuid"); + + b.Property("Score") + .HasColumnType("double precision"); + + b.Property("StartTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("TeamId") + .HasColumnType("integer"); + + b.Property("Type") + .HasColumnType("integer"); + + b.Property("UserId") + .HasColumnType("numeric(20,0)"); + + b.HasKey("Id"); + + b.HasIndex("ProfileMemberId"); + + b.HasIndex("TeamId"); + + b.HasIndex("UserId"); + + b.HasIndex("EventId", "UserId") + .IsUnique(); + + b.ToTable("EventMembers"); + + b.HasDiscriminator("Type").HasValue(0); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.EventTeam", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Color") + .HasMaxLength(6) + .HasColumnType("character varying(6)"); + + b.Property("EventId") + .HasColumnType("numeric(20,0)"); + + b.Property("JoinCode") + .IsRequired() + .HasMaxLength(6) + .HasColumnType("character varying(6)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("UserId") + .IsRequired() + .HasMaxLength(22) + .HasColumnType("character varying(22)"); + + b.HasKey("Id"); + + b.HasIndex("EventId", "UserId") + .IsUnique(); + + b.ToTable("EventTeams"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Farming.Farming", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property>("BonusWeight") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property>("CropWeight") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Fortune") + .HasColumnType("jsonb"); + + b.Property("Inventory") + .HasColumnType("jsonb"); + + b.Property("ProfileMemberId") + .HasColumnType("uuid"); + + b.Property("TotalWeight") + .HasColumnType("double precision"); + + b.Property>("UncountedCrops") + .IsRequired() + .HasColumnType("jsonb"); + + b.HasKey("Id"); + + b.HasIndex("ProfileMemberId") + .IsUnique(); + + b.ToTable("FarmingWeights"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.ChocolateFactory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Chocolate") + .HasColumnType("bigint"); + + b.Property("ChocolateSincePrestige") + .HasColumnType("bigint"); + + b.Property("ChocolateSpent") + .HasColumnType("bigint"); + + b.Property("CocoaFortuneUpgrades") + .HasColumnType("integer"); + + b.Property("LastViewedChocolateFactory") + .HasColumnType("bigint"); + + b.Property("Prestige") + .HasColumnType("integer"); + + b.Property("ProfileMemberId") + .HasColumnType("uuid"); + + b.Property("RefinedTrufflesConsumed") + .HasColumnType("integer"); + + b.Property("TotalChocolate") + .HasColumnType("bigint"); + + b.Property("UnlockedZorro") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("ProfileMemberId") + .IsUnique(); + + b.ToTable("ChocolateFactories"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.ContestParticipation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Collected") + .HasColumnType("integer"); + + b.Property("JacobContestId") + .HasColumnType("bigint"); + + b.Property("JacobDataId") + .HasColumnType("integer"); + + b.Property("MedalEarned") + .HasColumnType("integer"); + + b.Property("Position") + .HasColumnType("integer"); + + b.Property("ProfileMemberId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("JacobContestId"); + + b.HasIndex("JacobDataId"); + + b.HasIndex("ProfileMemberId"); + + b.ToTable("ContestParticipations"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.Garden", b => + { + b.Property("ProfileId") + .HasMaxLength(36) + .HasColumnType("character varying(36)"); + + b.Property("CompletedVisitors") + .HasColumnType("integer"); + + b.Property("Composter") + .HasColumnType("jsonb"); + + b.Property("GardenExperience") + .HasColumnType("bigint"); + + b.Property("LastUpdated") + .HasColumnType("timestamp with time zone"); + + b.Property("ProfileResponseHash") + .HasColumnType("bigint"); + + b.Property("UniqueVisitors") + .HasColumnType("integer"); + + b.Property("UnlockedPlots") + .HasColumnType("bigint"); + + b.Property>("Visitors") + .IsRequired() + .HasColumnType("jsonb"); + + b.HasKey("ProfileId"); + + b.ToTable("Gardens"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.JacobContest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Bronze") + .HasColumnType("integer"); + + b.Property("Crop") + .HasColumnType("integer"); + + b.Property("Diamond") + .HasColumnType("integer"); + + b.Property("Finnegan") + .HasColumnType("boolean"); + + b.Property("Gold") + .HasColumnType("integer"); + + b.Property("Participants") + .HasColumnType("integer"); + + b.Property("Platinum") + .HasColumnType("integer"); + + b.Property("Silver") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("Timestamp"); + + b.ToTable("JacobContests"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.JacobData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ContestsLastUpdated") + .HasColumnType("bigint"); + + b.Property("FirstPlaceScores") + .HasColumnType("integer"); + + b.Property("Participations") + .HasColumnType("integer"); + + b.Property("ProfileMemberId") + .HasColumnType("uuid"); + + b.Property("Stats") + .HasColumnType("jsonb"); + + b.HasKey("Id"); + + b.HasIndex("ProfileMemberId") + .IsUnique(); + + b.ToTable("JacobData"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.PlayerData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DisplayName") + .HasColumnType("text"); + + b.Property("FirstLogin") + .HasColumnType("bigint"); + + b.Property("Karma") + .HasColumnType("bigint"); + + b.Property("LastLogin") + .HasColumnType("bigint"); + + b.Property("LastLogout") + .HasColumnType("bigint"); + + b.Property("LastUpdated") + .HasColumnType("bigint"); + + b.Property("MonthlyPackageRank") + .HasColumnType("text"); + + b.Property("MonthlyRankColor") + .HasColumnType("text"); + + b.Property("MostRecentMonthlyPackageRank") + .HasColumnType("text"); + + b.Property("NetworkExp") + .HasColumnType("double precision"); + + b.Property("NewPackageRank") + .HasColumnType("text"); + + b.Property("PackageRank") + .HasColumnType("text"); + + b.Property("Prefix") + .HasColumnType("text"); + + b.Property("Rank") + .HasColumnType("text"); + + b.Property("RankPlusColor") + .HasColumnType("text"); + + b.Property("RewardHighScore") + .HasColumnType("integer"); + + b.Property("RewardScore") + .HasColumnType("integer"); + + b.Property("RewardStreak") + .HasColumnType("integer"); + + b.Property("TotalDailyRewards") + .HasColumnType("integer"); + + b.Property("TotalRewards") + .HasColumnType("integer"); + + b.Property("Uuid") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("Uuid") + .IsUnique(); + + b.ToTable("PlayerData"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.Profile", b => + { + b.Property("ProfileId") + .HasColumnType("text"); + + b.Property("BankBalance") + .HasColumnType("double precision"); + + b.Property>("CraftedMinions") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("GameMode") + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("LastUpdated") + .HasColumnType("bigint"); + + b.Property("MuseumLastUpdated") + .HasColumnType("bigint"); + + b.Property("ProfileName") + .IsRequired() + .HasColumnType("text"); + + b.Property("SocialXp") + .HasColumnType("double precision"); + + b.HasKey("ProfileId"); + + b.ToTable("Profiles"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.ProfileMember", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property>("CollectionTiers") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property>("Collections") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("FunctionalNetworth") + .HasColumnType("double precision"); + + b.Property("IsSelected") + .HasColumnType("boolean"); + + b.Property("LastDataChanged") + .HasColumnType("bigint"); + + b.Property("LastUpdated") + .HasColumnType("bigint"); + + b.Property("LiquidFunctionalNetworth") + .HasColumnType("double precision"); + + b.Property("LiquidNetworth") + .HasColumnType("double precision"); + + b.Property("Networth") + .HasColumnType("double precision"); + + b.Property("PersonalBank") + .HasColumnType("double precision"); + + b.Property>("Pets") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("PlayerUuid") + .IsRequired() + .HasColumnType("text"); + + b.Property("ProfileId") + .IsRequired() + .HasColumnType("text"); + + b.Property("ProfileName") + .HasColumnType("text"); + + b.Property("Purse") + .HasColumnType("double precision"); + + b.Property("ResponseHash") + .HasColumnType("bigint"); + + b.Property>("Sacks") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("SkyblockXp") + .HasColumnType("integer"); + + b.Property("Slayers") + .HasColumnType("jsonb"); + + b.Property("Unparsed") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("WasRemoved") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("PlayerUuid"); + + b.HasIndex("ProfileId"); + + b.ToTable("ProfileMembers"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.Skills", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Alchemy") + .HasColumnType("double precision"); + + b.Property("Carpentry") + .HasColumnType("double precision"); + + b.Property("Combat") + .HasColumnType("double precision"); + + b.Property("Enchanting") + .HasColumnType("double precision"); + + b.Property("Farming") + .HasColumnType("double precision"); + + b.Property("Fishing") + .HasColumnType("double precision"); + + b.Property("Foraging") + .HasColumnType("double precision"); + + b.Property>("LevelCaps") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Mining") + .HasColumnType("double precision"); + + b.Property("ProfileMemberId") + .HasColumnType("uuid"); + + b.Property("Runecrafting") + .HasColumnType("double precision"); + + b.Property("Social") + .HasColumnType("double precision"); + + b.Property("Taming") + .HasColumnType("double precision"); + + b.HasKey("Id"); + + b.HasIndex("ProfileMemberId") + .IsUnique(); + + b.ToTable("Skills"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.Category", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Description") + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("Order") + .HasColumnType("integer"); + + b.Property("Published") + .HasColumnType("boolean"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("Slug") + .IsUnique(); + + b.ToTable("Categories"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.CosmeticImage", b => + { + b.Property("CosmeticId") + .HasColumnType("integer"); + + b.Property("ImageId") + .HasColumnType("character varying(48)"); + + b.HasKey("CosmeticId", "ImageId"); + + b.HasIndex("ImageId"); + + b.ToTable("CosmeticImage"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.Product", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("Available") + .HasColumnType("boolean"); + + b.Property("Description") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("Features") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Flags") + .HasColumnType("numeric(20,0)"); + + b.Property("Icon") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Price") + .HasColumnType("integer"); + + b.Property("ReleasedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ThumbnailId") + .HasMaxLength(48) + .HasColumnType("character varying(48)"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ThumbnailId"); + + b.ToTable("Products"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.ProductCategory", b => + { + b.Property("ProductId") + .HasColumnType("numeric(20,0)"); + + b.Property("CategoryId") + .HasColumnType("integer"); + + b.Property("Order") + .HasColumnType("integer"); + + b.HasKey("ProductId", "CategoryId"); + + b.HasIndex("CategoryId"); + + b.HasIndex("Order"); + + b.ToTable("ProductCategories"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.ProductImage", b => + { + b.Property("ProductId") + .HasColumnType("numeric(20,0)"); + + b.Property("ImageId") + .HasColumnType("character varying(48)"); + + b.HasKey("ProductId", "ImageId"); + + b.HasIndex("ImageId"); + + b.ToTable("ProductImage"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.ProductTag", b => + { + b.Property("ProductId") + .HasColumnType("numeric(20,0)"); + + b.Property("TagId") + .HasColumnType("integer"); + + b.Property("Order") + .HasColumnType("integer"); + + b.HasKey("ProductId", "TagId"); + + b.HasIndex("Order"); + + b.HasIndex("TagId"); + + b.ToTable("ProductTags"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.ProductWeightStyle", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ProductId") + .HasColumnType("numeric(20,0)"); + + b.Property("WeightStyleId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.HasIndex("WeightStyleId"); + + b.ToTable("ProductCosmetics"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.Tag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Description") + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("Order") + .HasColumnType("integer"); + + b.Property("Published") + .HasColumnType("boolean"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("Slug") + .IsUnique(); + + b.ToTable("Tags"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.WeightStyle", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Collection") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Data") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Description") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("ImageId") + .HasColumnType("character varying(48)"); + + b.Property("Leaderboard") + .HasColumnType("jsonb"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("NameStyle") + .HasColumnType("jsonb"); + + b.Property("StyleFormatter") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ImageId"); + + b.HasIndex("Type"); + + b.ToTable("Cosmetics"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Timescale.CropCollection", b => + { + b.Property("Beetle") + .HasColumnType("integer"); + + b.Property("Cactus") + .HasColumnType("bigint"); + + b.Property("Carrot") + .HasColumnType("bigint"); + + b.Property("CocoaBeans") + .HasColumnType("bigint"); + + b.Property("Cricket") + .HasColumnType("integer"); + + b.Property("Dragonfly") + .HasColumnType("integer"); + + b.Property("Earthworm") + .HasColumnType("integer"); + + b.Property("Firefly") + .HasColumnType("integer"); + + b.Property("Fly") + .HasColumnType("integer"); + + b.Property("Locust") + .HasColumnType("integer"); + + b.Property("Mantis") + .HasColumnType("integer"); + + b.Property("Melon") + .HasColumnType("bigint"); + + b.Property("Mite") + .HasColumnType("integer"); + + b.Property("Moonflower") + .HasColumnType("bigint"); + + b.Property("Mosquito") + .HasColumnType("integer"); + + b.Property("Moth") + .HasColumnType("integer"); + + b.Property("Mouse") + .HasColumnType("integer"); + + b.Property("Mushroom") + .HasColumnType("bigint"); + + b.Property("NetherWart") + .HasColumnType("bigint"); + + b.Property("Potato") + .HasColumnType("bigint"); + + b.Property("ProfileMemberId") + .HasColumnType("uuid"); + + b.Property("Pumpkin") + .HasColumnType("bigint"); + + b.Property("Rat") + .HasColumnType("integer"); + + b.Property("Seeds") + .HasColumnType("bigint"); + + b.Property("Slug") + .HasColumnType("integer"); + + b.Property("SugarCane") + .HasColumnType("bigint"); + + b.Property("Sunflower") + .HasColumnType("bigint"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.Property("Wheat") + .HasColumnType("bigint"); + + b.Property("WildRose") + .HasColumnType("bigint"); + + b.HasIndex("ProfileMemberId"); + + b.ToTable("CropCollections"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Timescale.SkillExperience", b => + { + b.Property("Alchemy") + .HasColumnType("double precision"); + + b.Property("Carpentry") + .HasColumnType("double precision"); + + b.Property("Combat") + .HasColumnType("double precision"); + + b.Property("Enchanting") + .HasColumnType("double precision"); + + b.Property("Farming") + .HasColumnType("double precision"); + + b.Property("Fishing") + .HasColumnType("double precision"); + + b.Property("Foraging") + .HasColumnType("double precision"); + + b.Property("Mining") + .HasColumnType("double precision"); + + b.Property("ProfileMemberId") + .HasColumnType("uuid"); + + b.Property("Runecrafting") + .HasColumnType("double precision"); + + b.Property("Social") + .HasColumnType("double precision"); + + b.Property("Taming") + .HasColumnType("double precision"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasIndex("ProfileMemberId"); + + b.ToTable("SkillExperiences"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + + b.HasData( + new + { + Id = "8270a1b1-5809-436a-ba1c-b712f4f55f67", + ConcurrencyStamp = "11d759b6-025f-4334-b8fc-3b26a72cda87", + Name = "Admin", + NormalizedName = "ADMIN" + }, + new + { + Id = "3384aba1-5453-4787-81d9-0b7222225d81", + ConcurrencyStamp = "34eb8585-7920-4f4c-857a-e5d131a835ef", + Name = "Moderator", + NormalizedName = "MODERATOR" + }, + new + { + Id = "d8c803c1-63a0-4594-8d68-aad7bd59df7d", + ConcurrencyStamp = "e0e6b08b-7cd1-4f8c-b827-cab959ebc9be", + Name = "Support", + NormalizedName = "SUPPORT" + }, + new + { + Id = "ff4f5319-644e-4332-8bd5-2ec989ba5e7f", + ConcurrencyStamp = "e4ec974b-71af-4307-8bf0-3feb9f380566", + Name = "Wiki", + NormalizedName = "WIKI" + }, + new + { + Id = "e99efab5-3fd2-416e-b8f5-93b0370892ac", + ConcurrencyStamp = "c9ad7f78-129a-4507-ace1-5a71c221a901", + Name = "User", + NormalizedName = "USER" + }); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("ProviderKey") + .HasColumnType("text"); + + b.Property("ProviderDisplayName") + .HasColumnType("text"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("text"); + + b.Property("RoleId") + .HasColumnType("text"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("text"); + + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Value") + .HasColumnType("text"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("EliteAPI.Features.Monetization.Models.GuildEntitlement", b => + { + b.HasBaseType("EliteAPI.Features.Monetization.Models.Entitlement"); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.HasIndex("GuildId"); + + b.HasDiscriminator().HasValue(1); + }); + + modelBuilder.Entity("EliteAPI.Features.Monetization.Models.UserEntitlement", b => + { + b.HasBaseType("EliteAPI.Features.Monetization.Models.Entitlement"); + + b.Property("AccountId") + .HasMaxLength(22) + .HasColumnType("numeric(20,0)"); + + b.HasIndex("AccountId"); + + b.HasDiscriminator().HasValue(2); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.CollectionEvent", b => + { + b.HasBaseType("EliteAPI.Models.Entities.Events.Event"); + + b.Property("Data") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("jsonb") + .HasColumnName("Data"); + + b.HasDiscriminator().HasValue(2); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.MedalEvent", b => + { + b.HasBaseType("EliteAPI.Models.Entities.Events.Event"); + + b.Property("Data") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("jsonb") + .HasColumnName("Data"); + + b.HasDiscriminator().HasValue(4); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.PestEvent", b => + { + b.HasBaseType("EliteAPI.Models.Entities.Events.Event"); + + b.Property("Data") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("jsonb") + .HasColumnName("Data"); + + b.HasDiscriminator().HasValue(5); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.WeightEvent", b => + { + b.HasBaseType("EliteAPI.Models.Entities.Events.Event"); + + b.Property("Data") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("jsonb") + .HasColumnName("Data"); + + b.HasDiscriminator().HasValue(1); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.CollectionEventMember", b => + { + b.HasBaseType("EliteAPI.Models.Entities.Events.EventMember"); + + b.Property("Data") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("jsonb") + .HasColumnName("Data"); + + b.HasDiscriminator().HasValue(2); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.MedalEventMember", b => + { + b.HasBaseType("EliteAPI.Models.Entities.Events.EventMember"); + + b.Property("Data") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("jsonb") + .HasColumnName("Data"); + + b.HasDiscriminator().HasValue(4); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.PestEventMember", b => + { + b.HasBaseType("EliteAPI.Models.Entities.Events.EventMember"); + + b.Property("Data") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("jsonb") + .HasColumnName("Data"); + + b.HasDiscriminator().HasValue(5); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.WeightEventMember", b => + { + b.HasBaseType("EliteAPI.Models.Entities.Events.EventMember"); + + b.Property("Data") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("jsonb") + .HasColumnName("Data"); + + b.HasDiscriminator().HasValue(1); + }); + + modelBuilder.Entity("EliteAPI.Features.Account.Models.Badge", b => + { + b.HasOne("EliteAPI.Features.Images.Models.Image", "Image") + .WithMany() + .HasForeignKey("ImageId"); + + b.Navigation("Image"); + }); + + modelBuilder.Entity("EliteAPI.Features.Account.Models.EliteAccount", b => + { + b.HasOne("EliteAPI.Features.Account.Models.UserSettings", "UserSettings") + .WithMany() + .HasForeignKey("UserSettingsId"); + + b.Navigation("UserSettings"); + }); + + modelBuilder.Entity("EliteAPI.Features.Account.Models.MinecraftAccount", b => + { + b.HasOne("EliteAPI.Features.Account.Models.EliteAccount", "EliteAccount") + .WithMany("MinecraftAccounts") + .HasForeignKey("AccountId"); + + b.Navigation("EliteAccount"); + }); + + modelBuilder.Entity("EliteAPI.Features.Account.Models.UserBadge", b => + { + b.HasOne("EliteAPI.Features.Account.Models.Badge", "Badge") + .WithMany() + .HasForeignKey("BadgeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Features.Account.Models.MinecraftAccount", "MinecraftAccount") + .WithMany("Badges") + .HasForeignKey("MinecraftAccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Badge"); + + b.Navigation("MinecraftAccount"); + }); + + modelBuilder.Entity("EliteAPI.Features.Account.Models.UserSettings", b => + { + b.HasOne("EliteAPI.Models.Entities.Monetization.WeightStyle", "LeaderboardStyle") + .WithMany() + .HasForeignKey("LeaderboardStyleId"); + + b.HasOne("EliteAPI.Models.Entities.Monetization.WeightStyle", "NameStyle") + .WithMany() + .HasForeignKey("NameStyleId"); + + b.HasOne("EliteAPI.Models.Entities.Monetization.WeightStyle", "WeightStyle") + .WithMany() + .HasForeignKey("WeightStyleId"); + + b.Navigation("LeaderboardStyle"); + + b.Navigation("NameStyle"); + + b.Navigation("WeightStyle"); + }); + + modelBuilder.Entity("EliteAPI.Features.Announcements.Models.DismissedAnnouncement", b => + { + b.HasOne("EliteAPI.Features.Account.Models.EliteAccount", "EliteAccount") + .WithMany("DismissedAnnouncements") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Features.Announcements.Models.Announcement", "Announcement") + .WithMany() + .HasForeignKey("AnnouncementId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Announcement"); + + b.Navigation("EliteAccount"); + }); + + modelBuilder.Entity("EliteAPI.Features.AuditLogs.Models.AdminAuditLog", b => + { + b.HasOne("EliteAPI.Features.Account.Models.EliteAccount", "AdminUser") + .WithMany() + .HasForeignKey("AdminUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AdminUser"); + }); + + modelBuilder.Entity("EliteAPI.Features.Auth.Models.ApiUser", b => + { + b.HasOne("EliteAPI.Features.Account.Models.EliteAccount", "Account") + .WithMany() + .HasForeignKey("AccountId"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("EliteAPI.Features.Auth.Models.RefreshToken", b => + { + b.HasOne("EliteAPI.Features.Auth.Models.ApiUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("EliteAPI.Features.Confirmations.Models.UserConfirmation", b => + { + b.HasOne("EliteAPI.Features.Confirmations.Models.Confirmation", "Confirmation") + .WithMany("UserConfirmations") + .HasForeignKey("ConfirmationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Features.Auth.Models.ApiUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Confirmation"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("EliteAPI.Features.Guides.Models.Comment", b => + { + b.HasOne("EliteAPI.Features.Account.Models.EliteAccount", "Author") + .WithMany() + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Features.Guides.Models.Comment", "Parent") + .WithMany("Replies") + .HasForeignKey("ParentId"); + + b.Navigation("Author"); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("EliteAPI.Features.Guides.Models.CommentVote", b => + { + b.HasOne("EliteAPI.Features.Guides.Models.Comment", "Comment") + .WithMany("Votes") + .HasForeignKey("CommentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Features.Account.Models.EliteAccount", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Comment"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("EliteAPI.Features.Guides.Models.Guide", b => + { + b.HasOne("EliteAPI.Features.Guides.Models.GuideVersion", "ActiveVersion") + .WithOne() + .HasForeignKey("EliteAPI.Features.Guides.Models.Guide", "ActiveVersionId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("EliteAPI.Features.Account.Models.EliteAccount", "Author") + .WithMany() + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Features.Guides.Models.GuideVersion", "DraftVersion") + .WithOne() + .HasForeignKey("EliteAPI.Features.Guides.Models.Guide", "DraftVersionId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("ActiveVersion"); + + b.Navigation("Author"); + + b.Navigation("DraftVersion"); + }); + + modelBuilder.Entity("EliteAPI.Features.Guides.Models.GuideBookmark", b => + { + b.HasOne("EliteAPI.Features.Guides.Models.Guide", "Guide") + .WithMany() + .HasForeignKey("GuideId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Guide"); + }); + + modelBuilder.Entity("EliteAPI.Features.Guides.Models.GuideTagMapping", b => + { + b.HasOne("EliteAPI.Features.Guides.Models.Guide", "Guide") + .WithMany("Tags") + .HasForeignKey("GuideId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Features.Guides.Models.GuideTag", "Tag") + .WithMany("Guides") + .HasForeignKey("TagId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Guide"); + + b.Navigation("Tag"); + }); + + modelBuilder.Entity("EliteAPI.Features.Guides.Models.GuideVersion", b => + { + b.HasOne("EliteAPI.Features.Guides.Models.Guide", "Guide") + .WithMany("Versions") + .HasForeignKey("GuideId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Guide"); + }); + + modelBuilder.Entity("EliteAPI.Features.Guides.Models.GuideVote", b => + { + b.HasOne("EliteAPI.Features.Guides.Models.Guide", "Guide") + .WithMany("Votes") + .HasForeignKey("GuideId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Features.Account.Models.EliteAccount", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Guide"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("EliteAPI.Features.HypixelGuilds.Models.HypixelGuildMember", b => + { + b.HasOne("EliteAPI.Features.HypixelGuilds.Models.HypixelGuild", "Guild") + .WithMany("Members") + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Features.Account.Models.MinecraftAccount", "MinecraftAccount") + .WithMany("GuildMembers") + .HasForeignKey("PlayerUuid") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Guild"); + + b.Navigation("MinecraftAccount"); + }); + + modelBuilder.Entity("EliteAPI.Features.HypixelGuilds.Models.HypixelGuildMemberExp", b => + { + b.HasOne("EliteAPI.Features.HypixelGuilds.Models.HypixelGuildMember", null) + .WithMany("ExpHistory") + .HasForeignKey("GuildMemberId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("EliteAPI.Features.HypixelGuilds.Models.HypixelGuildStats", b => + { + b.HasOne("EliteAPI.Features.HypixelGuilds.Models.HypixelGuild", null) + .WithMany("Stats") + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("EliteAPI.Features.HypixelGuilds.Models.HypixelGuildStat", "CatacombsExperience", b1 => + { + b1.Property("HypixelGuildStatsId") + .HasColumnType("bigint"); + + b1.Property("Average") + .HasColumnType("double precision"); + + b1.Property("Total") + .HasColumnType("double precision"); + + b1.HasKey("HypixelGuildStatsId"); + + b1.HasIndex("Total"); + + b1.ToTable("HypixelGuildStats"); + + b1.WithOwner() + .HasForeignKey("HypixelGuildStatsId"); + }); + + b.OwnsOne("EliteAPI.Features.HypixelGuilds.Models.HypixelGuildStat", "FarmingWeight", b1 => + { + b1.Property("HypixelGuildStatsId") + .HasColumnType("bigint"); + + b1.Property("Average") + .HasColumnType("double precision"); + + b1.Property("Total") + .HasColumnType("double precision"); + + b1.HasKey("HypixelGuildStatsId"); + + b1.HasIndex("Total"); + + b1.ToTable("HypixelGuildStats"); + + b1.WithOwner() + .HasForeignKey("HypixelGuildStatsId"); + }); + + b.OwnsOne("EliteAPI.Features.HypixelGuilds.Models.HypixelGuildStat", "HypixelLevel", b1 => + { + b1.Property("HypixelGuildStatsId") + .HasColumnType("bigint"); + + b1.Property("Average") + .HasColumnType("double precision"); + + b1.Property("Total") + .HasColumnType("double precision"); + + b1.HasKey("HypixelGuildStatsId"); + + b1.HasIndex("Total"); + + b1.ToTable("HypixelGuildStats"); + + b1.WithOwner() + .HasForeignKey("HypixelGuildStatsId"); + }); + + b.OwnsOne("EliteAPI.Features.HypixelGuilds.Models.HypixelGuildStat", "Networth", b1 => + { + b1.Property("HypixelGuildStatsId") + .HasColumnType("bigint"); + + b1.Property("Average") + .HasColumnType("double precision"); + + b1.Property("Total") + .HasColumnType("double precision"); + + b1.HasKey("HypixelGuildStatsId"); + + b1.HasIndex("Average"); + + b1.HasIndex("Total"); + + b1.ToTable("HypixelGuildStats"); + + b1.WithOwner() + .HasForeignKey("HypixelGuildStatsId"); + }); + + b.OwnsOne("EliteAPI.Features.HypixelGuilds.Models.HypixelGuildStat", "SkillLevel", b1 => + { + b1.Property("HypixelGuildStatsId") + .HasColumnType("bigint"); + + b1.Property("Average") + .HasColumnType("double precision"); + + b1.Property("Total") + .HasColumnType("double precision"); + + b1.HasKey("HypixelGuildStatsId"); + + b1.HasIndex("Average"); + + b1.HasIndex("Total"); + + b1.ToTable("HypixelGuildStats"); + + b1.WithOwner() + .HasForeignKey("HypixelGuildStatsId"); + }); + + b.OwnsOne("EliteAPI.Features.HypixelGuilds.Models.HypixelGuildStat", "SkyblockExperience", b1 => + { + b1.Property("HypixelGuildStatsId") + .HasColumnType("bigint"); + + b1.Property("Average") + .HasColumnType("double precision"); + + b1.Property("Total") + .HasColumnType("double precision"); + + b1.HasKey("HypixelGuildStatsId"); + + b1.HasIndex("Average"); + + b1.HasIndex("Total"); + + b1.ToTable("HypixelGuildStats"); + + b1.WithOwner() + .HasForeignKey("HypixelGuildStatsId"); + }); + + b.OwnsOne("EliteAPI.Features.HypixelGuilds.Models.HypixelGuildStat", "SlayerExperience", b1 => + { + b1.Property("HypixelGuildStatsId") + .HasColumnType("bigint"); + + b1.Property("Average") + .HasColumnType("double precision"); + + b1.Property("Total") + .HasColumnType("double precision"); + + b1.HasKey("HypixelGuildStatsId"); + + b1.HasIndex("Total"); + + b1.ToTable("HypixelGuildStats"); + + b1.WithOwner() + .HasForeignKey("HypixelGuildStatsId"); + }); + + b.Navigation("CatacombsExperience") + .IsRequired(); + + b.Navigation("FarmingWeight") + .IsRequired(); + + b.Navigation("HypixelLevel") + .IsRequired(); + + b.Navigation("Networth") + .IsRequired(); + + b.Navigation("SkillLevel") + .IsRequired(); + + b.Navigation("SkyblockExperience") + .IsRequired(); + + b.Navigation("SlayerExperience") + .IsRequired(); + }); + + modelBuilder.Entity("EliteAPI.Features.Leaderboards.Models.Leaderboard", b => + { + b.HasOne("EliteAPI.Features.Images.Models.Image", "Icon") + .WithMany() + .HasForeignKey("IconId"); + + b.Navigation("Icon"); + }); + + modelBuilder.Entity("EliteAPI.Features.Leaderboards.Models.LeaderboardEntry", b => + { + b.HasOne("EliteAPI.Features.Leaderboards.Models.Leaderboard", "Leaderboard") + .WithMany() + .HasForeignKey("LeaderboardId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Models.Entities.Hypixel.Profile", "Profile") + .WithMany() + .HasForeignKey("ProfileId"); + + b.HasOne("EliteAPI.Models.Entities.Hypixel.ProfileMember", "ProfileMember") + .WithMany() + .HasForeignKey("ProfileMemberId"); + + b.Navigation("Leaderboard"); + + b.Navigation("Profile"); + + b.Navigation("ProfileMember"); + }); + + modelBuilder.Entity("EliteAPI.Features.Leaderboards.Models.LeaderboardSnapshot", b => + { + b.HasOne("EliteAPI.Features.Leaderboards.Models.Leaderboard", "Leaderboard") + .WithMany() + .HasForeignKey("LeaderboardId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Leaderboard"); + }); + + modelBuilder.Entity("EliteAPI.Features.Leaderboards.Models.LeaderboardSnapshotEntry", b => + { + b.HasOne("EliteAPI.Features.Leaderboards.Models.LeaderboardSnapshot", "LeaderboardSnapshot") + .WithMany() + .HasForeignKey("LeaderboardSnapshotId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("LeaderboardSnapshot"); + }); + + modelBuilder.Entity("EliteAPI.Features.Leaderboards.Models.ProfileMemberMetadata", b => + { + b.HasOne("EliteAPI.Models.Entities.Hypixel.ProfileMember", "ProfileMember") + .WithOne("Metadata") + .HasForeignKey("EliteAPI.Features.Leaderboards.Models.ProfileMemberMetadata", "ProfileMemberId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("EliteAPI.Features.Leaderboards.Models.ProfileMemberMetadataCosmetics", "Cosmetics", b1 => + { + b1.Property("ProfileMemberMetadataProfileMemberId"); + + b1.Property("Prefix") + .HasMaxLength(16); + + b1.Property("Suffix") + .HasMaxLength(16); + + b1.HasKey("ProfileMemberMetadataProfileMemberId"); + + b1.ToTable("ProfileMemberMetadata"); + + b1.ToJson("Cosmetics"); + + b1.WithOwner() + .HasForeignKey("ProfileMemberMetadataProfileMemberId"); + + b1.OwnsOne("EliteAPI.Features.Leaderboards.Models.MemberLeaderboardCosmeticsDto", "Leaderboard", b2 => + { + b2.Property("ProfileMemberMetadataCosmeticsProfileMemberMetadataProfileMemberId") + .HasColumnName("ProfileMemberMetadataCosmeticsProfileMemberMetadataProfileMemb~"); + + b2.Property("BackgroundColor"); + + b2.Property("BackgroundImage"); + + b2.Property("BorderColor"); + + b2.Property("OverlayImage"); + + b2.Property("RankColor"); + + b2.Property("StyleId"); + + b2.Property("TextColor"); + + b2.HasKey("ProfileMemberMetadataCosmeticsProfileMemberMetadataProfileMemberId"); + + b2.ToTable("ProfileMemberMetadata"); + + b2.WithOwner() + .HasForeignKey("ProfileMemberMetadataCosmeticsProfileMemberMetadataProfileMemberId"); + }); + + b1.Navigation("Leaderboard"); + }); + + b.Navigation("Cosmetics"); + + b.Navigation("ProfileMember"); + }); + + modelBuilder.Entity("EliteAPI.Features.Monetization.Models.Entitlement", b => + { + b.HasOne("EliteAPI.Models.Entities.Monetization.Product", "Product") + .WithMany() + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Product"); + }); + + modelBuilder.Entity("EliteAPI.Features.Monetization.Models.ProductAccess", b => + { + b.HasOne("EliteAPI.Models.Entities.Discord.Guild", "Guild") + .WithMany() + .HasForeignKey("GuildId"); + + b.HasOne("EliteAPI.Models.Entities.Monetization.Product", "Product") + .WithMany() + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Features.Monetization.Models.ShopOrder", "SourceOrder") + .WithMany() + .HasForeignKey("SourceOrderId"); + + b.HasOne("EliteAPI.Features.Account.Models.EliteAccount", "User") + .WithMany("ProductAccesses") + .HasForeignKey("UserId"); + + b.Navigation("Guild"); + + b.Navigation("Product"); + + b.Navigation("SourceOrder"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("EliteAPI.Features.Monetization.Models.ShopOrder", b => + { + b.HasOne("EliteAPI.Features.Account.Models.EliteAccount", "Buyer") + .WithMany() + .HasForeignKey("BuyerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Models.Entities.Discord.Guild", "RecipientGuild") + .WithMany() + .HasForeignKey("RecipientGuildId"); + + b.HasOne("EliteAPI.Features.Account.Models.EliteAccount", "Recipient") + .WithMany() + .HasForeignKey("RecipientId"); + + b.Navigation("Buyer"); + + b.Navigation("Recipient"); + + b.Navigation("RecipientGuild"); + }); + + modelBuilder.Entity("EliteAPI.Features.Monetization.Models.ShopOrderItem", b => + { + b.HasOne("EliteAPI.Features.Monetization.Models.ShopOrder", "ShopOrder") + .WithMany("OrderItems") + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Models.Entities.Monetization.Product", "Product") + .WithMany() + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Product"); + + b.Navigation("ShopOrder"); + }); + + modelBuilder.Entity("EliteAPI.Features.Notifications.Models.Notification", b => + { + b.HasOne("EliteAPI.Features.Account.Models.EliteAccount", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("EliteAPI.Features.Profiles.Models.GameModeHistory", b => + { + b.HasOne("EliteAPI.Models.Entities.Hypixel.Profile", null) + .WithMany() + .HasForeignKey("ProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("EliteAPI.Features.Profiles.Models.HypixelInventory", b => + { + b.HasOne("EliteAPI.Models.Entities.Hypixel.ProfileMember", null) + .WithMany("Inventories") + .HasForeignKey("ProfileMemberId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("EliteAPI.Features.Profiles.Models.HypixelItem", b => + { + b.HasOne("EliteAPI.Features.Profiles.Models.HypixelInventory", null) + .WithMany("Items") + .HasForeignKey("InventoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("EliteAPI.Features.Recap.Models.YearlyRecap", b => + { + b.HasOne("EliteAPI.Models.Entities.Hypixel.ProfileMember", "ProfileMember") + .WithMany() + .HasForeignKey("ProfileMemberId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ProfileMember"); + }); + + modelBuilder.Entity("EliteAPI.Features.Resources.Auctions.Models.Auction", b => + { + b.HasOne("EliteAPI.Models.Entities.Hypixel.ProfileMember", null) + .WithMany() + .HasForeignKey("BuyerProfileMemberId"); + + b.HasOne("EliteAPI.Models.Entities.Hypixel.ProfileMember", null) + .WithMany("Auctions") + .HasForeignKey("SellerProfileMemberId"); + }); + + modelBuilder.Entity("EliteAPI.Features.Resources.Auctions.Models.AuctionItem", b => + { + b.HasOne("EliteAPI.Features.Resources.Items.Models.SkyblockItem", null) + .WithMany("AuctionItems") + .HasForeignKey("SkyblockId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("EliteAPI.Features.Resources.Auctions.Models.AuctionSubscription", b => + { + b.HasOne("EliteAPI.Features.Account.Models.EliteAccount", null) + .WithMany() + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Models.Entities.Hypixel.ProfileMember", null) + .WithMany() + .HasForeignKey("ProfileMemberId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("EliteAPI.Features.Resources.Bazaar.BazaarProductSummary", b => + { + b.HasOne("EliteAPI.Features.Resources.Items.Models.SkyblockItem", "SkyblockItem") + .WithOne("BazaarProductSummary") + .HasForeignKey("EliteAPI.Features.Resources.Bazaar.BazaarProductSummary", "ItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("SkyblockItem"); + }); + + modelBuilder.Entity("EliteAPI.Features.Resources.Firesales.Models.SkyblockFiresaleItem", b => + { + b.HasOne("EliteAPI.Features.Resources.Firesales.Models.SkyblockFiresale", null) + .WithMany("Items") + .HasForeignKey("FiresaleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Discord.Guild", b => + { + b.HasOne("EliteAPI.Features.Images.Models.Image", "Banner") + .WithMany() + .HasForeignKey("BannerId"); + + b.HasOne("EliteAPI.Features.Images.Models.Image", "Icon") + .WithMany() + .HasForeignKey("IconId"); + + b.Navigation("Banner"); + + b.Navigation("Icon"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Discord.GuildChannel", b => + { + b.HasOne("EliteAPI.Models.Entities.Discord.Guild", "Guild") + .WithMany("Channels") + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Guild"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Discord.GuildMember", b => + { + b.HasOne("EliteAPI.Features.Auth.Models.ApiUser", "Account") + .WithMany("GuildMemberships") + .HasForeignKey("AccountId"); + + b.HasOne("EliteAPI.Models.Entities.Discord.Guild", "Guild") + .WithMany() + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("Guild"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Discord.GuildRole", b => + { + b.HasOne("EliteAPI.Models.Entities.Discord.Guild", "Guild") + .WithMany("Roles") + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Guild"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.Event", b => + { + b.HasOne("EliteAPI.Features.Images.Models.Image", "Banner") + .WithMany() + .HasForeignKey("BannerId"); + + b.HasOne("EliteAPI.Models.Entities.Discord.Guild", "Guild") + .WithMany() + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Banner"); + + b.Navigation("Guild"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.EventMember", b => + { + b.HasOne("EliteAPI.Models.Entities.Events.Event", "Event") + .WithMany() + .HasForeignKey("EventId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Models.Entities.Hypixel.ProfileMember", "ProfileMember") + .WithMany("EventEntries") + .HasForeignKey("ProfileMemberId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Models.Entities.Events.EventTeam", "Team") + .WithMany("Members") + .HasForeignKey("TeamId"); + + b.HasOne("EliteAPI.Features.Account.Models.EliteAccount", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Event"); + + b.Navigation("ProfileMember"); + + b.Navigation("Team"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.EventTeam", b => + { + b.HasOne("EliteAPI.Models.Entities.Events.Event", "Event") + .WithMany("Teams") + .HasForeignKey("EventId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Event"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Farming.Farming", b => + { + b.HasOne("EliteAPI.Models.Entities.Hypixel.ProfileMember", "ProfileMember") + .WithOne("Farming") + .HasForeignKey("EliteAPI.Models.Entities.Farming.Farming", "ProfileMemberId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("EliteAPI.Models.Entities.Farming.Pests", "Pests", b1 => + { + b1.Property("FarmingId") + .HasColumnType("integer"); + + b1.Property("Beetle") + .HasColumnType("integer"); + + b1.Property("Cricket") + .HasColumnType("integer"); + + b1.Property("Dragonfly") + .HasColumnType("integer"); + + b1.Property("Earthworm") + .HasColumnType("integer"); + + b1.Property("Firefly") + .HasColumnType("integer"); + + b1.Property("Fly") + .HasColumnType("integer"); + + b1.Property("Locust") + .HasColumnType("integer"); + + b1.Property("Mantis") + .HasColumnType("integer"); + + b1.Property("Mite") + .HasColumnType("integer"); + + b1.Property("Mosquito") + .HasColumnType("integer"); + + b1.Property("Moth") + .HasColumnType("integer"); + + b1.Property("Mouse") + .HasColumnType("integer"); + + b1.Property("Rat") + .HasColumnType("integer"); + + b1.Property("Slug") + .HasColumnType("integer"); + + b1.HasKey("FarmingId"); + + b1.ToTable("FarmingWeights"); + + b1.WithOwner() + .HasForeignKey("FarmingId"); + }); + + b.Navigation("Pests") + .IsRequired(); + + b.Navigation("ProfileMember"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.ChocolateFactory", b => + { + b.HasOne("EliteAPI.Models.Entities.Hypixel.ProfileMember", "ProfileMember") + .WithOne("ChocolateFactory") + .HasForeignKey("EliteAPI.Models.Entities.Hypixel.ChocolateFactory", "ProfileMemberId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("EliteAPI.Models.Entities.Hypixel.ChocolateFactoryRabbits", "TotalRabbits", b1 => + { + b1.Property("ChocolateFactoryId") + .HasColumnType("integer"); + + b1.Property("Common") + .HasColumnType("integer"); + + b1.Property("Divine") + .HasColumnType("integer"); + + b1.Property("Epic") + .HasColumnType("integer"); + + b1.Property("Legendary") + .HasColumnType("integer"); + + b1.Property("Mythic") + .HasColumnType("integer"); + + b1.Property("Rare") + .HasColumnType("integer"); + + b1.Property("Uncommon") + .HasColumnType("integer"); + + b1.HasKey("ChocolateFactoryId"); + + b1.ToTable("ChocolateFactories"); + + b1.WithOwner() + .HasForeignKey("ChocolateFactoryId"); + }); + + b.OwnsOne("EliteAPI.Models.Entities.Hypixel.ChocolateFactoryRabbits", "UniqueRabbits", b1 => + { + b1.Property("ChocolateFactoryId") + .HasColumnType("integer"); + + b1.Property("Common") + .HasColumnType("integer"); + + b1.Property("Divine") + .HasColumnType("integer"); + + b1.Property("Epic") + .HasColumnType("integer"); + + b1.Property("Legendary") + .HasColumnType("integer"); + + b1.Property("Mythic") + .HasColumnType("integer"); + + b1.Property("Rare") + .HasColumnType("integer"); + + b1.Property("Uncommon") + .HasColumnType("integer"); + + b1.HasKey("ChocolateFactoryId"); + + b1.ToTable("ChocolateFactories"); + + b1.WithOwner() + .HasForeignKey("ChocolateFactoryId"); + }); + + b.Navigation("ProfileMember"); + + b.Navigation("TotalRabbits") + .IsRequired(); + + b.Navigation("UniqueRabbits") + .IsRequired(); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.ContestParticipation", b => + { + b.HasOne("EliteAPI.Models.Entities.Hypixel.JacobContest", "JacobContest") + .WithMany() + .HasForeignKey("JacobContestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Models.Entities.Hypixel.JacobData", null) + .WithMany("Contests") + .HasForeignKey("JacobDataId"); + + b.HasOne("EliteAPI.Models.Entities.Hypixel.ProfileMember", "ProfileMember") + .WithMany() + .HasForeignKey("ProfileMemberId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("JacobContest"); + + b.Navigation("ProfileMember"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.Garden", b => + { + b.HasOne("EliteAPI.Models.Entities.Hypixel.Profile", "Profile") + .WithOne("Garden") + .HasForeignKey("EliteAPI.Models.Entities.Hypixel.Garden", "ProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("EliteAPI.Models.Entities.Hypixel.CropUpgrades", "Upgrades", b1 => + { + b1.Property("GardenProfileId") + .HasColumnType("character varying(36)"); + + b1.Property("Cactus") + .HasColumnType("smallint"); + + b1.Property("Carrot") + .HasColumnType("smallint"); + + b1.Property("CocoaBeans") + .HasColumnType("smallint"); + + b1.Property("Melon") + .HasColumnType("smallint"); + + b1.Property("Moonflower") + .HasColumnType("smallint"); + + b1.Property("Mushroom") + .HasColumnType("smallint"); + + b1.Property("NetherWart") + .HasColumnType("smallint"); + + b1.Property("Potato") + .HasColumnType("smallint"); + + b1.Property("Pumpkin") + .HasColumnType("smallint"); + + b1.Property("SugarCane") + .HasColumnType("smallint"); + + b1.Property("Sunflower") + .HasColumnType("smallint"); + + b1.Property("Wheat") + .HasColumnType("smallint"); + + b1.Property("WildRose") + .HasColumnType("smallint"); + + b1.HasKey("GardenProfileId"); + + b1.ToTable("Gardens"); + + b1.WithOwner() + .HasForeignKey("GardenProfileId"); + }); + + b.OwnsOne("EliteAPI.Models.Entities.Hypixel.MilestoneCrops", "Crops", b1 => + { + b1.Property("GardenProfileId") + .HasColumnType("character varying(36)"); + + b1.Property("Cactus") + .HasColumnType("bigint"); + + b1.Property("Carrot") + .HasColumnType("bigint"); + + b1.Property("CocoaBeans") + .HasColumnType("bigint"); + + b1.Property("Melon") + .HasColumnType("bigint"); + + b1.Property("Moonflower") + .HasColumnType("bigint"); + + b1.Property("Mushroom") + .HasColumnType("bigint"); + + b1.Property("NetherWart") + .HasColumnType("bigint"); + + b1.Property("Potato") + .HasColumnType("bigint"); + + b1.Property("Pumpkin") + .HasColumnType("bigint"); + + b1.Property("SugarCane") + .HasColumnType("bigint"); + + b1.Property("Sunflower") + .HasColumnType("bigint"); + + b1.Property("Wheat") + .HasColumnType("bigint"); + + b1.Property("WildRose") + .HasColumnType("bigint"); + + b1.HasKey("GardenProfileId"); + + b1.ToTable("Gardens"); + + b1.WithOwner() + .HasForeignKey("GardenProfileId"); + }); + + b.Navigation("Crops") + .IsRequired(); + + b.Navigation("Profile"); + + b.Navigation("Upgrades") + .IsRequired(); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.JacobData", b => + { + b.HasOne("EliteAPI.Models.Entities.Hypixel.ProfileMember", "ProfileMember") + .WithOne("JacobData") + .HasForeignKey("EliteAPI.Models.Entities.Hypixel.JacobData", "ProfileMemberId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("EliteAPI.Models.Entities.Hypixel.EarnedMedalInventory", "EarnedMedals", b1 => + { + b1.Property("JacobDataId") + .HasColumnType("integer"); + + b1.Property("Bronze") + .HasColumnType("integer"); + + b1.Property("Diamond") + .HasColumnType("integer"); + + b1.Property("Gold") + .HasColumnType("integer"); + + b1.Property("Platinum") + .HasColumnType("integer"); + + b1.Property("Silver") + .HasColumnType("integer"); + + b1.HasKey("JacobDataId"); + + b1.ToTable("JacobData"); + + b1.WithOwner() + .HasForeignKey("JacobDataId"); + }); + + b.OwnsOne("EliteAPI.Models.Entities.Hypixel.JacobPerks", "Perks", b1 => + { + b1.Property("JacobDataId") + .HasColumnType("integer"); + + b1.Property("DoubleDrops") + .HasColumnType("integer"); + + b1.Property("LevelCap") + .HasColumnType("integer"); + + b1.Property("PersonalBests") + .HasColumnType("boolean"); + + b1.HasKey("JacobDataId"); + + b1.ToTable("JacobData"); + + b1.WithOwner() + .HasForeignKey("JacobDataId"); + }); + + b.OwnsOne("EliteAPI.Models.Entities.Hypixel.MedalInventory", "Medals", b1 => + { + b1.Property("JacobDataId") + .HasColumnType("integer"); + + b1.Property("Bronze") + .HasColumnType("integer"); + + b1.Property("Gold") + .HasColumnType("integer"); + + b1.Property("Silver") + .HasColumnType("integer"); + + b1.HasKey("JacobDataId"); + + b1.ToTable("JacobData"); + + b1.WithOwner() + .HasForeignKey("JacobDataId"); + }); + + b.Navigation("EarnedMedals") + .IsRequired(); + + b.Navigation("Medals") + .IsRequired(); + + b.Navigation("Perks") + .IsRequired(); + + b.Navigation("ProfileMember"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.PlayerData", b => + { + b.HasOne("EliteAPI.Features.Account.Models.MinecraftAccount", "MinecraftAccount") + .WithOne("PlayerData") + .HasForeignKey("EliteAPI.Models.Entities.Hypixel.PlayerData", "Uuid") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("EliteAPI.Models.Entities.Hypixel.SocialMediaLinks", "SocialMedia", b1 => + { + b1.Property("PlayerDataId") + .HasColumnType("integer"); + + b1.Property("Discord") + .HasColumnType("text"); + + b1.Property("Hypixel") + .HasColumnType("text"); + + b1.Property("Youtube") + .HasColumnType("text"); + + b1.HasKey("PlayerDataId"); + + b1.ToTable("PlayerData"); + + b1.WithOwner() + .HasForeignKey("PlayerDataId"); + }); + + b.Navigation("MinecraftAccount"); + + b.Navigation("SocialMedia") + .IsRequired(); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.ProfileMember", b => + { + b.HasOne("EliteAPI.Features.Account.Models.MinecraftAccount", "MinecraftAccount") + .WithMany() + .HasForeignKey("PlayerUuid") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Models.Entities.Hypixel.Profile", "Profile") + .WithMany("Members") + .HasForeignKey("ProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("EliteAPI.Models.Entities.Hypixel.ApiAccess", "Api", b1 => + { + b1.Property("ProfileMemberId") + .HasColumnType("uuid"); + + b1.Property("Collections") + .HasColumnType("boolean"); + + b1.Property("Inventories") + .HasColumnType("boolean"); + + b1.Property("Museum") + .HasColumnType("boolean"); + + b1.Property("Skills") + .HasColumnType("boolean"); + + b1.Property("Vault") + .HasColumnType("boolean"); + + b1.HasKey("ProfileMemberId"); + + b1.ToTable("ProfileMembers"); + + b1.WithOwner() + .HasForeignKey("ProfileMemberId"); + }); + + b.Navigation("Api") + .IsRequired(); + + b.Navigation("MinecraftAccount"); + + b.Navigation("Profile"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.Skills", b => + { + b.HasOne("EliteAPI.Models.Entities.Hypixel.ProfileMember", "ProfileMember") + .WithOne("Skills") + .HasForeignKey("EliteAPI.Models.Entities.Hypixel.Skills", "ProfileMemberId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ProfileMember"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.CosmeticImage", b => + { + b.HasOne("EliteAPI.Models.Entities.Monetization.WeightStyle", "Cosmetic") + .WithMany() + .HasForeignKey("CosmeticId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Features.Images.Models.Image", "Image") + .WithMany() + .HasForeignKey("ImageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Cosmetic"); + + b.Navigation("Image"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.Product", b => + { + b.HasOne("EliteAPI.Features.Images.Models.Image", "Thumbnail") + .WithMany() + .HasForeignKey("ThumbnailId"); + + b.Navigation("Thumbnail"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.ProductCategory", b => + { + b.HasOne("EliteAPI.Models.Entities.Monetization.Category", "Category") + .WithMany("ProductCategories") + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Models.Entities.Monetization.Product", "Product") + .WithMany("ProductCategories") + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + + b.Navigation("Product"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.ProductImage", b => + { + b.HasOne("EliteAPI.Features.Images.Models.Image", "Image") + .WithMany() + .HasForeignKey("ImageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Models.Entities.Monetization.Product", "Product") + .WithMany() + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Image"); + + b.Navigation("Product"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.ProductTag", b => + { + b.HasOne("EliteAPI.Models.Entities.Monetization.Product", "Product") + .WithMany("ProductTags") + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Models.Entities.Monetization.Tag", "Tag") + .WithMany("ProductTags") + .HasForeignKey("TagId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Product"); + + b.Navigation("Tag"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.ProductWeightStyle", b => + { + b.HasOne("EliteAPI.Models.Entities.Monetization.Product", null) + .WithMany("ProductWeightStyles") + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Models.Entities.Monetization.WeightStyle", null) + .WithMany("ProductWeightStyles") + .HasForeignKey("WeightStyleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.WeightStyle", b => + { + b.HasOne("EliteAPI.Features.Images.Models.Image", "Image") + .WithMany() + .HasForeignKey("ImageId"); + + b.Navigation("Image"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Timescale.CropCollection", b => + { + b.HasOne("EliteAPI.Models.Entities.Hypixel.ProfileMember", "ProfileMember") + .WithMany() + .HasForeignKey("ProfileMemberId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ProfileMember"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Timescale.SkillExperience", b => + { + b.HasOne("EliteAPI.Models.Entities.Hypixel.ProfileMember", "ProfileMember") + .WithMany() + .HasForeignKey("ProfileMemberId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ProfileMember"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("EliteAPI.Features.Auth.Models.ApiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("EliteAPI.Features.Auth.Models.ApiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Features.Auth.Models.ApiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("EliteAPI.Features.Auth.Models.ApiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("EliteAPI.Features.Monetization.Models.GuildEntitlement", b => + { + b.HasOne("EliteAPI.Models.Entities.Discord.Guild", "Guild") + .WithMany("Entitlements") + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Guild"); + }); + + modelBuilder.Entity("EliteAPI.Features.Monetization.Models.UserEntitlement", b => + { + b.HasOne("EliteAPI.Features.Account.Models.EliteAccount", "Account") + .WithMany("Entitlements") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("EliteAPI.Features.Account.Models.EliteAccount", b => + { + b.Navigation("DismissedAnnouncements"); + + b.Navigation("Entitlements"); + + b.Navigation("MinecraftAccounts"); + + b.Navigation("ProductAccesses"); + }); + + modelBuilder.Entity("EliteAPI.Features.Account.Models.MinecraftAccount", b => + { + b.Navigation("Badges"); + + b.Navigation("GuildMembers"); + + b.Navigation("PlayerData"); + }); + + modelBuilder.Entity("EliteAPI.Features.Auth.Models.ApiUser", b => + { + b.Navigation("GuildMemberships"); + }); + + modelBuilder.Entity("EliteAPI.Features.Confirmations.Models.Confirmation", b => + { + b.Navigation("UserConfirmations"); + }); + + modelBuilder.Entity("EliteAPI.Features.Guides.Models.Comment", b => + { + b.Navigation("Replies"); + + b.Navigation("Votes"); + }); + + modelBuilder.Entity("EliteAPI.Features.Guides.Models.Guide", b => + { + b.Navigation("Tags"); + + b.Navigation("Versions"); + + b.Navigation("Votes"); + }); + + modelBuilder.Entity("EliteAPI.Features.Guides.Models.GuideTag", b => + { + b.Navigation("Guides"); + }); + + modelBuilder.Entity("EliteAPI.Features.HypixelGuilds.Models.HypixelGuild", b => + { + b.Navigation("Members"); + + b.Navigation("Stats"); + }); + + modelBuilder.Entity("EliteAPI.Features.HypixelGuilds.Models.HypixelGuildMember", b => + { + b.Navigation("ExpHistory"); + }); + + modelBuilder.Entity("EliteAPI.Features.Monetization.Models.ShopOrder", b => + { + b.Navigation("OrderItems"); + }); + + modelBuilder.Entity("EliteAPI.Features.Profiles.Models.HypixelInventory", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("EliteAPI.Features.Resources.Firesales.Models.SkyblockFiresale", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("EliteAPI.Features.Resources.Items.Models.SkyblockItem", b => + { + b.Navigation("AuctionItems"); + + b.Navigation("BazaarProductSummary"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Discord.Guild", b => + { + b.Navigation("Channels"); + + b.Navigation("Entitlements"); + + b.Navigation("Roles"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.Event", b => + { + b.Navigation("Teams"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.EventTeam", b => + { + b.Navigation("Members"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.JacobData", b => + { + b.Navigation("Contests"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.Profile", b => + { + b.Navigation("Garden"); + + b.Navigation("Members"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.ProfileMember", b => + { + b.Navigation("Auctions"); + + b.Navigation("ChocolateFactory") + .IsRequired(); + + b.Navigation("EventEntries"); + + b.Navigation("Farming") + .IsRequired(); + + b.Navigation("Inventories"); + + b.Navigation("JacobData") + .IsRequired(); + + b.Navigation("Metadata"); + + b.Navigation("Skills") + .IsRequired(); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.Category", b => + { + b.Navigation("ProductCategories"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.Product", b => + { + b.Navigation("ProductCategories"); + + b.Navigation("ProductTags"); + + b.Navigation("ProductWeightStyles"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.Tag", b => + { + b.Navigation("ProductTags"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.WeightStyle", b => + { + b.Navigation("ProductWeightStyles"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/EliteAPI/Data/Migrations/20260114012911_AddLatestFlagToGuildStats.cs b/EliteAPI/Data/Migrations/20260114012911_AddLatestFlagToGuildStats.cs new file mode 100644 index 00000000..f28ae1ed --- /dev/null +++ b/EliteAPI/Data/Migrations/20260114012911_AddLatestFlagToGuildStats.cs @@ -0,0 +1,48 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace EliteAPI.Data.Migrations +{ + /// + public partial class AddLatestFlagToGuildStats : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_HypixelGuildStats_GuildId", + table: "HypixelGuildStats"); + + migrationBuilder.AddColumn( + name: "IsLatest", + table: "HypixelGuildStats", + type: "boolean", + nullable: false, + defaultValue: false); + + migrationBuilder.CreateIndex( + name: "IX_HypixelGuildStats_GuildId_IsLatest", + table: "HypixelGuildStats", + columns: new[] { "GuildId", "IsLatest" }, + filter: "\"IsLatest\" = true"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_HypixelGuildStats_GuildId_IsLatest", + table: "HypixelGuildStats"); + + migrationBuilder.DropColumn( + name: "IsLatest", + table: "HypixelGuildStats"); + + migrationBuilder.CreateIndex( + name: "IX_HypixelGuildStats_GuildId", + table: "HypixelGuildStats", + column: "GuildId"); + } + } +} From f0e081eed0672347d43c777ee6f6ff41b2e89566 Mon Sep 17 00:00:00 2001 From: ptlthg <24925519+ptlthg@users.noreply.github.com> Date: Tue, 13 Jan 2026 21:27:59 -0500 Subject: [PATCH 2/2] Fixes --- ...0260114012911_AddLatestFlagToGuildStats.cs | 11 ++++ .../Migrations/DataContextModelSnapshot.cs | 8 ++- .../HypixelGuilds/Models/HypixelGuildStats.cs | 5 ++ .../Services/HypixelGuildService.cs | 52 +++++-------------- .../Services/HypixelGuildStatsService.cs | 5 ++ 5 files changed, 39 insertions(+), 42 deletions(-) diff --git a/EliteAPI/Data/Migrations/20260114012911_AddLatestFlagToGuildStats.cs b/EliteAPI/Data/Migrations/20260114012911_AddLatestFlagToGuildStats.cs index f28ae1ed..8640393c 100644 --- a/EliteAPI/Data/Migrations/20260114012911_AddLatestFlagToGuildStats.cs +++ b/EliteAPI/Data/Migrations/20260114012911_AddLatestFlagToGuildStats.cs @@ -26,6 +26,17 @@ protected override void Up(MigrationBuilder migrationBuilder) table: "HypixelGuildStats", columns: new[] { "GuildId", "IsLatest" }, filter: "\"IsLatest\" = true"); + + migrationBuilder.Sql(""" + UPDATE "HypixelGuildStats" s + SET "IsLatest" = true + FROM ( + SELECT DISTINCT ON ("GuildId") "Id" + FROM "HypixelGuildStats" + ORDER BY "GuildId", "RecordedAt" DESC + ) AS latest + WHERE s."Id" = latest."Id"; + """); } /// diff --git a/EliteAPI/Data/Migrations/DataContextModelSnapshot.cs b/EliteAPI/Data/Migrations/DataContextModelSnapshot.cs index 0fa0d462..17d6ea14 100644 --- a/EliteAPI/Data/Migrations/DataContextModelSnapshot.cs +++ b/EliteAPI/Data/Migrations/DataContextModelSnapshot.cs @@ -962,6 +962,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) .IsRequired() .HasColumnType("text"); + b.Property("IsLatest") + .HasColumnType("boolean"); + b.Property("MemberCount") .HasColumnType("integer"); @@ -974,10 +977,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.HasIndex("GuildId"); - b.HasIndex("RecordedAt"); + b.HasIndex("GuildId", "IsLatest") + .HasFilter("\"IsLatest\" = true"); + b.ToTable("HypixelGuildStats"); }); diff --git a/EliteAPI/Features/HypixelGuilds/Models/HypixelGuildStats.cs b/EliteAPI/Features/HypixelGuilds/Models/HypixelGuildStats.cs index c872be93..df8c5b6c 100644 --- a/EliteAPI/Features/HypixelGuilds/Models/HypixelGuildStats.cs +++ b/EliteAPI/Features/HypixelGuilds/Models/HypixelGuildStats.cs @@ -15,6 +15,8 @@ public class HypixelGuildStats public required string GuildId { get; set; } public DateTimeOffset RecordedAt { get; set; } = DateTimeOffset.UtcNow; + public bool IsLatest { get; set; } + public int MemberCount { get; set; } public HypixelGuildStat HypixelLevel { get; set; } = new(); @@ -45,6 +47,9 @@ public void Configure(Microsoft.EntityFrameworkCore.Metadata.Builders.EntityType { builder.HasIndex(x => x.RecordedAt); + builder.HasIndex(x => new { x.GuildId, x.IsLatest }) + .HasFilter("\"IsLatest\" = true"); + builder.HasOne() .WithMany(x => x.Stats) .HasForeignKey(x => x.GuildId) diff --git a/EliteAPI/Features/HypixelGuilds/Services/HypixelGuildService.cs b/EliteAPI/Features/HypixelGuilds/Services/HypixelGuildService.cs index 278d20f9..0635cad9 100644 --- a/EliteAPI/Features/HypixelGuilds/Services/HypixelGuildService.cs +++ b/EliteAPI/Features/HypixelGuilds/Services/HypixelGuildService.cs @@ -311,15 +311,8 @@ public async Task GetGuildLeaderboardTotalCount(HypixelGuildListQuery query var sql = """ SELECT COUNT(*)::int as "Value" FROM "HypixelGuilds" g - LEFT JOIN ( - SELECT DISTINCT ON ("GuildId") - "GuildId", - ("Collections"->>@collectionId)::bigint as "Amount" - FROM "HypixelGuildStats" - WHERE "Collections"->>@collectionId IS NOT NULL - ORDER BY "GuildId", "RecordedAt" DESC - ) AS c ON c."GuildId" = g."Id" - WHERE c."Amount" IS NOT NULL + INNER JOIN "HypixelGuildStats" s ON s."GuildId" = g."Id" AND s."IsLatest" = true + WHERE (s."Collections"->>@collectionId)::bigint IS NOT NULL """; var result = await context.Database @@ -334,15 +327,8 @@ WHERE c."Amount" IS NOT NULL var sql = """ SELECT COUNT(*)::int as "Value" FROM "HypixelGuilds" g - LEFT JOIN ( - SELECT DISTINCT ON ("GuildId") - "GuildId", - ("Skills"->>@skillId)::bigint as "Amount" - FROM "HypixelGuildStats" - WHERE "Skills"->>@skillId IS NOT NULL - ORDER BY "GuildId", "RecordedAt" DESC - ) AS c ON c."GuildId" = g."Id" - WHERE c."Amount" IS NOT NULL + INNER JOIN "HypixelGuildStats" s ON s."GuildId" = g."Id" AND s."IsLatest" = true + WHERE (s."Skills"->>@skillId)::bigint IS NOT NULL """; var result = await context.Database @@ -471,18 +457,11 @@ private async Task> GetGuildListByCollectionAsync(H CancellationToken c = default) { var sql = $""" - SELECT c."Amount", g."Id", g."Name", g."CreatedAt", g."Tag", g."TagColor", g."MemberCount", g."LastUpdated" + SELECT (s."Collections"->>@collectionId)::bigint as "Amount", g."Id", g."Name", g."CreatedAt", g."Tag", g."TagColor", g."MemberCount", g."LastUpdated" FROM "HypixelGuilds" g - LEFT JOIN ( - SELECT DISTINCT ON ("GuildId") - "GuildId", - ("Collections"->>@collectionId)::bigint as "Amount" - FROM "HypixelGuildStats" - WHERE "Collections"->>@collectionId IS NOT NULL - ORDER BY "GuildId", "RecordedAt" DESC - ) AS c ON c."GuildId" = g."Id" - WHERE c."Amount" IS NOT NULL - ORDER BY c."Amount"::bigint DESC + INNER JOIN "HypixelGuildStats" s ON s."GuildId" = g."Id" AND s."IsLatest" = true + WHERE (s."Collections"->>@collectionId)::bigint IS NOT NULL + ORDER BY (s."Collections"->>@collectionId)::bigint DESC LIMIT @pageSize OFFSET @offset; """; @@ -500,18 +479,11 @@ private async Task> GetGuildListBySkillAsync(Hypixe CancellationToken c = default) { var sql = $""" - SELECT c."Amount", g."Id", g."Name", g."CreatedAt", g."Tag", g."TagColor", g."MemberCount", g."LastUpdated" + SELECT (s."Skills"->>@skillId)::bigint as "Amount", g."Id", g."Name", g."CreatedAt", g."Tag", g."TagColor", g."MemberCount", g."LastUpdated" FROM "HypixelGuilds" g - LEFT JOIN ( - SELECT DISTINCT ON ("GuildId") - "GuildId", - ("Skills"->>@skillId)::bigint as "Amount" - FROM "HypixelGuildStats" - WHERE "Skills"->>@skillId IS NOT NULL - ORDER BY "GuildId", "RecordedAt" DESC - ) AS c ON c."GuildId" = g."Id" - WHERE c."Amount" IS NOT NULL - ORDER BY c."Amount"::bigint DESC + INNER JOIN "HypixelGuildStats" s ON s."GuildId" = g."Id" AND s."IsLatest" = true + WHERE (s."Skills"->>@skillId)::bigint IS NOT NULL + ORDER BY (s."Skills"->>@skillId)::bigint DESC LIMIT @pageSize OFFSET @offset; """; diff --git a/EliteAPI/Features/HypixelGuilds/Services/HypixelGuildStatsService.cs b/EliteAPI/Features/HypixelGuilds/Services/HypixelGuildStatsService.cs index 9ad5eb6a..244b4414 100644 --- a/EliteAPI/Features/HypixelGuilds/Services/HypixelGuildStatsService.cs +++ b/EliteAPI/Features/HypixelGuilds/Services/HypixelGuildStatsService.cs @@ -191,6 +191,11 @@ public async Task UpdateGuildStats(string guildId, CancellationToken ct) { newStats.Collections = collections; newStats.Skills = skills; + newStats.IsLatest = true; + + await context.HypixelGuildStats + .Where(s => s.GuildId == guildId && s.IsLatest) + .ExecuteUpdateAsync(s => s.SetProperty(x => x.IsLatest, false), ct); context.HypixelGuildStats.Add(newStats); await context.SaveChangesAsync(ct);