diff --git a/EliteAPI/Controllers/ProductController.cs b/EliteAPI/Controllers/ProductController.cs index 7df3d2e..06a3455 100644 --- a/EliteAPI/Controllers/ProductController.cs +++ b/EliteAPI/Controllers/ProductController.cs @@ -281,17 +281,19 @@ public async Task> GetWeightStyle(int style } var existing = await context.WeightStyles + .Include(s => s.Images) .Where(s => s.Id == styleId) - .Select(s => mapper.Map(s)) .FirstOrDefaultAsync(); if (existing is null) { return NotFound("Weight style not found"); } + + var mapped = mapper.Map(existing); - await db.StringSetAsync(key, JsonSerializer.Serialize(existing, JsonOptions), TimeSpan.FromMinutes(30)); + await db.StringSetAsync(key, JsonSerializer.Serialize(mapped, JsonOptions), TimeSpan.FromMinutes(30)); - return existing; + return mapped; } /// @@ -406,7 +408,7 @@ public async Task SetWeightStyleImage(int styleId, [FromForm] Upl await DeleteWeightStyleImage(styleId); } - var path = $"cosmetics/weightstyles/{styleId}{Path.GetExtension(imageDto.Image.FileName).ToLowerInvariant()}"; + var path = $"cosmetics/weightstyles/{styleId}/{Path.GetExtension(imageDto.Image.FileName).ToLowerInvariant()}"; var newImage = await objectStorageService.UploadImageAsync(path, imageDto.Image); newImage.Title = imageDto.Title; @@ -525,4 +527,89 @@ public async Task RemoveWeightStyleFromProduct(ulong productId, i return Ok(); } + + /// + /// Add image to a cosmetic + /// + /// + /// + /// Specify if this image should be the thumbnail + /// + [Authorize(ApiUserPolicies.Admin)] + [HttpPost("style/{styleId:int}/images")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound, Type = typeof(string))] + public async Task AddStyleImage(int styleId, [FromForm] UploadImageDto imageDto, [FromQuery] bool thumbnail = false) + { + var style = await context.WeightStyles.FindAsync(styleId); + if (style is null) { + return NotFound("Style not found"); + } + + var image = await objectStorageService.UploadImageAsync($"cosmetics/weightstyles/{styleId}/{Guid.NewGuid()}.png", imageDto.Image); + + image.Title = imageDto.Title; + image.Description = imageDto.Description; + + if (thumbnail) { + if (style.Image is not null) { + await DeleteStyleImage(styleId, style.Image.Path); + } + + style.Image = image; + } else { + style.Images.Add(image); + } + + await context.SaveChangesAsync(); + + // Clear the product list cache + var db = redis.GetDatabase(); + await db.KeyDeleteAsync("bot:stylelist"); + await db.KeyDeleteAsync($"bot:stylelist:{styleId}"); + + return Ok(); + } + + /// + /// Delete image from a style + /// + /// + /// + /// + [Authorize(ApiUserPolicies.Admin)] + [HttpDelete("style/{styleId:int}/images/{imagePath}")] + [ProducesResponseType(StatusCodes.Status200OK)] + public async Task DeleteStyleImage(int styleId, string imagePath) + { + var style = await context.WeightStyles.Include(i => i.Images).FirstOrDefaultAsync(p => p.Id == styleId); + if (style is null) { + return NotFound("Style not found"); + } + + var decoded = HttpUtility.UrlDecode(imagePath); + var styleImage = style.Images.FirstOrDefault(i => decoded.EndsWith(i.Path)) + ?? (style.Image?.Path == decoded ? style.Image : null); + + if (styleImage is null) { + return NotFound("Image not found"); + } + + if (style.Image == styleImage) { + style.Image = null; + } else { + style.Images.Remove(styleImage); + } + + await context.SaveChangesAsync(); + + await objectStorageService.DeleteAsync(styleImage.Path); + + // Clear the product list cache + var db = redis.GetDatabase(); + await db.KeyDeleteAsync("bot:stylelist"); + await db.KeyDeleteAsync($"bot:stylelist:{styleId}"); + + return Ok(); + } } \ No newline at end of file diff --git a/EliteAPI/Data/Migrations/20241224005454_AddCosmeticImages.Designer.cs b/EliteAPI/Data/Migrations/20241224005454_AddCosmeticImages.Designer.cs new file mode 100644 index 0000000..d1acdb7 --- /dev/null +++ b/EliteAPI/Data/Migrations/20241224005454_AddCosmeticImages.Designer.cs @@ -0,0 +1,2573 @@ +// +using System; +using System.Collections.Generic; +using System.Text.Json; +using EliteAPI.Data; +using EliteAPI.Models.Entities.Accounts; +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 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("20241224005454_AddCosmeticImages")] + partial class AddCosmeticImages + { + /// + 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", "8.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.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.Models.Entities.Accounts.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.Models.Entities.Accounts.EliteAccount", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("ActiveRewards") + .HasColumnType("boolean"); + + b.Property("Avatar") + .HasColumnType("text"); + + b.Property("Discriminator") + .HasColumnType("text"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Email") + .HasColumnType("text"); + + b.Property("Locale") + .HasColumnType("text"); + + b.Property("UserSettingsId") + .HasColumnType("integer"); + + b.Property("Username") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("UserSettingsId"); + + b.ToTable("Accounts"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.MinecraftAccount", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("AccountId") + .HasColumnType("numeric(20,0)"); + + b.Property>("FlagReasons") + .HasColumnType("jsonb"); + + b.Property("Flags") + .HasColumnType("integer"); + + 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>("Properties") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Selected") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex(new[] { "Name" }, "idx_minecraft_accounts_name"); + + b.ToTable("MinecraftAccounts"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.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.Models.Entities.Accounts.UserSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Features") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("WeightStyleId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("WeightStyleId"); + + b.ToTable("UserSettings"); + }); + + 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.Property>("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.Property("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("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("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("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("ProfileName") + .IsRequired() + .HasColumnType("text"); + + 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("IsSelected") + .HasColumnType("boolean"); + + b.Property("LastUpdated") + .HasColumnType("bigint"); + + 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("SkyblockXp") + .HasColumnType("integer"); + + 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("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.Images.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("Path"); + + b.ToTable("Images"); + }); + + 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.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)") + .HasAnnotation("Relational:JsonPropertyName", "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.Models.Entities.Monetization.Product", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("Available") + .HasColumnType("boolean"); + + b.Property("Category") + .HasColumnType("integer"); + + 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("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.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.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.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("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + 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("Earthworm") + .HasColumnType("integer"); + + b.Property("Fly") + .HasColumnType("integer"); + + b.Property("Locust") + .HasColumnType("integer"); + + b.Property("Melon") + .HasColumnType("bigint"); + + b.Property("Mite") + .HasColumnType("integer"); + + 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("Time") + .HasColumnType("timestamp with time zone"); + + b.Property("Wheat") + .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", + Name = "Admin", + NormalizedName = "ADMIN" + }, + new + { + Id = "3384aba1-5453-4787-81d9-0b7222225d81", + Name = "Moderator", + NormalizedName = "MODERATOR" + }, + new + { + Id = "d8c803c1-63a0-4594-8d68-aad7bd59df7d", + Name = "Support", + NormalizedName = "SUPPORT" + }, + new + { + Id = "ff4f5319-644e-4332-8bd5-2ec989ba5e7f", + Name = "Wiki", + NormalizedName = "WIKI" + }, + new + { + Id = "e99efab5-3fd2-416e-b8f5-93b0370892ac", + 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.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.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.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.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.Models.Entities.Monetization.GuildEntitlement", b => + { + b.HasBaseType("EliteAPI.Models.Entities.Monetization.Entitlement"); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.HasIndex("GuildId"); + + b.HasDiscriminator().HasValue(1); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.UserEntitlement", b => + { + b.HasBaseType("EliteAPI.Models.Entities.Monetization.Entitlement"); + + b.Property("AccountId") + .HasMaxLength(22) + .HasColumnType("numeric(20,0)"); + + b.HasIndex("AccountId"); + + b.HasDiscriminator().HasValue(2); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.ApiUser", b => + { + b.HasOne("EliteAPI.Models.Entities.Accounts.EliteAccount", "Account") + .WithMany() + .HasForeignKey("AccountId"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.Badge", b => + { + b.HasOne("EliteAPI.Models.Entities.Images.Image", "Image") + .WithMany() + .HasForeignKey("ImageId"); + + b.Navigation("Image"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.EliteAccount", b => + { + b.HasOne("EliteAPI.Models.Entities.Accounts.UserSettings", "UserSettings") + .WithMany() + .HasForeignKey("UserSettingsId"); + + b.Navigation("UserSettings"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.MinecraftAccount", b => + { + b.HasOne("EliteAPI.Models.Entities.Accounts.EliteAccount", "EliteAccount") + .WithMany("MinecraftAccounts") + .HasForeignKey("AccountId"); + + b.Navigation("EliteAccount"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.UserBadge", b => + { + b.HasOne("EliteAPI.Models.Entities.Accounts.Badge", "Badge") + .WithMany() + .HasForeignKey("BadgeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Models.Entities.Accounts.MinecraftAccount", "MinecraftAccount") + .WithMany("Badges") + .HasForeignKey("MinecraftAccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Badge"); + + b.Navigation("MinecraftAccount"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.UserSettings", b => + { + b.HasOne("EliteAPI.Models.Entities.Monetization.WeightStyle", "WeightStyle") + .WithMany() + .HasForeignKey("WeightStyleId"); + + b.Navigation("WeightStyle"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Discord.Guild", b => + { + b.HasOne("EliteAPI.Models.Entities.Images.Image", "Banner") + .WithMany() + .HasForeignKey("BannerId"); + + b.HasOne("EliteAPI.Models.Entities.Images.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.Models.Entities.Accounts.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.Models.Entities.Images.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.Models.Entities.Accounts.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("Earthworm") + .HasColumnType("integer"); + + b1.Property("Fly") + .HasColumnType("integer"); + + b1.Property("Locust") + .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("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("Wheat") + .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("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("Wheat") + .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.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.Models.Entities.Accounts.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.Models.Entities.Accounts.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.Models.Entities.Images.Image", "Image") + .WithMany() + .HasForeignKey("ImageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Cosmetic"); + + b.Navigation("Image"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.Entitlement", b => + { + b.HasOne("EliteAPI.Models.Entities.Monetization.Product", "Product") + .WithMany() + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Product"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.Product", b => + { + b.HasOne("EliteAPI.Models.Entities.Images.Image", "Thumbnail") + .WithMany() + .HasForeignKey("ThumbnailId"); + + b.Navigation("Thumbnail"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.ProductImage", b => + { + b.HasOne("EliteAPI.Models.Entities.Images.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.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.Models.Entities.Images.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.Models.Entities.Accounts.ApiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("EliteAPI.Models.Entities.Accounts.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.Models.Entities.Accounts.ApiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("EliteAPI.Models.Entities.Accounts.ApiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.GuildEntitlement", b => + { + b.HasOne("EliteAPI.Models.Entities.Discord.Guild", "Guild") + .WithMany("Entitlements") + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Guild"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.UserEntitlement", b => + { + b.HasOne("EliteAPI.Models.Entities.Accounts.EliteAccount", "Account") + .WithMany("Entitlements") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.ApiUser", b => + { + b.Navigation("GuildMemberships"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.EliteAccount", b => + { + b.Navigation("Entitlements"); + + b.Navigation("MinecraftAccounts"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.MinecraftAccount", b => + { + b.Navigation("Badges"); + + b.Navigation("PlayerData"); + }); + + 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("ChocolateFactory") + .IsRequired(); + + b.Navigation("EventEntries"); + + b.Navigation("Farming") + .IsRequired(); + + b.Navigation("JacobData") + .IsRequired(); + + b.Navigation("Skills") + .IsRequired(); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.Product", b => + { + b.Navigation("ProductWeightStyles"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.WeightStyle", b => + { + b.Navigation("ProductWeightStyles"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/EliteAPI/Data/Migrations/20241224005454_AddCosmeticImages.cs b/EliteAPI/Data/Migrations/20241224005454_AddCosmeticImages.cs new file mode 100644 index 0000000..edce0f6 --- /dev/null +++ b/EliteAPI/Data/Migrations/20241224005454_AddCosmeticImages.cs @@ -0,0 +1,50 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace EliteAPI.Data.Migrations +{ + /// + public partial class AddCosmeticImages : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "CosmeticImage", + columns: table => new + { + CosmeticId = table.Column(type: "integer", nullable: false), + ImageId = table.Column(type: "character varying(48)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CosmeticImage", x => new { x.CosmeticId, x.ImageId }); + table.ForeignKey( + name: "FK_CosmeticImage_Cosmetics_CosmeticId", + column: x => x.CosmeticId, + principalTable: "Cosmetics", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_CosmeticImage_Images_ImageId", + column: x => x.ImageId, + principalTable: "Images", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_CosmeticImage_ImageId", + table: "CosmeticImage", + column: "ImageId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "CosmeticImage"); + } + } +} diff --git a/EliteAPI/Data/Migrations/DataContextModelSnapshot.cs b/EliteAPI/Data/Migrations/DataContextModelSnapshot.cs index cd7168b..0b35e9f 100644 --- a/EliteAPI/Data/Migrations/DataContextModelSnapshot.cs +++ b/EliteAPI/Data/Migrations/DataContextModelSnapshot.cs @@ -1118,6 +1118,21 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("Images"); }); + 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.Entitlement", b => { b.Property("Id") @@ -2296,6 +2311,25 @@ protected override void BuildModel(ModelBuilder modelBuilder) 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.Models.Entities.Images.Image", "Image") + .WithMany() + .HasForeignKey("ImageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Cosmetic"); + + b.Navigation("Image"); + }); + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.Entitlement", b => { b.HasOne("EliteAPI.Models.Entities.Monetization.Product", "Product") diff --git a/EliteAPI/Mappers/Discord/WeightStyleMapper.cs b/EliteAPI/Mappers/Discord/WeightStyleMapper.cs index 411677c..85cbe41 100644 --- a/EliteAPI/Mappers/Discord/WeightStyleMapper.cs +++ b/EliteAPI/Mappers/Discord/WeightStyleMapper.cs @@ -12,11 +12,13 @@ public WeightStyleMapper() { CreateMap() .ForMember(w => w.Image, opt => opt.MapFrom(w => w.Image)) + .ForMember(w => w.Images, opt => opt.MapFrom(w => w.Images)) .ForMember(w => w.Products, opt => opt.MapFrom(w => w.Products)); CreateMap() .ForMember(w => w.Data, opt => opt.MapFrom(w => w.Data)) .ForMember(w => w.Image, opt => opt.MapFrom(w => w.Image)) + .ForMember(w => w.Images, opt => opt.MapFrom(w => w.Images)) .ForMember(w => w.Products, opt => opt.MapFrom(w => w.Products)); CreateMap() diff --git a/EliteAPI/Models/DTOs/Outgoing/WeightStyles.cs b/EliteAPI/Models/DTOs/Outgoing/WeightStyles.cs index 799895d..1c7af24 100644 --- a/EliteAPI/Models/DTOs/Outgoing/WeightStyles.cs +++ b/EliteAPI/Models/DTOs/Outgoing/WeightStyles.cs @@ -19,6 +19,7 @@ public class WeightStyleDto public string? Description { get; set; } public ImageAttachmentDto? Image { get; set; } + public List Images { get; set; } = []; public List Products { get; set; } = []; } diff --git a/EliteAPI/Models/Entities/Monetization/CosmeticImage.cs b/EliteAPI/Models/Entities/Monetization/CosmeticImage.cs new file mode 100644 index 0000000..b3551ad --- /dev/null +++ b/EliteAPI/Models/Entities/Monetization/CosmeticImage.cs @@ -0,0 +1,24 @@ +using System.ComponentModel.DataAnnotations.Schema; +using EliteAPI.Models.Entities.Images; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace EliteAPI.Models.Entities.Monetization; + +public class CosmeticImage { + [ForeignKey("Cosmetic")] + public int CosmeticId { get; set; } + public WeightStyle Cosmetic { get; set; } = null!; + + [ForeignKey("Image")] + public required string ImageId { get; set; } + public Image Image { get; set; } = null!; +} + +public class CosmeticImageEntityConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(pi => new { pi.CosmeticId, pi.ImageId }); + } +} \ No newline at end of file diff --git a/EliteAPI/Models/Entities/Monetization/WeightStyle.cs b/EliteAPI/Models/Entities/Monetization/WeightStyle.cs index 2d4bb60..8066f57 100644 --- a/EliteAPI/Models/Entities/Monetization/WeightStyle.cs +++ b/EliteAPI/Models/Entities/Monetization/WeightStyle.cs @@ -32,6 +32,7 @@ public class WeightStyle { public string? Description { get; set; } public Image? Image { get; set; } + public List Images { get; set; } = []; public List ProductWeightStyles { get; set; } = []; public List Products { get; set; } = []; @@ -45,6 +46,15 @@ public class CosmeticEntityConfiguration : IEntityTypeConfiguration public void Configure(EntityTypeBuilder builder) { builder.Navigation(p => p.Image).AutoInclude(); + builder.Navigation(p => p.Images).AutoInclude(); + + builder + .HasMany(e => e.Images) + .WithMany() + .UsingEntity( + j => j.HasOne(ci => ci.Image).WithMany().HasForeignKey(ci => ci.ImageId), + j => j.HasOne(ci => ci.Cosmetic).WithMany().HasForeignKey(ci => ci.CosmeticId) + ); } }