diff --git a/apps/backend/Helpers/UserUploadCharacterProcessor.cs b/apps/backend/Helpers/UserUploadCharacterProcessor.cs index 5649f4ff3..812c18dc2 100644 --- a/apps/backend/Helpers/UserUploadCharacterProcessor.cs +++ b/apps/backend/Helpers/UserUploadCharacterProcessor.cs @@ -1219,7 +1219,10 @@ private void HandleQuests() if (scanTime >= _character.AddonQuests.CompletedQuestsScannedAt) { _character.AddonQuests.CompletedQuestsScannedAt = scanTime; - _character.AddonQuests.CompletedQuests = SquishUtilities.Unsquish(_characterData.CompletedQuestsSquish); + + var completedQuestIds = SquishUtilities.Unsquish(_characterData.CompletedQuestsSquish); + _character.AddonQuests.CompressedCompletedIds = SerializationUtilities.SerializeToBitmap(completedQuestIds); + _character.AddonQuests.CompletedQuests = null; } } @@ -1232,9 +1235,6 @@ private void HandleQuests() { _character.AddonQuests.QuestsScannedAt = scanTime; - _character.AddonQuests.DailyQuests = _characterData.DailyQuests.EmptyIfNull(); - _character.AddonQuests.OtherQuests = _characterData.OtherQuests.EmptyIfNull(); - _character.AddonQuests.ProgressQuests = new(); foreach (string packedProgress in _characterData.ProgressQuests.EmptyIfNull()) { diff --git a/apps/backend/Jobs/Character/CharacterQuestsCompletedJob.cs b/apps/backend/Jobs/Character/CharacterQuestsCompletedJob.cs index 3028e77b4..89ba1e264 100644 --- a/apps/backend/Jobs/Character/CharacterQuestsCompletedJob.cs +++ b/apps/backend/Jobs/Character/CharacterQuestsCompletedJob.cs @@ -1,8 +1,11 @@ using System.Net.Http; +using Equativ.RoaringBitmaps; +using Wowthing.Backend.Models; using Wowthing.Backend.Models.API.Character; using Wowthing.Lib.Constants; using Wowthing.Lib.Models.Player; using Wowthing.Lib.Models.Query; +using Wowthing.Lib.Utilities; namespace Wowthing.Backend.Jobs.Character; @@ -21,18 +24,16 @@ public override void Setup(string[] data) public override async Task Run(string[] data) { // Fetch API data - ApiCharacterQuestsCompleted resultData; + JobHttpResult result; var uri = GenerateUri(_query, ApiPath); try { - var result = await GetUriAsJsonAsync(uri, useLastModified: false); + result = await GetUriAsJsonAsync(uri, useLastModified: false); if (result.NotModified) { LogNotModified(); return; } - - resultData = result.Data; } catch (HttpRequestException e) { @@ -51,15 +52,20 @@ public override async Task Run(string[] data) Context.PlayerCharacterQuests.Add(pcQuests); } - var completedIds = resultData.Quests + pcQuests.ScannedAt = result.LastModified; + + var completedIds = result.Data.Quests .EmptyIfNull() .Select(quest => quest.Id) - .OrderBy(id => id) + .Order() .ToList(); - if (pcQuests.CompletedIds == null || !completedIds.SequenceEqual(pcQuests.CompletedIds)) + byte[] compressedCompletedIds = SerializationUtilities.SerializeToBitmap(completedIds); + + if (pcQuests.CompressedCompletedIds == null || !compressedCompletedIds.SequenceEqual(pcQuests.CompressedCompletedIds)) { - pcQuests.CompletedIds = completedIds; + pcQuests.CompletedIds = null; + pcQuests.CompressedCompletedIds = compressedCompletedIds; } int updated = await Context.SaveChangesAsync(CancellationToken); diff --git a/apps/backend/Models/Uploads/UploadCharacter.cs b/apps/backend/Models/Uploads/UploadCharacter.cs index 65cfcab6a..f9a806ab5 100644 --- a/apps/backend/Models/Uploads/UploadCharacter.cs +++ b/apps/backend/Models/Uploads/UploadCharacter.cs @@ -63,8 +63,6 @@ public class UploadCharacter public Dictionary ScanTimes { get; set; } public string Transmog { get; set; } - public List DailyQuests { get; set; } - public List OtherQuests { get; set; } public List ProgressQuests { get; set; } public Dictionary> WorldQuests { get; set; } diff --git a/apps/backend/Wowthing.Backend.csproj b/apps/backend/Wowthing.Backend.csproj index c5d5a4000..d28065bd5 100644 --- a/apps/backend/Wowthing.Backend.csproj +++ b/apps/backend/Wowthing.Backend.csproj @@ -8,6 +8,7 @@ + diff --git a/apps/benchmark/Program.cs b/apps/benchmark/Program.cs index c250af284..4f90331ce 100644 --- a/apps/benchmark/Program.cs +++ b/apps/benchmark/Program.cs @@ -1,5 +1,6 @@ // See https://aka.ms/new-console-template for more information +using System.Diagnostics; using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Running; using Wowthing.Lib.Utilities; @@ -9,24 +10,24 @@ namespace Wowthing.Benchmark; [MemoryDiagnoser] public class JsonConverterBench { - private readonly string _data; + private readonly string _luaData; public JsonConverterBench() { - _data = File.ReadAllText("/home/freddie/projects/wowthing-again/temp/WoWthing_Collector.lua"); + _luaData = File.ReadAllText("/home/freddie/projects/wowthing-again/temp/WoWthing_Collector.lua"); } [Benchmark] - public string V1() => LuaToJsonConverter.Convert(_data); + public string V1() => LuaToJsonConverter.Convert(_luaData); [Benchmark] - public string V2() => LuaToJsonConverter2.Convert(_data); + public string V2() => LuaToJsonConverter2.Convert(_luaData); [Benchmark] - public string V3() => LuaToJsonConverter3.Convert(_data); + public string V3() => LuaToJsonConverter3.Convert(_luaData); [Benchmark] - public string V4() => LuaToJsonConverter4.Convert(_data); + public string V4() => LuaToJsonConverter4.Convert(_luaData); } public class Program diff --git a/docker-compose.yml b/docker-compose.yml index d4951542f..7f27f16ff 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -24,6 +24,8 @@ services: - ./:/app/ - /app/apps/backend/bin/container/ - /app/apps/backend/obj/container/ + - /app/packages/csharp-lib/bin/container/ + - /app/packages/csharp-lib/obj/container/ web: build: @@ -49,6 +51,8 @@ services: - ./:/app/ - /app/apps/web/bin/container/ - /app/apps/web/obj/container/ + - /app/packages/csharp-lib/bin/container/ + - /app/packages/csharp-lib/obj/container/ frontend: build: diff --git a/packages/csharp-lib/Migrations/20260703195433_Add_PlayerCharacterQuests_CompressedCompletedIds.Designer.cs b/packages/csharp-lib/Migrations/20260703195433_Add_PlayerCharacterQuests_CompressedCompletedIds.Designer.cs new file mode 100644 index 000000000..bf1fabc87 --- /dev/null +++ b/packages/csharp-lib/Migrations/20260703195433_Add_PlayerCharacterQuests_CompressedCompletedIds.Designer.cs @@ -0,0 +1,4522 @@ +// +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Wowthing.Lib.Contexts; +using Wowthing.Lib.Enums; +using Wowthing.Lib.Models; +using Wowthing.Lib.Models.Global; +using Wowthing.Lib.Models.Player; +using Wowthing.Lib.Models.Wow; + +#nullable disable + +namespace Wowthing.Lib.Migrations +{ + [DbContext(typeof(WowDbContext))] + [Migration("20260703195433_Add_PlayerCharacterQuests_CompressedCompletedIds")] + partial class Add_PlayerCharacterQuests_CompressedCompletedIds + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text") + .HasColumnName("concurrency_stamp"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("name"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("normalized_name"); + + b.HasKey("Id") + .HasName("pk_asp_net_roles"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("asp_net_roles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text") + .HasColumnName("claim_type"); + + b.Property("ClaimValue") + .HasColumnType("text") + .HasColumnName("claim_value"); + + b.Property("RoleId") + .HasColumnType("bigint") + .HasColumnName("role_id"); + + b.HasKey("Id") + .HasName("pk_asp_net_role_claims"); + + b.HasIndex("RoleId") + .HasDatabaseName("ix_asp_net_role_claims_role_id"); + + b.ToTable("asp_net_role_claims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text") + .HasColumnName("claim_type"); + + b.Property("ClaimValue") + .HasColumnType("text") + .HasColumnName("claim_value"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_asp_net_user_claims"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_asp_net_user_claims_user_id"); + + b.ToTable("asp_net_user_claims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("text") + .HasColumnName("login_provider"); + + b.Property("ProviderKey") + .HasColumnType("text") + .HasColumnName("provider_key"); + + b.Property("ProviderDisplayName") + .HasColumnType("text") + .HasColumnName("provider_display_name"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("LoginProvider", "ProviderKey") + .HasName("pk_asp_net_user_logins"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_asp_net_user_logins_user_id"); + + b.ToTable("asp_net_user_logins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.Property("RoleId") + .HasColumnType("bigint") + .HasColumnName("role_id"); + + b.HasKey("UserId", "RoleId") + .HasName("pk_asp_net_user_roles"); + + b.HasIndex("RoleId") + .HasDatabaseName("ix_asp_net_user_roles_role_id"); + + b.ToTable("asp_net_user_roles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.Property("LoginProvider") + .HasColumnType("text") + .HasColumnName("login_provider"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("Value") + .HasColumnType("text") + .HasColumnName("value"); + + b.HasKey("UserId", "LoginProvider", "Name") + .HasName("pk_asp_net_user_tokens"); + + b.ToTable("asp_net_user_tokens", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.ApplicationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessFailedCount") + .HasColumnType("integer") + .HasColumnName("access_failed_count"); + + b.Property("ApiKey") + .HasColumnType("text") + .HasColumnName("api_key"); + + b.Property("CanUseSubdomain") + .HasColumnType("boolean") + .HasColumnName("can_use_subdomain"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text") + .HasColumnName("concurrency_stamp"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("email"); + + b.Property("EmailConfirmed") + .HasColumnType("boolean") + .HasColumnName("email_confirmed"); + + b.Property("LastApiCheck") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_api_check"); + + b.Property("LastVisit") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_visit"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean") + .HasColumnName("lockout_enabled"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone") + .HasColumnName("lockout_end"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("normalized_email"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("normalized_user_name"); + + b.Property("PasswordHash") + .HasColumnType("text") + .HasColumnName("password_hash"); + + b.Property("PhoneNumber") + .HasColumnType("text") + .HasColumnName("phone_number"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean") + .HasColumnName("phone_number_confirmed"); + + b.Property("SecurityStamp") + .HasColumnType("text") + .HasColumnName("security_stamp"); + + b.Property("Settings") + .HasColumnType("jsonb") + .HasColumnName("settings"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean") + .HasColumnName("two_factor_enabled"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("user_name"); + + b.HasKey("Id") + .HasName("pk_asp_net_users"); + + b.HasIndex("ApiKey") + .IsUnique() + .HasDatabaseName("ix_asp_net_users_api_key"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("asp_net_users", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Action") + .HasColumnType("text") + .HasColumnName("action"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone") + .HasColumnName("timestamp"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_audit_log"); + + b.ToTable("audit_log", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.BackgroundImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Attribution") + .HasColumnType("text") + .HasColumnName("attribution"); + + b.Property("DefaultBrightness") + .HasColumnType("smallint") + .HasColumnName("default_brightness"); + + b.Property("DefaultSaturate") + .HasColumnType("smallint") + .HasColumnName("default_saturate"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("Filename") + .HasColumnType("text") + .HasColumnName("filename"); + + b.Property("RoleId") + .HasColumnType("bigint") + .HasColumnName("role_id"); + + b.HasKey("Id") + .HasName("pk_background_image"); + + b.HasIndex("RoleId") + .HasDatabaseName("ix_background_image_role_id"); + + b.ToTable("background_image", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Global.GlobalDailies", b => + { + b.Property("Expansion") + .HasColumnType("integer") + .HasColumnName("expansion"); + + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.PrimitiveCollection>("QuestExpires") + .HasColumnType("integer[]") + .HasColumnName("quest_expires"); + + b.PrimitiveCollection>("QuestIds") + .HasColumnType("integer[]") + .HasColumnName("quest_ids"); + + b.Property>("QuestRewards") + .HasColumnType("jsonb") + .HasColumnName("quest_rewards"); + + b.HasKey("Expansion", "Region") + .HasName("pk_global_dailies"); + + b.ToTable("global_dailies", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Image", b => + { + b.Property("Type") + .HasColumnType("integer") + .HasColumnName("type"); + + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Format") + .HasColumnType("smallint") + .HasColumnName("format"); + + b.Property("Data") + .HasColumnType("bytea") + .HasColumnName("data"); + + b.Property("Sha256") + .HasColumnType("char(64)") + .HasColumnName("sha256"); + + b.HasKey("Type", "Id", "Format") + .HasName("pk_image"); + + b.HasIndex("Type", "Sha256", "Format") + .HasDatabaseName("ix_image_type_sha256_format"); + + b.ToTable("image", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.LanguageString", b => + { + b.Property("Language") + .HasColumnType("smallint") + .HasColumnName("language"); + + b.Property("Type") + .HasColumnType("smallint") + .HasColumnName("type"); + + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("String") + .HasColumnType("text") + .HasColumnName("string"); + + b.HasKey("Language", "Type", "Id") + .HasName("pk_language_string"); + + b.HasIndex("String") + .HasDatabaseName("ix_language_string_string"); + + NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("String"), "gin"); + NpgsqlIndexBuilderExtensions.HasOperators(b.HasIndex("String"), new[] { "gin_trgm_ops" }); + + b.HasIndex("Language", "Type", "Id") + .HasDatabaseName("ix_language_string_language_type_id"); + + b.ToTable("language_string", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.MiscAggregate", b => + { + b.Property("Region") + .HasColumnType("smallint") + .HasColumnName("region"); + + b.Property("ReportType") + .HasColumnType("smallint") + .HasColumnName("report_type"); + + b.Property("JsonData") + .HasColumnType("text") + .HasColumnName("json_data"); + + b.HasKey("Region", "ReportType") + .HasName("pk_misc_aggregate"); + + b.ToTable("misc_aggregate", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.MiscReport", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Data") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("data"); + + b.Property("ExpiresAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("expires_at"); + + b.Property("Region") + .HasColumnType("smallint") + .HasColumnName("region"); + + b.Property("ReportType") + .HasColumnType("smallint") + .HasColumnName("report_type"); + + b.Property("ReportedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("reported_at"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_misc_report"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_misc_report_user_id"); + + b.HasIndex("ReportType", "Region", "ExpiresAt") + .IsDescending(false, false, true) + .HasDatabaseName("ix_misc_report_report_type_region_expires_at"); + + b.ToTable("misc_report", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccount", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("bigint") + .HasColumnName("account_id"); + + b.Property("Enabled") + .HasColumnType("boolean") + .HasColumnName("enabled"); + + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.Property("Tag") + .HasColumnType("text") + .HasColumnName("tag"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_player_account"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_player_account_user_id"); + + b.HasIndex("Region", "AccountId") + .IsUnique() + .HasDatabaseName("ix_player_account_region_account_id"); + + b.ToTable("player_account", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountAddonData", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property>>("Decor") + .HasColumnType("jsonb") + .HasColumnName("decor"); + + b.Property("DecorScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("decor_scanned_at"); + + b.Property>("Heirlooms") + .HasColumnType("jsonb") + .HasColumnName("heirlooms"); + + b.Property("HonorCurrent") + .HasColumnType("smallint") + .HasColumnName("honor_current"); + + b.Property("HonorLevel") + .HasColumnType("smallint") + .HasColumnName("honor_level"); + + b.Property("HonorMax") + .HasColumnType("smallint") + .HasColumnName("honor_max"); + + b.PrimitiveCollection>("Illusions") + .HasColumnType("integer[]") + .HasColumnName("illusions"); + + b.PrimitiveCollection>("Quests") + .HasColumnType("integer[]") + .HasColumnName("quests"); + + b.Property>("Reputations") + .HasColumnType("jsonb") + .HasColumnName("reputations"); + + b.Property("ReputationsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("reputations_scanned_at"); + + b.HasKey("AccountId") + .HasName("pk_player_account_addon_data"); + + b.ToTable("player_account_addon_data", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountGoldSnapshot", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property("Gold") + .HasColumnType("integer") + .HasColumnName("gold"); + + b.Property("RealmId") + .HasColumnType("integer") + .HasColumnName("realm_id"); + + b.Property("Time") + .HasColumnType("timestamp with time zone") + .HasColumnName("time"); + + b.HasKey("Id") + .HasName("pk_player_account_gold_snapshot"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_player_account_gold_snapshot_account_id"); + + b.ToTable("player_account_gold_snapshot", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountHeirlooms", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property>("Heirlooms") + .HasColumnType("jsonb") + .HasColumnName("heirlooms"); + + b.HasKey("AccountId") + .HasName("pk_player_account_heirlooms"); + + b.ToTable("player_account_heirlooms", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountMounts", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.PrimitiveCollection>("MountIds") + .HasColumnType("integer[]") + .HasColumnName("mount_ids"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("AccountId") + .HasName("pk_player_account_mounts"); + + b.ToTable("player_account_mounts", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountPets", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property>("Pets") + .HasColumnType("jsonb") + .HasColumnName("pets"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("AccountId") + .HasName("pk_player_account_pets"); + + b.ToTable("player_account_pets", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountToys", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.PrimitiveCollection>("ToyIds") + .HasColumnType("integer[]") + .HasColumnName("toy_ids"); + + b.HasKey("AccountId") + .HasName("pk_player_account_toys"); + + b.ToTable("player_account_toys", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountTransmogIds", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.PrimitiveCollection>("Ids") + .HasColumnType("integer[]") + .HasColumnName("ids"); + + b.HasKey("AccountId") + .HasName("pk_player_account_transmog_ids"); + + b.ToTable("player_account_transmog_ids", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountTransmogSources", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.PrimitiveCollection>("Sources") + .HasColumnType("text[]") + .HasColumnName("sources"); + + b.HasKey("AccountId") + .HasName("pk_player_account_transmog_sources"); + + b.ToTable("player_account_transmog_sources", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacter", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property("ActiveSpecId") + .HasColumnType("integer") + .HasColumnName("active_spec_id"); + + b.Property("ActiveTitleId") + .HasColumnType("integer") + .HasColumnName("active_title_id"); + + b.Property("AverageItemLevel") + .HasColumnType("integer") + .HasColumnName("average_item_level"); + + b.Property("CharacterId") + .HasColumnType("bigint") + .HasColumnName("character_id"); + + b.Property("ChromieTime") + .HasColumnType("integer") + .HasColumnName("chromie_time"); + + b.Property("ClassId") + .HasColumnType("integer") + .HasColumnName("class_id"); + + b.Property("Copper") + .HasColumnType("bigint") + .HasColumnName("copper"); + + b.Property("EquippedItemLevel") + .HasColumnType("integer") + .HasColumnName("equipped_item_level"); + + b.Property("Experience") + .HasColumnType("integer") + .HasColumnName("experience"); + + b.Property("Faction") + .HasColumnType("smallint") + .HasColumnName("faction"); + + b.Property("Gender") + .HasColumnType("integer") + .HasColumnName("gender"); + + b.Property("GuildId") + .HasColumnType("integer") + .HasColumnName("guild_id"); + + b.Property("IsResting") + .HasColumnType("boolean") + .HasColumnName("is_resting"); + + b.Property("IsWarMode") + .HasColumnType("boolean") + .HasColumnName("is_war_mode"); + + b.Property("LastApiCheck") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_api_check"); + + b.Property("LastApiModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_api_modified"); + + b.Property("LastSeenAddon") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_seen_addon"); + + b.Property("Level") + .HasColumnType("integer") + .HasColumnName("level"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("PlayedTotal") + .HasColumnType("integer") + .HasColumnName("played_total"); + + b.Property("RaceId") + .HasColumnType("integer") + .HasColumnName("race_id"); + + b.Property("RealmId") + .HasColumnType("integer") + .HasColumnName("realm_id"); + + b.Property("RestedExperience") + .HasColumnType("integer") + .HasColumnName("rested_experience"); + + b.Property("ShouldUpdate") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(true) + .HasColumnName("should_update"); + + b.HasKey("Id") + .HasName("pk_player_character"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_player_character_account_id"); + + b.HasIndex("GuildId") + .HasDatabaseName("ix_player_character_guild_id"); + + b.HasIndex("LastApiCheck") + .HasDatabaseName("ix_player_character_last_api_check") + .HasFilter("should_update = true AND account_id IS NOT NULL"); + + NpgsqlIndexBuilderExtensions.IncludeProperties(b.HasIndex("LastApiCheck"), new[] { "Id", "AccountId", "Name", "LastApiModified" }); + + b.HasIndex("CharacterId", "LastSeenAddon") + .HasDatabaseName("ix_player_character_character_id_last_seen_addon") + .HasFilter("account_id IS NOT NULL"); + + b.HasIndex("RealmId", "Name") + .IsUnique() + .HasDatabaseName("ix_player_character_realm_id_name"); + + b.ToTable("player_character", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAchievements", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("AchievementIds") + .HasColumnType("integer[]") + .HasColumnName("achievement_ids"); + + b.PrimitiveCollection>("AchievementTimestamps") + .HasColumnType("integer[]") + .HasColumnName("achievement_timestamps"); + + b.PrimitiveCollection>("CriteriaAmounts") + .HasColumnType("bigint[]") + .HasColumnName("criteria_amounts"); + + b.PrimitiveCollection>("CriteriaCompleted") + .HasColumnType("boolean[]") + .HasColumnName("criteria_completed"); + + b.PrimitiveCollection>("CriteriaIds") + .HasColumnType("integer[]") + .HasColumnName("criteria_ids"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_achievements"); + + b.ToTable("player_character_achievements", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonAchievements", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("Achievements") + .HasColumnType("jsonb") + .HasColumnName("achievements"); + + b.Property("ScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("scanned_at"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_addon_achievements"); + + b.ToTable("player_character_addon_achievements", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonData", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("Auras") + .HasColumnType("jsonb") + .HasColumnName("auras"); + + b.Property("BagsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("bags_scanned_at"); + + b.Property("BankScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("bank_scanned_at"); + + b.Property("BankTabs") + .HasColumnType("smallint") + .HasColumnName("bank_tabs"); + + b.Property("BindLocation") + .HasColumnType("text") + .HasColumnName("bind_location"); + + b.Property>("Currencies") + .HasColumnType("jsonb") + .HasColumnName("currencies"); + + b.Property("CurrenciesScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("currencies_scanned_at"); + + b.Property("CurrenciesTransferredAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("currencies_transferred_at"); + + b.Property("CurrentLocation") + .HasColumnType("text") + .HasColumnName("current_location"); + + b.Property("DailyReset") + .HasColumnType("timestamp with time zone") + .HasColumnName("daily_reset"); + + b.Property>("EquippedItems") + .HasColumnType("jsonb") + .HasColumnName("equipped_items"); + + b.Property>>>("GarrisonTrees") + .HasColumnType("jsonb") + .HasColumnName("garrison_trees"); + + b.Property("GarrisonTreesScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("garrison_trees_scanned_at"); + + b.Property>("Garrisons") + .HasColumnType("jsonb") + .HasColumnName("garrisons"); + + b.Property>("HighestItemLevel") + .HasColumnType("jsonb") + .HasColumnName("highest_item_level"); + + b.PrimitiveCollection>("KnownSpells") + .HasColumnType("integer[]") + .HasColumnName("known_spells"); + + b.Property("Level") + .HasColumnType("smallint") + .HasColumnName("level"); + + b.Property("LevelXp") + .HasColumnType("integer") + .HasColumnName("level_xp"); + + b.Property>("MythicPlus") + .HasColumnType("jsonb") + .HasColumnName("mythic_plus"); + + b.Property("MythicPlusScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("mythic_plus_scanned_at"); + + b.Property>>("MythicPlusSeasons") + .HasColumnType("jsonb") + .HasColumnName("mythic_plus_seasons"); + + b.Property>>("MythicPlusWeeks") + .HasColumnType("jsonb") + .HasColumnName("mythic_plus_weeks"); + + b.Property>("Paragons") + .HasColumnType("jsonb") + .HasColumnName("paragons"); + + b.Property>>("PatronOrders") + .HasColumnType("jsonb") + .HasColumnName("patron_orders"); + + b.Property("PatronOrdersScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("patron_orders_scanned_at"); + + b.Property>>("ProfessionCooldowns") + .HasColumnType("jsonb") + .HasColumnName("profession_cooldowns"); + + b.Property>>("ProfessionTraits") + .HasColumnType("jsonb") + .HasColumnName("profession_traits"); + + b.Property>("Professions") + .HasColumnType("jsonb") + .HasColumnName("professions"); + + b.Property>("Reputations") + .HasColumnType("jsonb") + .HasColumnName("reputations"); + + b.Property("ReputationsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("reputations_scanned_at"); + + b.Property("WeeklyReset") + .HasColumnType("timestamp with time zone") + .HasColumnName("weekly_reset"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_addon_data"); + + b.ToTable("player_character_addon_data", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonMounts", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("Mounts") + .HasColumnType("integer[]") + .HasColumnName("mounts"); + + b.Property("ScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("scanned_at"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_addon_mounts"); + + b.ToTable("player_character_addon_mounts", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonQuests", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("CallingsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("callings_scanned_at"); + + b.PrimitiveCollection>("CompletedQuests") + .HasColumnType("integer[]") + .HasColumnName("completed_quests"); + + b.Property("CompletedQuestsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("completed_quests_scanned_at"); + + b.Property>>>("Dailies") + .HasColumnType("jsonb") + .HasColumnName("dailies"); + + b.PrimitiveCollection>("DailyQuests") + .HasColumnType("integer[]") + .HasColumnName("daily_quests"); + + b.Property>>("GoldWorldQuests") + .HasColumnType("jsonb") + .HasColumnName("gold_world_quests"); + + b.PrimitiveCollection>("OtherQuests") + .HasColumnType("integer[]") + .HasColumnName("other_quests"); + + b.Property>("ProgressQuests") + .HasColumnType("jsonb") + .HasColumnName("progress_quests"); + + b.Property("QuestsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("quests_scanned_at"); + + b.Property("WorldQuestsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("world_quests_scanned_at"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_addon_quests"); + + b.ToTable("player_character_addon_quests", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterConfiguration", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("BackgroundBrightness") + .HasColumnType("smallint") + .HasColumnName("background_brightness"); + + b.Property("BackgroundId") + .HasColumnType("smallint") + .HasColumnName("background_id"); + + b.Property("BackgroundSaturation") + .HasColumnType("smallint") + .HasColumnName("background_saturation"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_configuration"); + + b.ToTable("player_character_configuration", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterEquippedItems", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("Items") + .HasColumnType("jsonb") + .HasColumnName("items"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_equipped_items"); + + b.ToTable("player_character_equipped_items", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BindType") + .HasColumnType("smallint") + .HasColumnName("bind_type"); + + b.PrimitiveCollection>("BonusIds") + .HasColumnType("smallint[]") + .HasColumnName("bonus_ids"); + + b.Property("Bound") + .HasColumnType("boolean") + .HasColumnName("bound"); + + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("ContainerId") + .HasColumnType("smallint") + .HasColumnName("container_id"); + + b.Property("Context") + .HasColumnType("smallint") + .HasColumnName("context"); + + b.Property("Count") + .HasColumnType("integer") + .HasColumnName("count"); + + b.Property("CraftedQuality") + .HasColumnType("smallint") + .HasColumnName("crafted_quality"); + + b.Property("EnchantId") + .HasColumnType("smallint") + .HasColumnName("enchant_id"); + + b.PrimitiveCollection>("Gems") + .HasColumnType("integer[]") + .HasColumnName("gems"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("ItemLevel") + .HasColumnType("smallint") + .HasColumnName("item_level"); + + b.Property("Location") + .HasColumnType("smallint") + .HasColumnName("location"); + + b.Property>("Modifiers") + .HasColumnType("jsonb") + .HasColumnName("modifiers"); + + b.Property("Quality") + .HasColumnType("smallint") + .HasColumnName("quality"); + + b.Property("Slot") + .HasColumnType("smallint") + .HasColumnName("slot"); + + b.Property("SuffixId") + .HasColumnType("smallint") + .HasColumnName("suffix_id"); + + b.HasKey("Id") + .HasName("pk_player_character_item"); + + b.HasIndex("CharacterId", "Slot") + .HasDatabaseName("ix_player_character_item_character_id_slot"); + + b.HasIndex("CharacterId", "ItemId", "Location") + .HasDatabaseName("ix_player_character_item_character_id_item_id_location"); + + b.ToTable("player_character_item", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterLockouts", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("LastUpdated") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_updated"); + + b.Property>("Lockouts") + .HasColumnType("jsonb") + .HasColumnName("lockouts"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_lockouts"); + + b.ToTable("player_character_lockouts", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMedia", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("AvatarUrl") + .HasColumnType("text") + .HasColumnName("avatar_url"); + + b.Property("InsetUrl") + .HasColumnType("text") + .HasColumnName("inset_url"); + + b.Property("MainRawUrl") + .HasColumnType("text") + .HasColumnName("main_raw_url"); + + b.Property("MainUrl") + .HasColumnType("text") + .HasColumnName("main_url"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_media"); + + b.ToTable("player_character_media", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMounts", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("Mounts") + .HasColumnType("integer[]") + .HasColumnName("mounts"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_mounts"); + + b.ToTable("player_character_mounts", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlus", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("CurrentPeriodId") + .HasColumnType("integer") + .HasColumnName("current_period_id"); + + b.Property>("PeriodRuns") + .HasColumnType("jsonb") + .HasColumnName("period_runs"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_mythic_plus"); + + b.ToTable("player_character_mythic_plus", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlusAddon", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("Maps") + .HasColumnType("jsonb") + .HasColumnName("maps"); + + b.Property("Season") + .HasColumnType("integer") + .HasColumnName("season"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_mythic_plus_addon"); + + b.ToTable("player_character_mythic_plus_addon", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlusSeason", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("Season") + .HasColumnType("integer") + .HasColumnName("season"); + + b.Property("Rating") + .HasColumnType("double precision") + .HasColumnName("rating"); + + b.Property>("Runs") + .HasColumnType("jsonb") + .HasColumnName("runs"); + + b.HasKey("CharacterId", "Season") + .HasName("pk_player_character_mythic_plus_season"); + + b.ToTable("player_character_mythic_plus_season", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterProfessions", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("ProfessionSpecializations") + .HasColumnType("jsonb") + .HasColumnName("profession_specializations"); + + b.Property>>("Professions") + .HasColumnType("jsonb") + .HasColumnName("professions"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_professions"); + + b.ToTable("player_character_professions", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterQuests", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("CompletedIds") + .HasColumnType("integer[]") + .HasColumnName("completed_ids"); + + b.Property("CompressedCompletedIds") + .HasColumnType("bytea") + .HasColumnName("compressed_completed_ids"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_quests"); + + b.ToTable("player_character_quests", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterRaiderIo", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("Seasons") + .HasColumnType("jsonb") + .HasColumnName("seasons"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_raider_io"); + + b.ToTable("player_character_raider_io", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterReputations", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("ExtraReputationIds") + .HasColumnType("integer[]") + .HasColumnName("extra_reputation_ids"); + + b.PrimitiveCollection>("ExtraReputationValues") + .HasColumnType("integer[]") + .HasColumnName("extra_reputation_values"); + + b.Property>("Paragons") + .HasColumnType("jsonb") + .HasColumnName("paragons"); + + b.PrimitiveCollection>("ReputationIds") + .HasColumnType("integer[]") + .HasColumnName("reputation_ids"); + + b.PrimitiveCollection>("ReputationValues") + .HasColumnType("integer[]") + .HasColumnName("reputation_values"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_reputations"); + + b.ToTable("player_character_reputations", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterShadowlands", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("ConduitIds") + .HasColumnType("integer[]") + .HasColumnName("conduit_ids"); + + b.PrimitiveCollection>("ConduitRanks") + .HasColumnType("integer[]") + .HasColumnName("conduit_ranks"); + + b.Property("CovenantId") + .HasColumnType("integer") + .HasColumnName("covenant_id"); + + b.Property>("Covenants") + .HasColumnType("jsonb") + .HasColumnName("covenants"); + + b.Property("RenownLevel") + .HasColumnType("integer") + .HasColumnName("renown_level"); + + b.Property("SoulbindId") + .HasColumnType("integer") + .HasColumnName("soulbind_id"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_shadowlands"); + + b.ToTable("player_character_shadowlands", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterSpecializations", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("Specializations") + .HasColumnType("jsonb") + .HasColumnName("specializations"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_specializations"); + + b.ToTable("player_character_specializations", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterStatistics", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("StatisticDescriptions") + .HasColumnType("text[]") + .HasColumnName("statistic_descriptions"); + + b.PrimitiveCollection>("StatisticIds") + .HasColumnType("integer[]") + .HasColumnName("statistic_ids"); + + b.PrimitiveCollection>("StatisticQuantities") + .HasColumnType("integer[]") + .HasColumnName("statistic_quantities"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_statistics"); + + b.ToTable("player_character_statistics", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterStats", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("Basic") + .HasColumnType("jsonb") + .HasColumnName("basic"); + + b.Property>("Misc") + .HasColumnType("jsonb") + .HasColumnName("misc"); + + b.Property>("Rating") + .HasColumnType("jsonb") + .HasColumnName("rating"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_stats"); + + b.ToTable("player_character_stats", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterTransmog", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("IllusionIds") + .HasColumnType("integer[]") + .HasColumnName("illusion_ids"); + + b.PrimitiveCollection>("TransmogIds") + .HasColumnType("integer[]") + .HasColumnName("transmog_ids"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_transmog"); + + b.ToTable("player_character_transmog", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterWeekly", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("DelveGilded") + .HasColumnType("smallint") + .HasColumnName("delve_gilded"); + + b.PrimitiveCollection>("DelveLevels") + .HasColumnType("integer[]") + .HasColumnName("delve_levels"); + + b.PrimitiveCollection>("DelveMaps") + .HasColumnType("text[]") + .HasColumnName("delve_maps"); + + b.Property("DelveWeek") + .HasColumnType("integer") + .HasColumnName("delve_week"); + + b.Property("KeystoneDungeon") + .HasColumnType("integer") + .HasColumnName("keystone_dungeon"); + + b.Property("KeystoneLevel") + .HasColumnType("integer") + .HasColumnName("keystone_level"); + + b.Property("KeystoneScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("keystone_scanned_at"); + + b.Property>("Torghast") + .HasColumnType("jsonb") + .HasColumnName("torghast"); + + b.Property("TorghastScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("torghast_scanned_at"); + + b.Property("Vault") + .HasColumnType("jsonb") + .HasColumnName("vault"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_weekly"); + + b.ToTable("player_character_weekly", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerGuild", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("RealmId") + .HasColumnType("integer") + .HasColumnName("realm_id"); + + b.Property>("Tabs") + .HasColumnType("jsonb") + .HasColumnName("tabs"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_player_guild"); + + b.HasIndex("UserId", "RealmId", "Name") + .IsUnique() + .HasDatabaseName("ix_player_guild_user_id_realm_id_name"); + + b.ToTable("player_guild", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerGuildItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BindType") + .HasColumnType("smallint") + .HasColumnName("bind_type"); + + b.PrimitiveCollection>("BonusIds") + .HasColumnType("smallint[]") + .HasColumnName("bonus_ids"); + + b.Property("Bound") + .HasColumnType("boolean") + .HasColumnName("bound"); + + b.Property("ContainerId") + .HasColumnType("smallint") + .HasColumnName("container_id"); + + b.Property("Context") + .HasColumnType("smallint") + .HasColumnName("context"); + + b.Property("Count") + .HasColumnType("integer") + .HasColumnName("count"); + + b.Property("CraftedQuality") + .HasColumnType("smallint") + .HasColumnName("crafted_quality"); + + b.Property("EnchantId") + .HasColumnType("smallint") + .HasColumnName("enchant_id"); + + b.PrimitiveCollection>("Gems") + .HasColumnType("integer[]") + .HasColumnName("gems"); + + b.Property("GuildId") + .HasColumnType("integer") + .HasColumnName("guild_id"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("ItemLevel") + .HasColumnType("smallint") + .HasColumnName("item_level"); + + b.Property>("Modifiers") + .HasColumnType("jsonb") + .HasColumnName("modifiers"); + + b.Property("Quality") + .HasColumnType("smallint") + .HasColumnName("quality"); + + b.Property("Slot") + .HasColumnType("smallint") + .HasColumnName("slot"); + + b.Property("SuffixId") + .HasColumnType("smallint") + .HasColumnName("suffix_id"); + + b.HasKey("Id") + .HasName("pk_player_guild_item"); + + b.HasIndex("GuildId", "ItemId") + .HasDatabaseName("ix_player_guild_item_guild_id_item_id"); + + b.ToTable("player_guild_item", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerWarbankItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BindType") + .HasColumnType("smallint") + .HasColumnName("bind_type"); + + b.PrimitiveCollection>("BonusIds") + .HasColumnType("smallint[]") + .HasColumnName("bonus_ids"); + + b.Property("Bound") + .HasColumnType("boolean") + .HasColumnName("bound"); + + b.Property("ContainerId") + .HasColumnType("smallint") + .HasColumnName("container_id"); + + b.Property("Context") + .HasColumnType("smallint") + .HasColumnName("context"); + + b.Property("Count") + .HasColumnType("integer") + .HasColumnName("count"); + + b.Property("CraftedQuality") + .HasColumnType("smallint") + .HasColumnName("crafted_quality"); + + b.Property("EnchantId") + .HasColumnType("smallint") + .HasColumnName("enchant_id"); + + b.PrimitiveCollection>("Gems") + .HasColumnType("integer[]") + .HasColumnName("gems"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("ItemLevel") + .HasColumnType("smallint") + .HasColumnName("item_level"); + + b.Property>("Modifiers") + .HasColumnType("jsonb") + .HasColumnName("modifiers"); + + b.Property("Quality") + .HasColumnType("smallint") + .HasColumnName("quality"); + + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.Property("Slot") + .HasColumnType("smallint") + .HasColumnName("slot"); + + b.Property("SuffixId") + .HasColumnType("smallint") + .HasColumnName("suffix_id"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_player_warbank_item"); + + b.HasIndex("UserId", "ItemId") + .HasDatabaseName("ix_player_warbank_item_user_id_item_id"); + + b.ToTable("player_warbank_item", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.AccountTransmogQuery", b => + { + b.PrimitiveCollection>("IllusionIds") + .HasColumnType("integer[]") + .HasColumnName("illusion_ids"); + + b.PrimitiveCollection>("TransmogIds") + .HasColumnType("integer[]") + .HasColumnName("transmog_ids"); + + b.ToTable("AccountTransmogQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.AchievementCriteriaQuery", b => + { + b.Property("Amount") + .HasColumnType("bigint") + .HasColumnName("amount"); + + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("CriteriaId") + .HasColumnType("integer") + .HasColumnName("criteria_id"); + + b.ToTable("AchievementCriteriaQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.ActiveConnectedRealmQuery", b => + { + b.Property("ConnectedRealmId") + .HasColumnType("integer") + .HasColumnName("connected_realm_id"); + + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.ToTable("ActiveConnectedRealmQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.AuctionBrowseQuery", b => + { + b.Property("GroupKey") + .HasColumnType("text") + .HasColumnName("group_key"); + + b.Property("LowestBuyoutPrice") + .HasColumnType("bigint") + .HasColumnName("lowest_buyout_price"); + + b.Property("TotalQuantity") + .HasColumnType("bigint") + .HasColumnName("total_quantity"); + + b.ToTable("AuctionBrowseQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.CompletedAchievementsQuery", b => + { + b.Property("AchievementId") + .HasColumnType("integer") + .HasColumnName("achievement_id"); + + b.Property("Timestamp") + .HasColumnType("integer") + .HasColumnName("timestamp"); + + b.ToTable("CompletedAchievementsQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.LatestPlayerAccountGoldSnapshotQuery", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property("Gold") + .HasColumnType("integer") + .HasColumnName("gold"); + + b.Property("RealmId") + .HasColumnType("integer") + .HasColumnName("realm_id"); + + b.ToTable("LatestPlayerAccountGoldSnapshotQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.LatestUserGoldSnapshotQuery", b => + { + b.Property("Gold") + .HasColumnType("integer") + .HasColumnName("gold"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.ToTable("LatestUserGoldSnapshotQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.MountQuery", b => + { + b.PrimitiveCollection>("AddonMounts") + .HasColumnType("integer[]") + .HasColumnName("addon_mounts"); + + b.PrimitiveCollection>("Mounts") + .HasColumnType("integer[]") + .HasColumnName("mounts"); + + b.ToTable("MountQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.PlayerAccountGoldSnapshotQuery", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property("RealmId") + .HasColumnType("integer") + .HasColumnName("realm_id"); + + b.Property("TotalGold") + .HasColumnType("integer") + .HasColumnName("total_gold"); + + b.ToTable("PlayerAccountGoldSnapshotQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.SchedulerCharacterQuery", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("CharacterName") + .HasColumnType("text") + .HasColumnName("character_name"); + + b.Property("LastApiCheck") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_api_check"); + + b.Property("LastApiModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_api_modified"); + + b.Property("RealmSlug") + .HasColumnType("text") + .HasColumnName("realm_slug"); + + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.ToTable("SchedulerCharacterQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.SchedulerUserQuery", b => + { + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.ToTable("SchedulerUserQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.StatisticsQuery", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("Quantity") + .HasColumnType("integer") + .HasColumnName("quantity"); + + b.Property("StatisticId") + .HasColumnType("integer") + .HasColumnName("statistic_id"); + + b.ToTable("StatisticsQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.UserGoldSnapshotQuery", b => + { + b.Property("TotalGold") + .HasColumnType("integer") + .HasColumnName("total_gold"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.ToTable("UserGoldSnapshotQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.UserLeaderboardQuery", b => + { + b.Property("AppearanceIdCount") + .HasColumnType("integer") + .HasColumnName("appearance_id_count"); + + b.Property("AppearanceSourceCount") + .HasColumnType("integer") + .HasColumnName("appearance_source_count"); + + b.Property("CompletedQuestCount") + .HasColumnType("integer") + .HasColumnName("completed_quest_count"); + + b.Property("IllusionCount") + .HasColumnType("smallint") + .HasColumnName("illusion_count"); + + b.Property("MountCount") + .HasColumnType("smallint") + .HasColumnName("mount_count"); + + b.Property("ToyCount") + .HasColumnType("smallint") + .HasColumnName("toy_count"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.ToTable("UserLeaderboardQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.QueuedJob", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Data") + .HasColumnType("text") + .HasColumnName("data"); + + b.Property("DataHash") + .HasColumnType("text") + .HasColumnName("data_hash"); + + b.Property("Failures") + .HasColumnType("smallint") + .HasColumnName("failures"); + + b.Property("Priority") + .HasColumnType("smallint") + .HasColumnName("priority"); + + b.Property("StartedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("started_at"); + + b.Property("Type") + .HasColumnType("smallint") + .HasColumnName("type"); + + b.HasKey("Id") + .HasName("pk_queued_job"); + + b.HasIndex("Priority") + .HasDatabaseName("ix_queued_job_priority") + .HasFilter("started_at IS NULL"); + + b.HasIndex("Priority", "Type", "DataHash") + .IsUnique() + .HasDatabaseName("ix_queued_job_priority_type_data_hash"); + + b.ToTable("queued_job", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Team.Team", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DefaultRealmId") + .HasColumnType("integer") + .HasColumnName("default_realm_id"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("guid"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.Property("Slug") + .HasColumnType("text") + .HasColumnName("slug"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_team"); + + b.HasIndex("Guid") + .IsUnique() + .HasDatabaseName("ix_team_guid"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_team_user_id"); + + b.ToTable("team", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Team.TeamCharacter", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("Note") + .HasColumnType("text") + .HasColumnName("note"); + + b.Property("PrimaryRole") + .HasColumnType("smallint") + .HasColumnName("primary_role"); + + b.Property("SecondaryRole") + .HasColumnType("smallint") + .HasColumnName("secondary_role"); + + b.Property("TeamId") + .HasColumnType("integer") + .HasColumnName("team_id"); + + b.HasKey("Id") + .HasName("pk_team_character"); + + b.HasIndex("CharacterId") + .HasDatabaseName("ix_team_character_character_id"); + + b.HasIndex("TeamId") + .HasDatabaseName("ix_team_character_team_id"); + + b.ToTable("team_character", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserAddonData", b => + { + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.Property("WarbankCopper") + .HasColumnType("bigint") + .HasColumnName("warbank_copper"); + + b.Property("WarbankGoldUpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("warbank_gold_updated_at"); + + b.Property("WarbankUpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("warbank_updated_at"); + + b.HasKey("UserId") + .HasName("pk_user_addon_data"); + + b.ToTable("user_addon_data", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserBulkData", b => + { + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.Property>("Heirlooms") + .HasColumnType("jsonb") + .HasColumnName("heirlooms"); + + b.Property("HeirloomsUpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("heirlooms_updated_at"); + + b.PrimitiveCollection>("MountIds") + .HasColumnType("smallint[]") + .HasColumnName("mount_ids"); + + b.Property("MountsUpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("mounts_updated_at"); + + b.Property>("Pets") + .HasColumnType("jsonb") + .HasColumnName("pets"); + + b.Property("PetsUpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("pets_updated_at"); + + b.PrimitiveCollection>("ToyIds") + .HasColumnType("smallint[]") + .HasColumnName("toy_ids"); + + b.Property("ToysUpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("toys_updated_at"); + + b.PrimitiveCollection>("TransmogIds") + .HasColumnType("integer[]") + .HasColumnName("transmog_ids"); + + b.Property("TransmogsUpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("transmogs_updated_at"); + + b.HasKey("UserId") + .HasName("pk_user_bulk_data"); + + b.ToTable("user_bulk_data", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserCache", b => + { + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.PrimitiveCollection>("AppearanceIds") + .HasColumnType("integer[]") + .HasColumnName("appearance_ids"); + + b.PrimitiveCollection>("AppearanceSources") + .HasColumnType("text[]") + .HasColumnName("appearance_sources"); + + b.Property("CompletedQuests") + .HasColumnType("integer") + .HasColumnName("completed_quests"); + + b.PrimitiveCollection>("IllusionIds") + .HasColumnType("smallint[]") + .HasColumnName("illusion_ids"); + + b.PrimitiveCollection>("MountIds") + .HasColumnType("smallint[]") + .HasColumnName("mount_ids"); + + b.Property("MountsUpdated") + .HasColumnType("timestamp with time zone") + .HasColumnName("mounts_updated"); + + b.PrimitiveCollection>("ToyIds") + .HasColumnType("smallint[]") + .HasColumnName("toy_ids"); + + b.Property("ToysUpdated") + .HasColumnType("timestamp with time zone") + .HasColumnName("toys_updated"); + + b.Property("TransmogUpdated") + .HasColumnType("timestamp with time zone") + .HasColumnName("transmog_updated"); + + b.HasKey("UserId") + .HasName("pk_user_cache"); + + b.ToTable("user_cache", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserGoldSnapshot", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Gold") + .HasColumnType("integer") + .HasColumnName("gold"); + + b.Property("Time") + .HasColumnType("timestamp with time zone") + .HasColumnName("time"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_user_gold_snapshot"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_user_gold_snapshot_user_id"); + + b.ToTable("user_gold_snapshot", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserLeaderboardSnapshot", b => + { + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.Property("Date") + .HasColumnType("date") + .HasColumnName("date"); + + b.Property("AchievementPointsAlliance") + .HasColumnType("integer") + .HasColumnName("achievement_points_alliance"); + + b.Property("AchievementPointsHorde") + .HasColumnType("integer") + .HasColumnName("achievement_points_horde"); + + b.Property("AchievementPointsOverall") + .HasColumnType("integer") + .HasColumnName("achievement_points_overall"); + + b.Property("AppearanceIdCount") + .HasColumnType("integer") + .HasColumnName("appearance_id_count"); + + b.Property("AppearanceSourceCount") + .HasColumnType("integer") + .HasColumnName("appearance_source_count"); + + b.Property("CompletedQuestCount") + .HasColumnType("integer") + .HasColumnName("completed_quest_count"); + + b.Property("HeirloomCount") + .HasColumnType("smallint") + .HasColumnName("heirloom_count"); + + b.Property("HeirloomLevels") + .HasColumnType("smallint") + .HasColumnName("heirloom_levels"); + + b.Property("IllusionCount") + .HasColumnType("smallint") + .HasColumnName("illusion_count"); + + b.Property("MountCount") + .HasColumnType("smallint") + .HasColumnName("mount_count"); + + b.Property("PetCount") + .HasColumnType("smallint") + .HasColumnName("pet_count"); + + b.Property("RecipeCount") + .HasColumnType("smallint") + .HasColumnName("recipe_count"); + + b.Property("ReputationCount") + .HasColumnType("smallint") + .HasColumnName("reputation_count"); + + b.Property("TitleCount") + .HasColumnType("smallint") + .HasColumnName("title_count"); + + b.Property("ToyCount") + .HasColumnType("smallint") + .HasColumnName("toy_count"); + + b.HasKey("UserId", "Date") + .HasName("pk_user_leaderboard_snapshot"); + + b.HasIndex("UserId", "Date") + .IsDescending(false, true) + .HasDatabaseName("ix_user_leaderboard_snapshot_user_id_date"); + + b.ToTable("user_leaderboard_snapshot", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.WorldQuestAggregate", b => + { + b.Property("Region") + .HasColumnType("smallint") + .HasColumnName("region"); + + b.Property("ZoneId") + .HasColumnType("integer") + .HasColumnName("zone_id"); + + b.Property("QuestId") + .HasColumnType("integer") + .HasColumnName("quest_id"); + + b.Property("JsonData") + .HasColumnType("text") + .HasColumnName("json_data"); + + b.HasKey("Region", "ZoneId", "QuestId") + .HasName("pk_world_quest_aggregate"); + + b.ToTable("world_quest_aggregate", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.WorldQuestReport", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Class") + .HasColumnType("smallint") + .HasColumnName("class"); + + b.Property("Expansion") + .HasColumnType("smallint") + .HasColumnName("expansion"); + + b.Property("ExpiresAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("expires_at"); + + b.Property("Faction") + .HasColumnType("smallint") + .HasColumnName("faction"); + + b.Property("Location") + .HasColumnType("text") + .HasColumnName("location"); + + b.Property("QuestId") + .HasColumnType("integer") + .HasColumnName("quest_id"); + + b.Property("Region") + .HasColumnType("smallint") + .HasColumnName("region"); + + b.Property("ReportedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("reported_at"); + + b.Property>("Rewards") + .HasColumnType("jsonb") + .HasColumnName("rewards"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.Property("ZoneId") + .HasColumnType("integer") + .HasColumnName("zone_id"); + + b.HasKey("Id") + .HasName("pk_world_quest_report"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_world_quest_report_user_id"); + + b.HasIndex("Region", "ExpiresAt") + .IsDescending(false, true) + .HasDatabaseName("ix_world_quest_report_region_expires_at"); + + b.ToTable("world_quest_report", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowAuction", b => + { + b.Property("ConnectedRealmId") + .HasColumnType("integer") + .HasColumnName("connected_realm_id"); + + b.Property("AuctionId") + .HasColumnType("integer") + .HasColumnName("auction_id"); + + b.Property("AppearanceId") + .HasColumnType("integer") + .HasColumnName("appearance_id"); + + b.Property("AppearanceSource") + .HasColumnType("text") + .HasColumnName("appearance_source"); + + b.Property("BidPrice") + .HasColumnType("bigint") + .HasColumnName("bid_price"); + + b.PrimitiveCollection>("BonusIds") + .HasColumnType("integer[]") + .HasColumnName("bonus_ids"); + + b.Property("BuyoutPrice") + .HasColumnType("bigint") + .HasColumnName("buyout_price"); + + b.Property("Context") + .HasColumnType("smallint") + .HasColumnName("context"); + + b.Property("GroupKey") + .HasColumnType("text") + .HasColumnName("group_key"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.PrimitiveCollection>("ModifierTypes") + .HasColumnType("smallint[]") + .HasColumnName("modifier_types"); + + b.PrimitiveCollection>("ModifierValues") + .HasColumnType("integer[]") + .HasColumnName("modifier_values"); + + b.Property("PetBreedId") + .HasColumnType("smallint") + .HasColumnName("pet_breed_id"); + + b.Property("PetLevel") + .HasColumnType("smallint") + .HasColumnName("pet_level"); + + b.Property("PetQuality") + .HasColumnType("smallint") + .HasColumnName("pet_quality"); + + b.Property("PetSpeciesId") + .HasColumnType("smallint") + .HasColumnName("pet_species_id"); + + b.Property("Quantity") + .HasColumnType("integer") + .HasColumnName("quantity"); + + b.Property("TimeLeft") + .HasColumnType("smallint") + .HasColumnName("time_left"); + + b.HasKey("ConnectedRealmId", "AuctionId") + .HasName("pk_wow_auction"); + + b.HasIndex("ItemId") + .HasDatabaseName("ix_wow_auction_item_id"); + + b.HasIndex("PetSpeciesId") + .HasDatabaseName("ix_wow_auction_pet_species_id"); + + b.HasIndex("AppearanceId", "BuyoutPrice") + .HasDatabaseName("ix_wow_auction_appearance_id_buyout_price") + .HasFilter("appearance_id IS NOT NULL"); + + b.HasIndex("AppearanceSource", "BuyoutPrice") + .HasDatabaseName("ix_wow_auction_appearance_source_buyout_price") + .HasFilter("appearance_source IS NOT NULL"); + + b.ToTable("wow_auction", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowAuctionCheapestByAppearanceId", b => + { + b.Property("ConnectedRealmId") + .HasColumnType("integer") + .HasColumnName("connected_realm_id"); + + b.Property("AppearanceId") + .HasColumnType("integer") + .HasColumnName("appearance_id"); + + b.Property("AuctionId") + .HasColumnType("integer") + .HasColumnName("auction_id"); + + b.HasKey("ConnectedRealmId", "AppearanceId") + .HasName("pk_wow_auction_cheapest_by_appearance_id"); + + b.ToTable("wow_auction_cheapest_by_appearance_id", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowAuctionCheapestByAppearanceSource", b => + { + b.Property("ConnectedRealmId") + .HasColumnType("integer") + .HasColumnName("connected_realm_id"); + + b.Property("AppearanceSource") + .HasColumnType("text") + .HasColumnName("appearance_source"); + + b.Property("AuctionId") + .HasColumnType("integer") + .HasColumnName("auction_id"); + + b.HasKey("ConnectedRealmId", "AppearanceSource") + .HasName("pk_wow_auction_cheapest_by_appearance_source"); + + b.ToTable("wow_auction_cheapest_by_appearance_source", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowAuctionCommodityDaily", b => + { + b.Property("Region") + .HasColumnType("smallint") + .HasColumnName("region"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("Date") + .HasColumnType("date") + .HasColumnName("date"); + + b.PrimitiveCollection>("AvgData") + .HasColumnType("integer[]") + .HasColumnName("avg_data"); + + b.Property("ListedMax") + .HasColumnType("integer") + .HasColumnName("listed_max"); + + b.Property("ListedMin") + .HasColumnType("integer") + .HasColumnName("listed_min"); + + b.PrimitiveCollection>("MaxData") + .HasColumnType("integer[]") + .HasColumnName("max_data"); + + b.PrimitiveCollection>("MinData") + .HasColumnType("integer[]") + .HasColumnName("min_data"); + + b.HasKey("Region", "ItemId", "Date") + .HasName("pk_wow_auction_commodity_daily"); + + b.ToTable("wow_auction_commodity_daily", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowAuctionCommodityHourly", b => + { + b.Property("Region") + .HasColumnType("smallint") + .HasColumnName("region"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone") + .HasColumnName("timestamp"); + + b.PrimitiveCollection>("Data") + .HasColumnType("integer[]") + .HasColumnName("data"); + + b.Property("Listed") + .HasColumnType("integer") + .HasColumnName("listed"); + + b.HasKey("Region", "ItemId", "Timestamp") + .HasName("pk_wow_auction_commodity_hourly"); + + b.ToTable("wow_auction_commodity_hourly", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowCampaign", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.PrimitiveCollection>("QuestLineIds") + .HasColumnType("integer[]") + .HasColumnName("quest_line_ids"); + + b.HasKey("Id") + .HasName("pk_wow_campaign"); + + b.ToTable("wow_campaign", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowChallengeDungeon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Expansion") + .HasColumnType("smallint") + .HasColumnName("expansion"); + + b.Property("MapId") + .HasColumnType("smallint") + .HasColumnName("map_id"); + + b.PrimitiveCollection>("TimerBreakpoints") + .HasColumnType("smallint[]") + .HasColumnName("timer_breakpoints"); + + b.HasKey("Id") + .HasName("pk_wow_challenge_dungeon"); + + b.ToTable("wow_challenge_dungeon", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowCharacterClass", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ArmorMask") + .HasColumnType("smallint") + .HasColumnName("armor_mask"); + + b.Property("RolesMask") + .HasColumnType("smallint") + .HasColumnName("roles_mask"); + + b.Property("Slug") + .HasColumnType("text") + .HasColumnName("slug"); + + b.HasKey("Id") + .HasName("pk_wow_character_class"); + + b.ToTable("wow_character_class", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowCharacterRace", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Bit") + .HasColumnType("smallint") + .HasColumnName("bit"); + + b.Property("Faction") + .HasColumnType("smallint") + .HasColumnName("faction"); + + b.HasKey("Id") + .HasName("pk_wow_character_race"); + + b.ToTable("wow_character_race", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowCharacterSpecialization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClassId") + .HasColumnType("smallint") + .HasColumnName("class_id"); + + b.Property("Order") + .HasColumnType("smallint") + .HasColumnName("order"); + + b.Property("PrimaryStat") + .HasColumnType("smallint") + .HasColumnName("primary_stat"); + + b.Property("Role") + .HasColumnType("smallint") + .HasColumnName("role"); + + b.HasKey("Id") + .HasName("pk_wow_character_specialization"); + + b.ToTable("wow_character_specialization", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowCurrency", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CategoryId") + .HasColumnType("smallint") + .HasColumnName("category_id"); + + b.Property("Flags") + .HasColumnType("smallint") + .HasColumnName("flags"); + + b.Property("MaxPerWeek") + .HasColumnType("integer") + .HasColumnName("max_per_week"); + + b.Property("MaxTotal") + .HasColumnType("integer") + .HasColumnName("max_total"); + + b.Property("RechargeAmount") + .HasColumnType("smallint") + .HasColumnName("recharge_amount"); + + b.Property("RechargeInterval") + .HasColumnType("bigint") + .HasColumnName("recharge_interval"); + + b.Property("TransferPercent") + .HasColumnType("smallint") + .HasColumnName("transfer_percent"); + + b.HasKey("Id") + .HasName("pk_wow_currency"); + + b.ToTable("wow_currency", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowCurrencyCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Expansion") + .HasColumnType("smallint") + .HasColumnName("expansion"); + + b.Property("Flags") + .HasColumnType("smallint") + .HasColumnName("flags"); + + b.HasKey("Id") + .HasName("pk_wow_currency_category"); + + b.ToTable("wow_currency_category", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowDecor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("Type") + .HasColumnType("smallint") + .HasColumnName("type"); + + b.HasKey("Id") + .HasName("pk_wow_decor"); + + b.ToTable("wow_decor", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowHoliday", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DescriptionId") + .HasColumnType("smallint") + .HasColumnName("description_id"); + + b.PrimitiveCollection>("Durations") + .HasColumnType("smallint[]") + .HasColumnName("durations"); + + b.Property("FilterType") + .HasColumnType("smallint") + .HasColumnName("filter_type"); + + b.Property("Flags") + .HasColumnType("smallint") + .HasColumnName("flags"); + + b.Property("Looping") + .HasColumnType("smallint") + .HasColumnName("looping"); + + b.Property("NameId") + .HasColumnType("smallint") + .HasColumnName("name_id"); + + b.Property("Priority") + .HasColumnType("smallint") + .HasColumnName("priority"); + + b.Property("Region") + .HasColumnType("smallint") + .HasColumnName("region"); + + b.PrimitiveCollection>("StartDates") + .HasColumnType("timestamp with time zone[]") + .HasColumnName("start_dates"); + + b.HasKey("Id") + .HasName("pk_wow_holiday"); + + b.ToTable("wow_holiday", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BindType") + .HasColumnType("smallint") + .HasColumnName("bind_type"); + + b.Property("ClassId") + .HasColumnType("smallint") + .HasColumnName("class_id"); + + b.Property("ClassMask") + .HasColumnType("integer") + .HasColumnName("class_mask"); + + b.PrimitiveCollection("CompletesQuestIds") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("integer[]") + .HasDefaultValue(new int[0]) + .HasColumnName("completes_quest_ids"); + + b.Property("ContainerSlots") + .HasColumnType("smallint") + .HasColumnName("container_slots"); + + b.Property("CraftingQuality") + .HasColumnType("smallint") + .HasColumnName("crafting_quality"); + + b.Property("Expansion") + .HasColumnType("smallint") + .HasColumnName("expansion"); + + b.Property("Flags") + .HasColumnType("smallint") + .HasColumnName("flags"); + + b.Property("InventoryType") + .HasColumnType("smallint") + .HasColumnName("inventory_type"); + + b.Property("ItemLevel") + .HasColumnType("smallint") + .HasColumnName("item_level"); + + b.Property("LimitCategory") + .HasColumnType("smallint") + .HasColumnName("limit_category"); + + b.Property("OppositeFactionId") + .HasColumnType("integer") + .HasColumnName("opposite_faction_id"); + + b.Property("PrimaryStat") + .HasColumnType("smallint") + .HasColumnName("primary_stat"); + + b.Property("Quality") + .HasColumnType("smallint") + .HasColumnName("quality"); + + b.Property("RaceMask") + .HasColumnType("bigint") + .HasColumnName("race_mask"); + + b.Property("RequiredAbility") + .HasColumnType("integer") + .HasColumnName("required_ability"); + + b.Property("RequiredLevel") + .HasColumnType("smallint") + .HasColumnName("required_level"); + + b.Property("RequiredSkill") + .HasColumnType("smallint") + .HasColumnName("required_skill"); + + b.Property("RequiredSkillRank") + .HasColumnType("smallint") + .HasColumnName("required_skill_rank"); + + b.PrimitiveCollection("Sockets") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("smallint[]") + .HasDefaultValue(new short[0]) + .HasColumnName("sockets"); + + b.Property("Stackable") + .HasColumnType("integer") + .HasColumnName("stackable"); + + b.Property("SubclassId") + .HasColumnType("smallint") + .HasColumnName("subclass_id"); + + b.PrimitiveCollection("TeachesDecorIds") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("integer[]") + .HasDefaultValue(new int[0]) + .HasColumnName("teaches_decor_ids"); + + b.PrimitiveCollection("TeachesSpellIds") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("integer[]") + .HasDefaultValue(new int[0]) + .HasColumnName("teaches_spell_ids"); + + b.PrimitiveCollection("TeachesTransmogIllusionIds") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("integer[]") + .HasDefaultValue(new int[0]) + .HasColumnName("teaches_transmog_illusion_ids"); + + b.PrimitiveCollection("TeachesTransmogSetIds") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("integer[]") + .HasDefaultValue(new int[0]) + .HasColumnName("teaches_transmog_set_ids"); + + b.Property("Unique") + .HasColumnType("smallint") + .HasColumnName("unique"); + + b.HasKey("Id") + .HasName("pk_wow_item"); + + b.ToTable("wow_item", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowItemBonus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BonusTypeFlags") + .HasColumnType("bigint") + .HasColumnName("bonus_type_flags"); + + b.Property>>("Bonuses") + .HasColumnType("jsonb") + .HasColumnName("bonuses"); + + b.HasKey("Id") + .HasName("pk_wow_item_bonus"); + + b.ToTable("wow_item_bonus", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowItemClass", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClassId") + .HasColumnType("smallint") + .HasColumnName("class_id"); + + b.HasKey("Id") + .HasName("pk_wow_item_class"); + + b.ToTable("wow_item_class", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowItemEffect", b => + { + b.Property("ItemXItemEffectId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("item_x_item_effect_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ItemXItemEffectId")); + + b.Property("Effect") + .HasColumnType("integer") + .HasColumnName("effect"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.PrimitiveCollection("Values") + .HasColumnType("integer[]") + .HasColumnName("values"); + + b.HasKey("ItemXItemEffectId") + .HasName("pk_wow_item_effect"); + + b.ToTable("wow_item_effect", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowItemEffectV2", b => + { + b.Property("ItemId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("item_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ItemId")); + + b.PrimitiveCollection>("ItemEffectIds") + .HasColumnType("integer[]") + .HasColumnName("item_effect_ids"); + + b.Property>>("SpellEffects") + .HasColumnType("jsonb") + .HasColumnName("spell_effects"); + + b.HasKey("ItemId") + .HasName("pk_wow_item_effect_v2"); + + b.ToTable("wow_item_effect_v2", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowItemModifiedAppearance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AppearanceId") + .HasColumnType("integer") + .HasColumnName("appearance_id"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("Modifier") + .HasColumnType("smallint") + .HasColumnName("modifier"); + + b.Property("Order") + .HasColumnType("smallint") + .HasColumnName("order"); + + b.Property("SourceType") + .HasColumnType("smallint") + .HasColumnName("source_type"); + + b.HasKey("Id") + .HasName("pk_wow_item_modified_appearance"); + + b.ToTable("wow_item_modified_appearance", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowItemSubclass", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AuctionHouseSortOrder") + .HasColumnType("smallint") + .HasColumnName("auction_house_sort_order"); + + b.Property("ClassId") + .HasColumnType("smallint") + .HasColumnName("class_id"); + + b.Property("SubclassId") + .HasColumnType("smallint") + .HasColumnName("subclass_id"); + + b.HasKey("Id") + .HasName("pk_wow_item_subclass"); + + b.ToTable("wow_item_subclass", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowJournalInstance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Flags") + .HasColumnType("integer") + .HasColumnName("flags"); + + b.Property("MapId") + .HasColumnType("smallint") + .HasColumnName("map_id"); + + b.HasKey("Id") + .HasName("pk_wow_journal_instance"); + + b.ToTable("wow_journal_instance", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowMount", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Flags") + .HasColumnType("integer") + .HasColumnName("flags"); + + b.PrimitiveCollection>("ItemIds") + .HasColumnType("integer[]") + .HasColumnName("item_ids"); + + b.Property("SourceType") + .HasColumnType("smallint") + .HasColumnName("source_type"); + + b.Property("SpellId") + .HasColumnType("integer") + .HasColumnName("spell_id"); + + b.HasKey("Id") + .HasName("pk_wow_mount"); + + b.ToTable("wow_mount", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowMythicPlusSeason", b => + { + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.HasKey("Region", "Id") + .HasName("pk_wow_mythic_plus_season"); + + b.ToTable("wow_mythic_plus_season", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowPeriod", b => + { + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Ends") + .HasColumnType("timestamp with time zone") + .HasColumnName("ends"); + + b.Property("Starts") + .HasColumnType("timestamp with time zone") + .HasColumnName("starts"); + + b.HasKey("Region", "Id") + .HasName("pk_wow_period"); + + b.ToTable("wow_period", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowPet", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatureId") + .HasColumnType("integer") + .HasColumnName("creature_id"); + + b.Property("Flags") + .HasColumnType("integer") + .HasColumnName("flags"); + + b.PrimitiveCollection>("ItemIds") + .HasColumnType("integer[]") + .HasColumnName("item_ids"); + + b.Property("PetType") + .HasColumnType("smallint") + .HasColumnName("pet_type"); + + b.Property("SourceType") + .HasColumnType("smallint") + .HasColumnName("source_type"); + + b.Property("SpellId") + .HasColumnType("integer") + .HasColumnName("spell_id"); + + b.HasKey("Id") + .HasName("pk_wow_pet"); + + b.ToTable("wow_pet", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowProfessionRecipeItem", b => + { + b.Property("SkillLineAbilityId") + .HasColumnType("integer") + .HasColumnName("skill_line_ability_id"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("SkillLineId") + .HasColumnType("integer") + .HasColumnName("skill_line_id"); + + b.HasKey("SkillLineAbilityId", "ItemId") + .HasName("pk_wow_profession_recipe_item"); + + b.ToTable("wow_profession_recipe_item", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowQuest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AreaId") + .HasColumnType("integer") + .HasColumnName("area_id"); + + b.Property("CategoryId") + .HasColumnType("integer") + .HasColumnName("category_id"); + + b.Property("LastApiCheck") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_api_check"); + + b.Property("MaximumLevel") + .HasColumnType("smallint") + .HasColumnName("maximum_level"); + + b.Property("MinimumLevel") + .HasColumnType("smallint") + .HasColumnName("minimum_level"); + + b.HasKey("Id") + .HasName("pk_wow_quest"); + + b.ToTable("wow_quest", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowQuestLine", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.PrimitiveCollection>("QuestIds") + .HasColumnType("integer[]") + .HasColumnName("quest_ids"); + + b.HasKey("Id") + .HasName("pk_wow_quest_line"); + + b.ToTable("wow_quest_line", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowRealm", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("ConnectedRealmId") + .HasColumnType("integer") + .HasColumnName("connected_realm_id"); + + b.Property("EnglishName") + .HasColumnType("text") + .HasColumnName("english_name"); + + b.Property("Locale") + .HasColumnType("text") + .HasColumnName("locale"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.Property("Slug") + .HasColumnType("text") + .HasColumnName("slug"); + + b.HasKey("Id") + .HasName("pk_wow_realm"); + + b.ToTable("wow_realm", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowReputation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountWide") + .HasColumnType("boolean") + .HasColumnName("account_wide"); + + b.PrimitiveCollection>("BaseValues") + .HasColumnType("integer[]") + .HasColumnName("base_values"); + + b.Property("Expansion") + .HasColumnType("smallint") + .HasColumnName("expansion"); + + b.PrimitiveCollection>("MaxValues") + .HasColumnType("integer[]") + .HasColumnName("max_values"); + + b.Property("ParagonId") + .HasColumnType("smallint") + .HasColumnName("paragon_id"); + + b.Property("ParagonQuestId") + .HasColumnType("integer") + .HasColumnName("paragon_quest_id"); + + b.Property("ParagonThreshold") + .HasColumnType("integer") + .HasColumnName("paragon_threshold"); + + b.Property("ParentId") + .HasColumnType("smallint") + .HasColumnName("parent_id"); + + b.Property("RenownCurrencyId") + .HasColumnType("smallint") + .HasColumnName("renown_currency_id"); + + b.Property("TierId") + .HasColumnType("smallint") + .HasColumnName("tier_id"); + + b.HasKey("Id") + .HasName("pk_wow_reputation"); + + b.ToTable("wow_reputation", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowReputationTier", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.PrimitiveCollection("MinValues") + .HasColumnType("integer[]") + .HasColumnName("min_values"); + + b.HasKey("Id") + .HasName("pk_wow_reputation_tier"); + + b.ToTable("wow_reputation_tier", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowToy", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Flags") + .HasColumnType("integer") + .HasColumnName("flags"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("SourceType") + .HasColumnType("smallint") + .HasColumnName("source_type"); + + b.HasKey("Id") + .HasName("pk_wow_toy"); + + b.ToTable("wow_toy", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowTransmogSet", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClassMask") + .HasColumnType("integer") + .HasColumnName("class_mask"); + + b.Property("Flags") + .HasColumnType("smallint") + .HasColumnName("flags"); + + b.Property("GroupId") + .HasColumnType("smallint") + .HasColumnName("group_id"); + + b.PrimitiveCollection>("ItemModifiedAppearanceIds") + .HasColumnType("integer[]") + .HasColumnName("item_modified_appearance_ids"); + + b.Property("ItemNameDescriptionId") + .HasColumnType("integer") + .HasColumnName("item_name_description_id"); + + b.HasKey("Id") + .HasName("pk_wow_transmog_set"); + + b.ToTable("wow_transmog_set", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowWorldQuest", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Expansion") + .HasColumnType("smallint") + .HasColumnName("expansion"); + + b.Property("Faction") + .HasColumnType("smallint") + .HasColumnName("faction"); + + b.Property("MaxLevel") + .HasColumnType("smallint") + .HasColumnName("max_level"); + + b.Property("MinLevel") + .HasColumnType("smallint") + .HasColumnName("min_level"); + + b.PrimitiveCollection>("NeedQuestIds") + .HasColumnType("integer[]") + .HasColumnName("need_quest_ids"); + + b.Property("QuestInfoId") + .HasColumnType("smallint") + .HasColumnName("quest_info_id"); + + b.PrimitiveCollection>("SkipQuestIds") + .HasColumnType("integer[]") + .HasColumnName("skip_quest_ids"); + + b.HasKey("Id") + .HasName("pk_wow_world_quest"); + + b.ToTable("wow_world_quest", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_asp_net_role_claims_asp_net_roles_role_id"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_asp_net_user_claims_asp_net_users_user_id"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_asp_net_user_logins_asp_net_users_user_id"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_asp_net_user_roles_asp_net_roles_role_id"); + + b.HasOne("Wowthing.Lib.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_asp_net_user_roles_asp_net_users_user_id"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_asp_net_user_tokens_asp_net_users_user_id"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.BackgroundImage", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", "Role") + .WithMany() + .HasForeignKey("RoleId") + .HasConstraintName("fk_background_image_roles_role_id"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.MiscReport", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_misc_report_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccount", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .HasConstraintName("fk_player_account_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountAddonData", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("AddonData") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountAddonData", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_addon_data_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountGoldSnapshot", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithMany() + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_gold_snapshot_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountHeirlooms", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("Heirlooms") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountHeirlooms", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_heirlooms_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountMounts", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("Mounts") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountMounts", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_mounts_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountPets", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("Pets") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountPets", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_pets_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountToys", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("Toys") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountToys", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_toys_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountTransmogIds", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("TransmogIds") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountTransmogIds", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_transmog_ids_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountTransmogSources", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("TransmogSources") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountTransmogSources", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_transmog_sources_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacter", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithMany("Characters") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("fk_player_character_player_account_account_id"); + + b.HasOne("Wowthing.Lib.Models.Player.PlayerGuild", "Guild") + .WithMany() + .HasForeignKey("GuildId") + .HasConstraintName("fk_player_character_player_guild_guild_id"); + + b.Navigation("Account"); + + b.Navigation("Guild"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAchievements", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Achievements") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterAchievements", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_achievements_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonAchievements", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("AddonAchievements") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterAddonAchievements", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_addon_achievements_player_character_charac"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonData", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("AddonData") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterAddonData", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_addon_data_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonMounts", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("AddonMounts") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterAddonMounts", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_addon_mounts_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonQuests", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("AddonQuests") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterAddonQuests", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_addon_quests_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterConfiguration", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Configuration") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterConfiguration", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_configuration_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterEquippedItems", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("EquippedItems") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterEquippedItems", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_equipped_items_player_character_character_"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterItem", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithMany("Items") + .HasForeignKey("CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_item_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterLockouts", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Lockouts") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterLockouts", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_lockouts_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMedia", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Media") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterMedia", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_media_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMounts", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Mounts") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterMounts", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_mounts_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlus", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("MythicPlus") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlus", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_mythic_plus_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlusAddon", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("MythicPlusAddon") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlusAddon", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_mythic_plus_addon_player_character_charact"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlusSeason", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithMany("MythicPlusSeasons") + .HasForeignKey("CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_mythic_plus_season_player_character_charac"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterProfessions", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Professions") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterProfessions", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_professions_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterQuests", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Quests") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterQuests", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_quests_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterRaiderIo", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("RaiderIo") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterRaiderIo", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_raider_io_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterReputations", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Reputations") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterReputations", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_reputations_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterShadowlands", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Shadowlands") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterShadowlands", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_shadowlands_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterSpecializations", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Specializations") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterSpecializations", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_specializations_player_character_character"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterStatistics", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithMany() + .HasForeignKey("CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_statistics_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterStats", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Stats") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterStats", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_stats_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterTransmog", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Transmog") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterTransmog", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_transmog_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterWeekly", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Weekly") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterWeekly", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_weekly_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerGuild", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_guild_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerGuildItem", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerGuild", "Guild") + .WithMany("Items") + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_guild_item_player_guild_guild_id"); + + b.Navigation("Guild"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerWarbankItem", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_warbank_item_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Team.Team", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_team_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Team.TeamCharacter", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithMany() + .HasForeignKey("CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_team_character_player_character_character_id"); + + b.HasOne("Wowthing.Lib.Models.Team.Team", "Team") + .WithMany("Characters") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_team_character_team_team_id"); + + b.Navigation("Character"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserAddonData", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_addon_data_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserBulkData", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_bulk_data_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserCache", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_cache_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserGoldSnapshot", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .HasConstraintName("fk_user_gold_snapshot_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserLeaderboardSnapshot", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_leaderboard_snapshot_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.WorldQuestReport", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_world_quest_report_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccount", b => + { + b.Navigation("AddonData"); + + b.Navigation("Characters"); + + b.Navigation("Heirlooms"); + + b.Navigation("Mounts"); + + b.Navigation("Pets"); + + b.Navigation("Toys"); + + b.Navigation("TransmogIds"); + + b.Navigation("TransmogSources"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacter", b => + { + b.Navigation("Achievements"); + + b.Navigation("AddonAchievements"); + + b.Navigation("AddonData"); + + b.Navigation("AddonMounts"); + + b.Navigation("AddonQuests"); + + b.Navigation("Configuration"); + + b.Navigation("EquippedItems"); + + b.Navigation("Items"); + + b.Navigation("Lockouts"); + + b.Navigation("Media"); + + b.Navigation("Mounts"); + + b.Navigation("MythicPlus"); + + b.Navigation("MythicPlusAddon"); + + b.Navigation("MythicPlusSeasons"); + + b.Navigation("Professions"); + + b.Navigation("Quests"); + + b.Navigation("RaiderIo"); + + b.Navigation("Reputations"); + + b.Navigation("Shadowlands"); + + b.Navigation("Specializations"); + + b.Navigation("Stats"); + + b.Navigation("Transmog"); + + b.Navigation("Weekly"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerGuild", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Team.Team", b => + { + b.Navigation("Characters"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/packages/csharp-lib/Migrations/20260703195433_Add_PlayerCharacterQuests_CompressedCompletedIds.cs b/packages/csharp-lib/Migrations/20260703195433_Add_PlayerCharacterQuests_CompressedCompletedIds.cs new file mode 100644 index 000000000..053cc70e0 --- /dev/null +++ b/packages/csharp-lib/Migrations/20260703195433_Add_PlayerCharacterQuests_CompressedCompletedIds.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Wowthing.Lib.Migrations +{ + /// + public partial class Add_PlayerCharacterQuests_CompressedCompletedIds : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "compressed_completed_ids", + table: "player_character_quests", + type: "bytea", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "compressed_completed_ids", + table: "player_character_quests"); + } + } +} diff --git a/packages/csharp-lib/Migrations/20260704181432_More_PlayerCharacterQuests_Things.Designer.cs b/packages/csharp-lib/Migrations/20260704181432_More_PlayerCharacterQuests_Things.Designer.cs new file mode 100644 index 000000000..608f4ce04 --- /dev/null +++ b/packages/csharp-lib/Migrations/20260704181432_More_PlayerCharacterQuests_Things.Designer.cs @@ -0,0 +1,4522 @@ +// +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Wowthing.Lib.Contexts; +using Wowthing.Lib.Enums; +using Wowthing.Lib.Models; +using Wowthing.Lib.Models.Global; +using Wowthing.Lib.Models.Player; +using Wowthing.Lib.Models.Wow; + +#nullable disable + +namespace Wowthing.Lib.Migrations +{ + [DbContext(typeof(WowDbContext))] + [Migration("20260704181432_More_PlayerCharacterQuests_Things")] + partial class More_PlayerCharacterQuests_Things + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text") + .HasColumnName("concurrency_stamp"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("name"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("normalized_name"); + + b.HasKey("Id") + .HasName("pk_asp_net_roles"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("asp_net_roles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text") + .HasColumnName("claim_type"); + + b.Property("ClaimValue") + .HasColumnType("text") + .HasColumnName("claim_value"); + + b.Property("RoleId") + .HasColumnType("bigint") + .HasColumnName("role_id"); + + b.HasKey("Id") + .HasName("pk_asp_net_role_claims"); + + b.HasIndex("RoleId") + .HasDatabaseName("ix_asp_net_role_claims_role_id"); + + b.ToTable("asp_net_role_claims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text") + .HasColumnName("claim_type"); + + b.Property("ClaimValue") + .HasColumnType("text") + .HasColumnName("claim_value"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_asp_net_user_claims"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_asp_net_user_claims_user_id"); + + b.ToTable("asp_net_user_claims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("text") + .HasColumnName("login_provider"); + + b.Property("ProviderKey") + .HasColumnType("text") + .HasColumnName("provider_key"); + + b.Property("ProviderDisplayName") + .HasColumnType("text") + .HasColumnName("provider_display_name"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("LoginProvider", "ProviderKey") + .HasName("pk_asp_net_user_logins"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_asp_net_user_logins_user_id"); + + b.ToTable("asp_net_user_logins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.Property("RoleId") + .HasColumnType("bigint") + .HasColumnName("role_id"); + + b.HasKey("UserId", "RoleId") + .HasName("pk_asp_net_user_roles"); + + b.HasIndex("RoleId") + .HasDatabaseName("ix_asp_net_user_roles_role_id"); + + b.ToTable("asp_net_user_roles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.Property("LoginProvider") + .HasColumnType("text") + .HasColumnName("login_provider"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("Value") + .HasColumnType("text") + .HasColumnName("value"); + + b.HasKey("UserId", "LoginProvider", "Name") + .HasName("pk_asp_net_user_tokens"); + + b.ToTable("asp_net_user_tokens", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.ApplicationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessFailedCount") + .HasColumnType("integer") + .HasColumnName("access_failed_count"); + + b.Property("ApiKey") + .HasColumnType("text") + .HasColumnName("api_key"); + + b.Property("CanUseSubdomain") + .HasColumnType("boolean") + .HasColumnName("can_use_subdomain"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text") + .HasColumnName("concurrency_stamp"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("email"); + + b.Property("EmailConfirmed") + .HasColumnType("boolean") + .HasColumnName("email_confirmed"); + + b.Property("LastApiCheck") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_api_check"); + + b.Property("LastVisit") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_visit"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean") + .HasColumnName("lockout_enabled"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone") + .HasColumnName("lockout_end"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("normalized_email"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("normalized_user_name"); + + b.Property("PasswordHash") + .HasColumnType("text") + .HasColumnName("password_hash"); + + b.Property("PhoneNumber") + .HasColumnType("text") + .HasColumnName("phone_number"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean") + .HasColumnName("phone_number_confirmed"); + + b.Property("SecurityStamp") + .HasColumnType("text") + .HasColumnName("security_stamp"); + + b.Property("Settings") + .HasColumnType("jsonb") + .HasColumnName("settings"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean") + .HasColumnName("two_factor_enabled"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("user_name"); + + b.HasKey("Id") + .HasName("pk_asp_net_users"); + + b.HasIndex("ApiKey") + .IsUnique() + .HasDatabaseName("ix_asp_net_users_api_key"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("asp_net_users", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Action") + .HasColumnType("text") + .HasColumnName("action"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone") + .HasColumnName("timestamp"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_audit_log"); + + b.ToTable("audit_log", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.BackgroundImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Attribution") + .HasColumnType("text") + .HasColumnName("attribution"); + + b.Property("DefaultBrightness") + .HasColumnType("smallint") + .HasColumnName("default_brightness"); + + b.Property("DefaultSaturate") + .HasColumnType("smallint") + .HasColumnName("default_saturate"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("Filename") + .HasColumnType("text") + .HasColumnName("filename"); + + b.Property("RoleId") + .HasColumnType("bigint") + .HasColumnName("role_id"); + + b.HasKey("Id") + .HasName("pk_background_image"); + + b.HasIndex("RoleId") + .HasDatabaseName("ix_background_image_role_id"); + + b.ToTable("background_image", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Global.GlobalDailies", b => + { + b.Property("Expansion") + .HasColumnType("integer") + .HasColumnName("expansion"); + + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.PrimitiveCollection>("QuestExpires") + .HasColumnType("integer[]") + .HasColumnName("quest_expires"); + + b.PrimitiveCollection>("QuestIds") + .HasColumnType("integer[]") + .HasColumnName("quest_ids"); + + b.Property>("QuestRewards") + .HasColumnType("jsonb") + .HasColumnName("quest_rewards"); + + b.HasKey("Expansion", "Region") + .HasName("pk_global_dailies"); + + b.ToTable("global_dailies", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Image", b => + { + b.Property("Type") + .HasColumnType("integer") + .HasColumnName("type"); + + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Format") + .HasColumnType("smallint") + .HasColumnName("format"); + + b.Property("Data") + .HasColumnType("bytea") + .HasColumnName("data"); + + b.Property("Sha256") + .HasColumnType("char(64)") + .HasColumnName("sha256"); + + b.HasKey("Type", "Id", "Format") + .HasName("pk_image"); + + b.HasIndex("Type", "Sha256", "Format") + .HasDatabaseName("ix_image_type_sha256_format"); + + b.ToTable("image", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.LanguageString", b => + { + b.Property("Language") + .HasColumnType("smallint") + .HasColumnName("language"); + + b.Property("Type") + .HasColumnType("smallint") + .HasColumnName("type"); + + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("String") + .HasColumnType("text") + .HasColumnName("string"); + + b.HasKey("Language", "Type", "Id") + .HasName("pk_language_string"); + + b.HasIndex("String") + .HasDatabaseName("ix_language_string_string"); + + NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("String"), "gin"); + NpgsqlIndexBuilderExtensions.HasOperators(b.HasIndex("String"), new[] { "gin_trgm_ops" }); + + b.HasIndex("Language", "Type", "Id") + .HasDatabaseName("ix_language_string_language_type_id"); + + b.ToTable("language_string", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.MiscAggregate", b => + { + b.Property("Region") + .HasColumnType("smallint") + .HasColumnName("region"); + + b.Property("ReportType") + .HasColumnType("smallint") + .HasColumnName("report_type"); + + b.Property("JsonData") + .HasColumnType("text") + .HasColumnName("json_data"); + + b.HasKey("Region", "ReportType") + .HasName("pk_misc_aggregate"); + + b.ToTable("misc_aggregate", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.MiscReport", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Data") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("data"); + + b.Property("ExpiresAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("expires_at"); + + b.Property("Region") + .HasColumnType("smallint") + .HasColumnName("region"); + + b.Property("ReportType") + .HasColumnType("smallint") + .HasColumnName("report_type"); + + b.Property("ReportedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("reported_at"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_misc_report"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_misc_report_user_id"); + + b.HasIndex("ReportType", "Region", "ExpiresAt") + .IsDescending(false, false, true) + .HasDatabaseName("ix_misc_report_report_type_region_expires_at"); + + b.ToTable("misc_report", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccount", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("bigint") + .HasColumnName("account_id"); + + b.Property("Enabled") + .HasColumnType("boolean") + .HasColumnName("enabled"); + + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.Property("Tag") + .HasColumnType("text") + .HasColumnName("tag"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_player_account"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_player_account_user_id"); + + b.HasIndex("Region", "AccountId") + .IsUnique() + .HasDatabaseName("ix_player_account_region_account_id"); + + b.ToTable("player_account", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountAddonData", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property>>("Decor") + .HasColumnType("jsonb") + .HasColumnName("decor"); + + b.Property("DecorScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("decor_scanned_at"); + + b.Property>("Heirlooms") + .HasColumnType("jsonb") + .HasColumnName("heirlooms"); + + b.Property("HonorCurrent") + .HasColumnType("smallint") + .HasColumnName("honor_current"); + + b.Property("HonorLevel") + .HasColumnType("smallint") + .HasColumnName("honor_level"); + + b.Property("HonorMax") + .HasColumnType("smallint") + .HasColumnName("honor_max"); + + b.PrimitiveCollection>("Illusions") + .HasColumnType("integer[]") + .HasColumnName("illusions"); + + b.PrimitiveCollection>("Quests") + .HasColumnType("integer[]") + .HasColumnName("quests"); + + b.Property>("Reputations") + .HasColumnType("jsonb") + .HasColumnName("reputations"); + + b.Property("ReputationsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("reputations_scanned_at"); + + b.HasKey("AccountId") + .HasName("pk_player_account_addon_data"); + + b.ToTable("player_account_addon_data", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountGoldSnapshot", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property("Gold") + .HasColumnType("integer") + .HasColumnName("gold"); + + b.Property("RealmId") + .HasColumnType("integer") + .HasColumnName("realm_id"); + + b.Property("Time") + .HasColumnType("timestamp with time zone") + .HasColumnName("time"); + + b.HasKey("Id") + .HasName("pk_player_account_gold_snapshot"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_player_account_gold_snapshot_account_id"); + + b.ToTable("player_account_gold_snapshot", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountHeirlooms", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property>("Heirlooms") + .HasColumnType("jsonb") + .HasColumnName("heirlooms"); + + b.HasKey("AccountId") + .HasName("pk_player_account_heirlooms"); + + b.ToTable("player_account_heirlooms", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountMounts", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.PrimitiveCollection>("MountIds") + .HasColumnType("integer[]") + .HasColumnName("mount_ids"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("AccountId") + .HasName("pk_player_account_mounts"); + + b.ToTable("player_account_mounts", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountPets", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property>("Pets") + .HasColumnType("jsonb") + .HasColumnName("pets"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("AccountId") + .HasName("pk_player_account_pets"); + + b.ToTable("player_account_pets", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountToys", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.PrimitiveCollection>("ToyIds") + .HasColumnType("integer[]") + .HasColumnName("toy_ids"); + + b.HasKey("AccountId") + .HasName("pk_player_account_toys"); + + b.ToTable("player_account_toys", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountTransmogIds", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.PrimitiveCollection>("Ids") + .HasColumnType("integer[]") + .HasColumnName("ids"); + + b.HasKey("AccountId") + .HasName("pk_player_account_transmog_ids"); + + b.ToTable("player_account_transmog_ids", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountTransmogSources", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.PrimitiveCollection>("Sources") + .HasColumnType("text[]") + .HasColumnName("sources"); + + b.HasKey("AccountId") + .HasName("pk_player_account_transmog_sources"); + + b.ToTable("player_account_transmog_sources", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacter", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property("ActiveSpecId") + .HasColumnType("integer") + .HasColumnName("active_spec_id"); + + b.Property("ActiveTitleId") + .HasColumnType("integer") + .HasColumnName("active_title_id"); + + b.Property("AverageItemLevel") + .HasColumnType("integer") + .HasColumnName("average_item_level"); + + b.Property("CharacterId") + .HasColumnType("bigint") + .HasColumnName("character_id"); + + b.Property("ChromieTime") + .HasColumnType("integer") + .HasColumnName("chromie_time"); + + b.Property("ClassId") + .HasColumnType("integer") + .HasColumnName("class_id"); + + b.Property("Copper") + .HasColumnType("bigint") + .HasColumnName("copper"); + + b.Property("EquippedItemLevel") + .HasColumnType("integer") + .HasColumnName("equipped_item_level"); + + b.Property("Experience") + .HasColumnType("integer") + .HasColumnName("experience"); + + b.Property("Faction") + .HasColumnType("smallint") + .HasColumnName("faction"); + + b.Property("Gender") + .HasColumnType("integer") + .HasColumnName("gender"); + + b.Property("GuildId") + .HasColumnType("integer") + .HasColumnName("guild_id"); + + b.Property("IsResting") + .HasColumnType("boolean") + .HasColumnName("is_resting"); + + b.Property("IsWarMode") + .HasColumnType("boolean") + .HasColumnName("is_war_mode"); + + b.Property("LastApiCheck") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_api_check"); + + b.Property("LastApiModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_api_modified"); + + b.Property("LastSeenAddon") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_seen_addon"); + + b.Property("Level") + .HasColumnType("integer") + .HasColumnName("level"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("PlayedTotal") + .HasColumnType("integer") + .HasColumnName("played_total"); + + b.Property("RaceId") + .HasColumnType("integer") + .HasColumnName("race_id"); + + b.Property("RealmId") + .HasColumnType("integer") + .HasColumnName("realm_id"); + + b.Property("RestedExperience") + .HasColumnType("integer") + .HasColumnName("rested_experience"); + + b.Property("ShouldUpdate") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(true) + .HasColumnName("should_update"); + + b.HasKey("Id") + .HasName("pk_player_character"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_player_character_account_id"); + + b.HasIndex("GuildId") + .HasDatabaseName("ix_player_character_guild_id"); + + b.HasIndex("LastApiCheck") + .HasDatabaseName("ix_player_character_last_api_check") + .HasFilter("should_update = true AND account_id IS NOT NULL"); + + NpgsqlIndexBuilderExtensions.IncludeProperties(b.HasIndex("LastApiCheck"), new[] { "Id", "AccountId", "Name", "LastApiModified" }); + + b.HasIndex("CharacterId", "LastSeenAddon") + .HasDatabaseName("ix_player_character_character_id_last_seen_addon") + .HasFilter("account_id IS NOT NULL"); + + b.HasIndex("RealmId", "Name") + .IsUnique() + .HasDatabaseName("ix_player_character_realm_id_name"); + + b.ToTable("player_character", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAchievements", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("AchievementIds") + .HasColumnType("integer[]") + .HasColumnName("achievement_ids"); + + b.PrimitiveCollection>("AchievementTimestamps") + .HasColumnType("integer[]") + .HasColumnName("achievement_timestamps"); + + b.PrimitiveCollection>("CriteriaAmounts") + .HasColumnType("bigint[]") + .HasColumnName("criteria_amounts"); + + b.PrimitiveCollection>("CriteriaCompleted") + .HasColumnType("boolean[]") + .HasColumnName("criteria_completed"); + + b.PrimitiveCollection>("CriteriaIds") + .HasColumnType("integer[]") + .HasColumnName("criteria_ids"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_achievements"); + + b.ToTable("player_character_achievements", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonAchievements", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("Achievements") + .HasColumnType("jsonb") + .HasColumnName("achievements"); + + b.Property("ScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("scanned_at"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_addon_achievements"); + + b.ToTable("player_character_addon_achievements", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonData", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("Auras") + .HasColumnType("jsonb") + .HasColumnName("auras"); + + b.Property("BagsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("bags_scanned_at"); + + b.Property("BankScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("bank_scanned_at"); + + b.Property("BankTabs") + .HasColumnType("smallint") + .HasColumnName("bank_tabs"); + + b.Property("BindLocation") + .HasColumnType("text") + .HasColumnName("bind_location"); + + b.Property>("Currencies") + .HasColumnType("jsonb") + .HasColumnName("currencies"); + + b.Property("CurrenciesScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("currencies_scanned_at"); + + b.Property("CurrenciesTransferredAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("currencies_transferred_at"); + + b.Property("CurrentLocation") + .HasColumnType("text") + .HasColumnName("current_location"); + + b.Property("DailyReset") + .HasColumnType("timestamp with time zone") + .HasColumnName("daily_reset"); + + b.Property>("EquippedItems") + .HasColumnType("jsonb") + .HasColumnName("equipped_items"); + + b.Property>>>("GarrisonTrees") + .HasColumnType("jsonb") + .HasColumnName("garrison_trees"); + + b.Property("GarrisonTreesScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("garrison_trees_scanned_at"); + + b.Property>("Garrisons") + .HasColumnType("jsonb") + .HasColumnName("garrisons"); + + b.Property>("HighestItemLevel") + .HasColumnType("jsonb") + .HasColumnName("highest_item_level"); + + b.PrimitiveCollection>("KnownSpells") + .HasColumnType("integer[]") + .HasColumnName("known_spells"); + + b.Property("Level") + .HasColumnType("smallint") + .HasColumnName("level"); + + b.Property("LevelXp") + .HasColumnType("integer") + .HasColumnName("level_xp"); + + b.Property>("MythicPlus") + .HasColumnType("jsonb") + .HasColumnName("mythic_plus"); + + b.Property("MythicPlusScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("mythic_plus_scanned_at"); + + b.Property>>("MythicPlusSeasons") + .HasColumnType("jsonb") + .HasColumnName("mythic_plus_seasons"); + + b.Property>>("MythicPlusWeeks") + .HasColumnType("jsonb") + .HasColumnName("mythic_plus_weeks"); + + b.Property>("Paragons") + .HasColumnType("jsonb") + .HasColumnName("paragons"); + + b.Property>>("PatronOrders") + .HasColumnType("jsonb") + .HasColumnName("patron_orders"); + + b.Property("PatronOrdersScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("patron_orders_scanned_at"); + + b.Property>>("ProfessionCooldowns") + .HasColumnType("jsonb") + .HasColumnName("profession_cooldowns"); + + b.Property>>("ProfessionTraits") + .HasColumnType("jsonb") + .HasColumnName("profession_traits"); + + b.Property>("Professions") + .HasColumnType("jsonb") + .HasColumnName("professions"); + + b.Property>("Reputations") + .HasColumnType("jsonb") + .HasColumnName("reputations"); + + b.Property("ReputationsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("reputations_scanned_at"); + + b.Property("WeeklyReset") + .HasColumnType("timestamp with time zone") + .HasColumnName("weekly_reset"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_addon_data"); + + b.ToTable("player_character_addon_data", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonMounts", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("Mounts") + .HasColumnType("integer[]") + .HasColumnName("mounts"); + + b.Property("ScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("scanned_at"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_addon_mounts"); + + b.ToTable("player_character_addon_mounts", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonQuests", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("CallingsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("callings_scanned_at"); + + b.PrimitiveCollection>("CompletedQuests") + .HasColumnType("integer[]") + .HasColumnName("completed_quests"); + + b.Property("CompletedQuestsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("completed_quests_scanned_at"); + + b.Property("CompressedCompletedIds") + .HasColumnType("bytea") + .HasColumnName("compressed_completed_ids"); + + b.Property>>>("Dailies") + .HasColumnType("jsonb") + .HasColumnName("dailies"); + + b.Property>>("GoldWorldQuests") + .HasColumnType("jsonb") + .HasColumnName("gold_world_quests"); + + b.Property>("ProgressQuests") + .HasColumnType("jsonb") + .HasColumnName("progress_quests"); + + b.Property("QuestsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("quests_scanned_at"); + + b.Property("WorldQuestsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("world_quests_scanned_at"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_addon_quests"); + + b.ToTable("player_character_addon_quests", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterConfiguration", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("BackgroundBrightness") + .HasColumnType("smallint") + .HasColumnName("background_brightness"); + + b.Property("BackgroundId") + .HasColumnType("smallint") + .HasColumnName("background_id"); + + b.Property("BackgroundSaturation") + .HasColumnType("smallint") + .HasColumnName("background_saturation"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_configuration"); + + b.ToTable("player_character_configuration", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterEquippedItems", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("Items") + .HasColumnType("jsonb") + .HasColumnName("items"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_equipped_items"); + + b.ToTable("player_character_equipped_items", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BindType") + .HasColumnType("smallint") + .HasColumnName("bind_type"); + + b.PrimitiveCollection>("BonusIds") + .HasColumnType("smallint[]") + .HasColumnName("bonus_ids"); + + b.Property("Bound") + .HasColumnType("boolean") + .HasColumnName("bound"); + + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("ContainerId") + .HasColumnType("smallint") + .HasColumnName("container_id"); + + b.Property("Context") + .HasColumnType("smallint") + .HasColumnName("context"); + + b.Property("Count") + .HasColumnType("integer") + .HasColumnName("count"); + + b.Property("CraftedQuality") + .HasColumnType("smallint") + .HasColumnName("crafted_quality"); + + b.Property("EnchantId") + .HasColumnType("smallint") + .HasColumnName("enchant_id"); + + b.PrimitiveCollection>("Gems") + .HasColumnType("integer[]") + .HasColumnName("gems"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("ItemLevel") + .HasColumnType("smallint") + .HasColumnName("item_level"); + + b.Property("Location") + .HasColumnType("smallint") + .HasColumnName("location"); + + b.Property>("Modifiers") + .HasColumnType("jsonb") + .HasColumnName("modifiers"); + + b.Property("Quality") + .HasColumnType("smallint") + .HasColumnName("quality"); + + b.Property("Slot") + .HasColumnType("smallint") + .HasColumnName("slot"); + + b.Property("SuffixId") + .HasColumnType("smallint") + .HasColumnName("suffix_id"); + + b.HasKey("Id") + .HasName("pk_player_character_item"); + + b.HasIndex("CharacterId", "Slot") + .HasDatabaseName("ix_player_character_item_character_id_slot"); + + b.HasIndex("CharacterId", "ItemId", "Location") + .HasDatabaseName("ix_player_character_item_character_id_item_id_location"); + + b.ToTable("player_character_item", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterLockouts", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("LastUpdated") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_updated"); + + b.Property>("Lockouts") + .HasColumnType("jsonb") + .HasColumnName("lockouts"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_lockouts"); + + b.ToTable("player_character_lockouts", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMedia", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("AvatarUrl") + .HasColumnType("text") + .HasColumnName("avatar_url"); + + b.Property("InsetUrl") + .HasColumnType("text") + .HasColumnName("inset_url"); + + b.Property("MainRawUrl") + .HasColumnType("text") + .HasColumnName("main_raw_url"); + + b.Property("MainUrl") + .HasColumnType("text") + .HasColumnName("main_url"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_media"); + + b.ToTable("player_character_media", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMounts", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("Mounts") + .HasColumnType("integer[]") + .HasColumnName("mounts"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_mounts"); + + b.ToTable("player_character_mounts", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlus", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("CurrentPeriodId") + .HasColumnType("integer") + .HasColumnName("current_period_id"); + + b.Property>("PeriodRuns") + .HasColumnType("jsonb") + .HasColumnName("period_runs"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_mythic_plus"); + + b.ToTable("player_character_mythic_plus", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlusAddon", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("Maps") + .HasColumnType("jsonb") + .HasColumnName("maps"); + + b.Property("Season") + .HasColumnType("integer") + .HasColumnName("season"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_mythic_plus_addon"); + + b.ToTable("player_character_mythic_plus_addon", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlusSeason", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("Season") + .HasColumnType("integer") + .HasColumnName("season"); + + b.Property("Rating") + .HasColumnType("double precision") + .HasColumnName("rating"); + + b.Property>("Runs") + .HasColumnType("jsonb") + .HasColumnName("runs"); + + b.HasKey("CharacterId", "Season") + .HasName("pk_player_character_mythic_plus_season"); + + b.ToTable("player_character_mythic_plus_season", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterProfessions", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("ProfessionSpecializations") + .HasColumnType("jsonb") + .HasColumnName("profession_specializations"); + + b.Property>>("Professions") + .HasColumnType("jsonb") + .HasColumnName("professions"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_professions"); + + b.ToTable("player_character_professions", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterQuests", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("CompletedIds") + .HasColumnType("integer[]") + .HasColumnName("completed_ids"); + + b.Property("CompressedCompletedIds") + .HasColumnType("bytea") + .HasColumnName("compressed_completed_ids"); + + b.Property("ScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("scanned_at"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_quests"); + + b.ToTable("player_character_quests", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterRaiderIo", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("Seasons") + .HasColumnType("jsonb") + .HasColumnName("seasons"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_raider_io"); + + b.ToTable("player_character_raider_io", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterReputations", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("ExtraReputationIds") + .HasColumnType("integer[]") + .HasColumnName("extra_reputation_ids"); + + b.PrimitiveCollection>("ExtraReputationValues") + .HasColumnType("integer[]") + .HasColumnName("extra_reputation_values"); + + b.Property>("Paragons") + .HasColumnType("jsonb") + .HasColumnName("paragons"); + + b.PrimitiveCollection>("ReputationIds") + .HasColumnType("integer[]") + .HasColumnName("reputation_ids"); + + b.PrimitiveCollection>("ReputationValues") + .HasColumnType("integer[]") + .HasColumnName("reputation_values"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_reputations"); + + b.ToTable("player_character_reputations", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterShadowlands", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("ConduitIds") + .HasColumnType("integer[]") + .HasColumnName("conduit_ids"); + + b.PrimitiveCollection>("ConduitRanks") + .HasColumnType("integer[]") + .HasColumnName("conduit_ranks"); + + b.Property("CovenantId") + .HasColumnType("integer") + .HasColumnName("covenant_id"); + + b.Property>("Covenants") + .HasColumnType("jsonb") + .HasColumnName("covenants"); + + b.Property("RenownLevel") + .HasColumnType("integer") + .HasColumnName("renown_level"); + + b.Property("SoulbindId") + .HasColumnType("integer") + .HasColumnName("soulbind_id"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_shadowlands"); + + b.ToTable("player_character_shadowlands", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterSpecializations", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("Specializations") + .HasColumnType("jsonb") + .HasColumnName("specializations"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_specializations"); + + b.ToTable("player_character_specializations", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterStatistics", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("StatisticDescriptions") + .HasColumnType("text[]") + .HasColumnName("statistic_descriptions"); + + b.PrimitiveCollection>("StatisticIds") + .HasColumnType("integer[]") + .HasColumnName("statistic_ids"); + + b.PrimitiveCollection>("StatisticQuantities") + .HasColumnType("integer[]") + .HasColumnName("statistic_quantities"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_statistics"); + + b.ToTable("player_character_statistics", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterStats", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("Basic") + .HasColumnType("jsonb") + .HasColumnName("basic"); + + b.Property>("Misc") + .HasColumnType("jsonb") + .HasColumnName("misc"); + + b.Property>("Rating") + .HasColumnType("jsonb") + .HasColumnName("rating"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_stats"); + + b.ToTable("player_character_stats", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterTransmog", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("IllusionIds") + .HasColumnType("integer[]") + .HasColumnName("illusion_ids"); + + b.PrimitiveCollection>("TransmogIds") + .HasColumnType("integer[]") + .HasColumnName("transmog_ids"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_transmog"); + + b.ToTable("player_character_transmog", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterWeekly", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("DelveGilded") + .HasColumnType("smallint") + .HasColumnName("delve_gilded"); + + b.PrimitiveCollection>("DelveLevels") + .HasColumnType("integer[]") + .HasColumnName("delve_levels"); + + b.PrimitiveCollection>("DelveMaps") + .HasColumnType("text[]") + .HasColumnName("delve_maps"); + + b.Property("DelveWeek") + .HasColumnType("integer") + .HasColumnName("delve_week"); + + b.Property("KeystoneDungeon") + .HasColumnType("integer") + .HasColumnName("keystone_dungeon"); + + b.Property("KeystoneLevel") + .HasColumnType("integer") + .HasColumnName("keystone_level"); + + b.Property("KeystoneScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("keystone_scanned_at"); + + b.Property>("Torghast") + .HasColumnType("jsonb") + .HasColumnName("torghast"); + + b.Property("TorghastScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("torghast_scanned_at"); + + b.Property("Vault") + .HasColumnType("jsonb") + .HasColumnName("vault"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_weekly"); + + b.ToTable("player_character_weekly", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerGuild", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("RealmId") + .HasColumnType("integer") + .HasColumnName("realm_id"); + + b.Property>("Tabs") + .HasColumnType("jsonb") + .HasColumnName("tabs"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_player_guild"); + + b.HasIndex("UserId", "RealmId", "Name") + .IsUnique() + .HasDatabaseName("ix_player_guild_user_id_realm_id_name"); + + b.ToTable("player_guild", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerGuildItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BindType") + .HasColumnType("smallint") + .HasColumnName("bind_type"); + + b.PrimitiveCollection>("BonusIds") + .HasColumnType("smallint[]") + .HasColumnName("bonus_ids"); + + b.Property("Bound") + .HasColumnType("boolean") + .HasColumnName("bound"); + + b.Property("ContainerId") + .HasColumnType("smallint") + .HasColumnName("container_id"); + + b.Property("Context") + .HasColumnType("smallint") + .HasColumnName("context"); + + b.Property("Count") + .HasColumnType("integer") + .HasColumnName("count"); + + b.Property("CraftedQuality") + .HasColumnType("smallint") + .HasColumnName("crafted_quality"); + + b.Property("EnchantId") + .HasColumnType("smallint") + .HasColumnName("enchant_id"); + + b.PrimitiveCollection>("Gems") + .HasColumnType("integer[]") + .HasColumnName("gems"); + + b.Property("GuildId") + .HasColumnType("integer") + .HasColumnName("guild_id"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("ItemLevel") + .HasColumnType("smallint") + .HasColumnName("item_level"); + + b.Property>("Modifiers") + .HasColumnType("jsonb") + .HasColumnName("modifiers"); + + b.Property("Quality") + .HasColumnType("smallint") + .HasColumnName("quality"); + + b.Property("Slot") + .HasColumnType("smallint") + .HasColumnName("slot"); + + b.Property("SuffixId") + .HasColumnType("smallint") + .HasColumnName("suffix_id"); + + b.HasKey("Id") + .HasName("pk_player_guild_item"); + + b.HasIndex("GuildId", "ItemId") + .HasDatabaseName("ix_player_guild_item_guild_id_item_id"); + + b.ToTable("player_guild_item", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerWarbankItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BindType") + .HasColumnType("smallint") + .HasColumnName("bind_type"); + + b.PrimitiveCollection>("BonusIds") + .HasColumnType("smallint[]") + .HasColumnName("bonus_ids"); + + b.Property("Bound") + .HasColumnType("boolean") + .HasColumnName("bound"); + + b.Property("ContainerId") + .HasColumnType("smallint") + .HasColumnName("container_id"); + + b.Property("Context") + .HasColumnType("smallint") + .HasColumnName("context"); + + b.Property("Count") + .HasColumnType("integer") + .HasColumnName("count"); + + b.Property("CraftedQuality") + .HasColumnType("smallint") + .HasColumnName("crafted_quality"); + + b.Property("EnchantId") + .HasColumnType("smallint") + .HasColumnName("enchant_id"); + + b.PrimitiveCollection>("Gems") + .HasColumnType("integer[]") + .HasColumnName("gems"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("ItemLevel") + .HasColumnType("smallint") + .HasColumnName("item_level"); + + b.Property>("Modifiers") + .HasColumnType("jsonb") + .HasColumnName("modifiers"); + + b.Property("Quality") + .HasColumnType("smallint") + .HasColumnName("quality"); + + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.Property("Slot") + .HasColumnType("smallint") + .HasColumnName("slot"); + + b.Property("SuffixId") + .HasColumnType("smallint") + .HasColumnName("suffix_id"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_player_warbank_item"); + + b.HasIndex("UserId", "ItemId") + .HasDatabaseName("ix_player_warbank_item_user_id_item_id"); + + b.ToTable("player_warbank_item", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.AccountTransmogQuery", b => + { + b.PrimitiveCollection>("IllusionIds") + .HasColumnType("integer[]") + .HasColumnName("illusion_ids"); + + b.PrimitiveCollection>("TransmogIds") + .HasColumnType("integer[]") + .HasColumnName("transmog_ids"); + + b.ToTable("AccountTransmogQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.AchievementCriteriaQuery", b => + { + b.Property("Amount") + .HasColumnType("bigint") + .HasColumnName("amount"); + + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("CriteriaId") + .HasColumnType("integer") + .HasColumnName("criteria_id"); + + b.ToTable("AchievementCriteriaQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.ActiveConnectedRealmQuery", b => + { + b.Property("ConnectedRealmId") + .HasColumnType("integer") + .HasColumnName("connected_realm_id"); + + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.ToTable("ActiveConnectedRealmQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.AuctionBrowseQuery", b => + { + b.Property("GroupKey") + .HasColumnType("text") + .HasColumnName("group_key"); + + b.Property("LowestBuyoutPrice") + .HasColumnType("bigint") + .HasColumnName("lowest_buyout_price"); + + b.Property("TotalQuantity") + .HasColumnType("bigint") + .HasColumnName("total_quantity"); + + b.ToTable("AuctionBrowseQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.CompletedAchievementsQuery", b => + { + b.Property("AchievementId") + .HasColumnType("integer") + .HasColumnName("achievement_id"); + + b.Property("Timestamp") + .HasColumnType("integer") + .HasColumnName("timestamp"); + + b.ToTable("CompletedAchievementsQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.LatestPlayerAccountGoldSnapshotQuery", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property("Gold") + .HasColumnType("integer") + .HasColumnName("gold"); + + b.Property("RealmId") + .HasColumnType("integer") + .HasColumnName("realm_id"); + + b.ToTable("LatestPlayerAccountGoldSnapshotQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.LatestUserGoldSnapshotQuery", b => + { + b.Property("Gold") + .HasColumnType("integer") + .HasColumnName("gold"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.ToTable("LatestUserGoldSnapshotQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.MountQuery", b => + { + b.PrimitiveCollection>("AddonMounts") + .HasColumnType("integer[]") + .HasColumnName("addon_mounts"); + + b.PrimitiveCollection>("Mounts") + .HasColumnType("integer[]") + .HasColumnName("mounts"); + + b.ToTable("MountQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.PlayerAccountGoldSnapshotQuery", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property("RealmId") + .HasColumnType("integer") + .HasColumnName("realm_id"); + + b.Property("TotalGold") + .HasColumnType("integer") + .HasColumnName("total_gold"); + + b.ToTable("PlayerAccountGoldSnapshotQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.SchedulerCharacterQuery", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("CharacterName") + .HasColumnType("text") + .HasColumnName("character_name"); + + b.Property("LastApiCheck") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_api_check"); + + b.Property("LastApiModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_api_modified"); + + b.Property("RealmSlug") + .HasColumnType("text") + .HasColumnName("realm_slug"); + + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.ToTable("SchedulerCharacterQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.SchedulerUserQuery", b => + { + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.ToTable("SchedulerUserQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.StatisticsQuery", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("Quantity") + .HasColumnType("integer") + .HasColumnName("quantity"); + + b.Property("StatisticId") + .HasColumnType("integer") + .HasColumnName("statistic_id"); + + b.ToTable("StatisticsQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.UserGoldSnapshotQuery", b => + { + b.Property("TotalGold") + .HasColumnType("integer") + .HasColumnName("total_gold"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.ToTable("UserGoldSnapshotQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.UserLeaderboardQuery", b => + { + b.Property("AppearanceIdCount") + .HasColumnType("integer") + .HasColumnName("appearance_id_count"); + + b.Property("AppearanceSourceCount") + .HasColumnType("integer") + .HasColumnName("appearance_source_count"); + + b.Property("CompletedQuestCount") + .HasColumnType("integer") + .HasColumnName("completed_quest_count"); + + b.Property("IllusionCount") + .HasColumnType("smallint") + .HasColumnName("illusion_count"); + + b.Property("MountCount") + .HasColumnType("smallint") + .HasColumnName("mount_count"); + + b.Property("ToyCount") + .HasColumnType("smallint") + .HasColumnName("toy_count"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.ToTable("UserLeaderboardQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.QueuedJob", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Data") + .HasColumnType("text") + .HasColumnName("data"); + + b.Property("DataHash") + .HasColumnType("text") + .HasColumnName("data_hash"); + + b.Property("Failures") + .HasColumnType("smallint") + .HasColumnName("failures"); + + b.Property("Priority") + .HasColumnType("smallint") + .HasColumnName("priority"); + + b.Property("StartedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("started_at"); + + b.Property("Type") + .HasColumnType("smallint") + .HasColumnName("type"); + + b.HasKey("Id") + .HasName("pk_queued_job"); + + b.HasIndex("Priority") + .HasDatabaseName("ix_queued_job_priority") + .HasFilter("started_at IS NULL"); + + b.HasIndex("Priority", "Type", "DataHash") + .IsUnique() + .HasDatabaseName("ix_queued_job_priority_type_data_hash"); + + b.ToTable("queued_job", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Team.Team", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DefaultRealmId") + .HasColumnType("integer") + .HasColumnName("default_realm_id"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("guid"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.Property("Slug") + .HasColumnType("text") + .HasColumnName("slug"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_team"); + + b.HasIndex("Guid") + .IsUnique() + .HasDatabaseName("ix_team_guid"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_team_user_id"); + + b.ToTable("team", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Team.TeamCharacter", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("Note") + .HasColumnType("text") + .HasColumnName("note"); + + b.Property("PrimaryRole") + .HasColumnType("smallint") + .HasColumnName("primary_role"); + + b.Property("SecondaryRole") + .HasColumnType("smallint") + .HasColumnName("secondary_role"); + + b.Property("TeamId") + .HasColumnType("integer") + .HasColumnName("team_id"); + + b.HasKey("Id") + .HasName("pk_team_character"); + + b.HasIndex("CharacterId") + .HasDatabaseName("ix_team_character_character_id"); + + b.HasIndex("TeamId") + .HasDatabaseName("ix_team_character_team_id"); + + b.ToTable("team_character", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserAddonData", b => + { + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.Property("WarbankCopper") + .HasColumnType("bigint") + .HasColumnName("warbank_copper"); + + b.Property("WarbankGoldUpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("warbank_gold_updated_at"); + + b.Property("WarbankUpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("warbank_updated_at"); + + b.HasKey("UserId") + .HasName("pk_user_addon_data"); + + b.ToTable("user_addon_data", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserBulkData", b => + { + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.Property>("Heirlooms") + .HasColumnType("jsonb") + .HasColumnName("heirlooms"); + + b.Property("HeirloomsUpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("heirlooms_updated_at"); + + b.PrimitiveCollection>("MountIds") + .HasColumnType("smallint[]") + .HasColumnName("mount_ids"); + + b.Property("MountsUpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("mounts_updated_at"); + + b.Property>("Pets") + .HasColumnType("jsonb") + .HasColumnName("pets"); + + b.Property("PetsUpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("pets_updated_at"); + + b.PrimitiveCollection>("ToyIds") + .HasColumnType("smallint[]") + .HasColumnName("toy_ids"); + + b.Property("ToysUpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("toys_updated_at"); + + b.PrimitiveCollection>("TransmogIds") + .HasColumnType("integer[]") + .HasColumnName("transmog_ids"); + + b.Property("TransmogsUpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("transmogs_updated_at"); + + b.HasKey("UserId") + .HasName("pk_user_bulk_data"); + + b.ToTable("user_bulk_data", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserCache", b => + { + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.PrimitiveCollection>("AppearanceIds") + .HasColumnType("integer[]") + .HasColumnName("appearance_ids"); + + b.PrimitiveCollection>("AppearanceSources") + .HasColumnType("text[]") + .HasColumnName("appearance_sources"); + + b.Property("CompletedQuests") + .HasColumnType("integer") + .HasColumnName("completed_quests"); + + b.PrimitiveCollection>("IllusionIds") + .HasColumnType("smallint[]") + .HasColumnName("illusion_ids"); + + b.PrimitiveCollection>("MountIds") + .HasColumnType("smallint[]") + .HasColumnName("mount_ids"); + + b.Property("MountsUpdated") + .HasColumnType("timestamp with time zone") + .HasColumnName("mounts_updated"); + + b.PrimitiveCollection>("ToyIds") + .HasColumnType("smallint[]") + .HasColumnName("toy_ids"); + + b.Property("ToysUpdated") + .HasColumnType("timestamp with time zone") + .HasColumnName("toys_updated"); + + b.Property("TransmogUpdated") + .HasColumnType("timestamp with time zone") + .HasColumnName("transmog_updated"); + + b.HasKey("UserId") + .HasName("pk_user_cache"); + + b.ToTable("user_cache", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserGoldSnapshot", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Gold") + .HasColumnType("integer") + .HasColumnName("gold"); + + b.Property("Time") + .HasColumnType("timestamp with time zone") + .HasColumnName("time"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_user_gold_snapshot"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_user_gold_snapshot_user_id"); + + b.ToTable("user_gold_snapshot", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserLeaderboardSnapshot", b => + { + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.Property("Date") + .HasColumnType("date") + .HasColumnName("date"); + + b.Property("AchievementPointsAlliance") + .HasColumnType("integer") + .HasColumnName("achievement_points_alliance"); + + b.Property("AchievementPointsHorde") + .HasColumnType("integer") + .HasColumnName("achievement_points_horde"); + + b.Property("AchievementPointsOverall") + .HasColumnType("integer") + .HasColumnName("achievement_points_overall"); + + b.Property("AppearanceIdCount") + .HasColumnType("integer") + .HasColumnName("appearance_id_count"); + + b.Property("AppearanceSourceCount") + .HasColumnType("integer") + .HasColumnName("appearance_source_count"); + + b.Property("CompletedQuestCount") + .HasColumnType("integer") + .HasColumnName("completed_quest_count"); + + b.Property("HeirloomCount") + .HasColumnType("smallint") + .HasColumnName("heirloom_count"); + + b.Property("HeirloomLevels") + .HasColumnType("smallint") + .HasColumnName("heirloom_levels"); + + b.Property("IllusionCount") + .HasColumnType("smallint") + .HasColumnName("illusion_count"); + + b.Property("MountCount") + .HasColumnType("smallint") + .HasColumnName("mount_count"); + + b.Property("PetCount") + .HasColumnType("smallint") + .HasColumnName("pet_count"); + + b.Property("RecipeCount") + .HasColumnType("smallint") + .HasColumnName("recipe_count"); + + b.Property("ReputationCount") + .HasColumnType("smallint") + .HasColumnName("reputation_count"); + + b.Property("TitleCount") + .HasColumnType("smallint") + .HasColumnName("title_count"); + + b.Property("ToyCount") + .HasColumnType("smallint") + .HasColumnName("toy_count"); + + b.HasKey("UserId", "Date") + .HasName("pk_user_leaderboard_snapshot"); + + b.HasIndex("UserId", "Date") + .IsDescending(false, true) + .HasDatabaseName("ix_user_leaderboard_snapshot_user_id_date"); + + b.ToTable("user_leaderboard_snapshot", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.WorldQuestAggregate", b => + { + b.Property("Region") + .HasColumnType("smallint") + .HasColumnName("region"); + + b.Property("ZoneId") + .HasColumnType("integer") + .HasColumnName("zone_id"); + + b.Property("QuestId") + .HasColumnType("integer") + .HasColumnName("quest_id"); + + b.Property("JsonData") + .HasColumnType("text") + .HasColumnName("json_data"); + + b.HasKey("Region", "ZoneId", "QuestId") + .HasName("pk_world_quest_aggregate"); + + b.ToTable("world_quest_aggregate", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.WorldQuestReport", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Class") + .HasColumnType("smallint") + .HasColumnName("class"); + + b.Property("Expansion") + .HasColumnType("smallint") + .HasColumnName("expansion"); + + b.Property("ExpiresAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("expires_at"); + + b.Property("Faction") + .HasColumnType("smallint") + .HasColumnName("faction"); + + b.Property("Location") + .HasColumnType("text") + .HasColumnName("location"); + + b.Property("QuestId") + .HasColumnType("integer") + .HasColumnName("quest_id"); + + b.Property("Region") + .HasColumnType("smallint") + .HasColumnName("region"); + + b.Property("ReportedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("reported_at"); + + b.Property>("Rewards") + .HasColumnType("jsonb") + .HasColumnName("rewards"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.Property("ZoneId") + .HasColumnType("integer") + .HasColumnName("zone_id"); + + b.HasKey("Id") + .HasName("pk_world_quest_report"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_world_quest_report_user_id"); + + b.HasIndex("Region", "ExpiresAt") + .IsDescending(false, true) + .HasDatabaseName("ix_world_quest_report_region_expires_at"); + + b.ToTable("world_quest_report", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowAuction", b => + { + b.Property("ConnectedRealmId") + .HasColumnType("integer") + .HasColumnName("connected_realm_id"); + + b.Property("AuctionId") + .HasColumnType("integer") + .HasColumnName("auction_id"); + + b.Property("AppearanceId") + .HasColumnType("integer") + .HasColumnName("appearance_id"); + + b.Property("AppearanceSource") + .HasColumnType("text") + .HasColumnName("appearance_source"); + + b.Property("BidPrice") + .HasColumnType("bigint") + .HasColumnName("bid_price"); + + b.PrimitiveCollection>("BonusIds") + .HasColumnType("integer[]") + .HasColumnName("bonus_ids"); + + b.Property("BuyoutPrice") + .HasColumnType("bigint") + .HasColumnName("buyout_price"); + + b.Property("Context") + .HasColumnType("smallint") + .HasColumnName("context"); + + b.Property("GroupKey") + .HasColumnType("text") + .HasColumnName("group_key"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.PrimitiveCollection>("ModifierTypes") + .HasColumnType("smallint[]") + .HasColumnName("modifier_types"); + + b.PrimitiveCollection>("ModifierValues") + .HasColumnType("integer[]") + .HasColumnName("modifier_values"); + + b.Property("PetBreedId") + .HasColumnType("smallint") + .HasColumnName("pet_breed_id"); + + b.Property("PetLevel") + .HasColumnType("smallint") + .HasColumnName("pet_level"); + + b.Property("PetQuality") + .HasColumnType("smallint") + .HasColumnName("pet_quality"); + + b.Property("PetSpeciesId") + .HasColumnType("smallint") + .HasColumnName("pet_species_id"); + + b.Property("Quantity") + .HasColumnType("integer") + .HasColumnName("quantity"); + + b.Property("TimeLeft") + .HasColumnType("smallint") + .HasColumnName("time_left"); + + b.HasKey("ConnectedRealmId", "AuctionId") + .HasName("pk_wow_auction"); + + b.HasIndex("ItemId") + .HasDatabaseName("ix_wow_auction_item_id"); + + b.HasIndex("PetSpeciesId") + .HasDatabaseName("ix_wow_auction_pet_species_id"); + + b.HasIndex("AppearanceId", "BuyoutPrice") + .HasDatabaseName("ix_wow_auction_appearance_id_buyout_price") + .HasFilter("appearance_id IS NOT NULL"); + + b.HasIndex("AppearanceSource", "BuyoutPrice") + .HasDatabaseName("ix_wow_auction_appearance_source_buyout_price") + .HasFilter("appearance_source IS NOT NULL"); + + b.ToTable("wow_auction", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowAuctionCheapestByAppearanceId", b => + { + b.Property("ConnectedRealmId") + .HasColumnType("integer") + .HasColumnName("connected_realm_id"); + + b.Property("AppearanceId") + .HasColumnType("integer") + .HasColumnName("appearance_id"); + + b.Property("AuctionId") + .HasColumnType("integer") + .HasColumnName("auction_id"); + + b.HasKey("ConnectedRealmId", "AppearanceId") + .HasName("pk_wow_auction_cheapest_by_appearance_id"); + + b.ToTable("wow_auction_cheapest_by_appearance_id", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowAuctionCheapestByAppearanceSource", b => + { + b.Property("ConnectedRealmId") + .HasColumnType("integer") + .HasColumnName("connected_realm_id"); + + b.Property("AppearanceSource") + .HasColumnType("text") + .HasColumnName("appearance_source"); + + b.Property("AuctionId") + .HasColumnType("integer") + .HasColumnName("auction_id"); + + b.HasKey("ConnectedRealmId", "AppearanceSource") + .HasName("pk_wow_auction_cheapest_by_appearance_source"); + + b.ToTable("wow_auction_cheapest_by_appearance_source", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowAuctionCommodityDaily", b => + { + b.Property("Region") + .HasColumnType("smallint") + .HasColumnName("region"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("Date") + .HasColumnType("date") + .HasColumnName("date"); + + b.PrimitiveCollection>("AvgData") + .HasColumnType("integer[]") + .HasColumnName("avg_data"); + + b.Property("ListedMax") + .HasColumnType("integer") + .HasColumnName("listed_max"); + + b.Property("ListedMin") + .HasColumnType("integer") + .HasColumnName("listed_min"); + + b.PrimitiveCollection>("MaxData") + .HasColumnType("integer[]") + .HasColumnName("max_data"); + + b.PrimitiveCollection>("MinData") + .HasColumnType("integer[]") + .HasColumnName("min_data"); + + b.HasKey("Region", "ItemId", "Date") + .HasName("pk_wow_auction_commodity_daily"); + + b.ToTable("wow_auction_commodity_daily", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowAuctionCommodityHourly", b => + { + b.Property("Region") + .HasColumnType("smallint") + .HasColumnName("region"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone") + .HasColumnName("timestamp"); + + b.PrimitiveCollection>("Data") + .HasColumnType("integer[]") + .HasColumnName("data"); + + b.Property("Listed") + .HasColumnType("integer") + .HasColumnName("listed"); + + b.HasKey("Region", "ItemId", "Timestamp") + .HasName("pk_wow_auction_commodity_hourly"); + + b.ToTable("wow_auction_commodity_hourly", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowCampaign", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.PrimitiveCollection>("QuestLineIds") + .HasColumnType("integer[]") + .HasColumnName("quest_line_ids"); + + b.HasKey("Id") + .HasName("pk_wow_campaign"); + + b.ToTable("wow_campaign", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowChallengeDungeon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Expansion") + .HasColumnType("smallint") + .HasColumnName("expansion"); + + b.Property("MapId") + .HasColumnType("smallint") + .HasColumnName("map_id"); + + b.PrimitiveCollection>("TimerBreakpoints") + .HasColumnType("smallint[]") + .HasColumnName("timer_breakpoints"); + + b.HasKey("Id") + .HasName("pk_wow_challenge_dungeon"); + + b.ToTable("wow_challenge_dungeon", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowCharacterClass", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ArmorMask") + .HasColumnType("smallint") + .HasColumnName("armor_mask"); + + b.Property("RolesMask") + .HasColumnType("smallint") + .HasColumnName("roles_mask"); + + b.Property("Slug") + .HasColumnType("text") + .HasColumnName("slug"); + + b.HasKey("Id") + .HasName("pk_wow_character_class"); + + b.ToTable("wow_character_class", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowCharacterRace", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Bit") + .HasColumnType("smallint") + .HasColumnName("bit"); + + b.Property("Faction") + .HasColumnType("smallint") + .HasColumnName("faction"); + + b.HasKey("Id") + .HasName("pk_wow_character_race"); + + b.ToTable("wow_character_race", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowCharacterSpecialization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClassId") + .HasColumnType("smallint") + .HasColumnName("class_id"); + + b.Property("Order") + .HasColumnType("smallint") + .HasColumnName("order"); + + b.Property("PrimaryStat") + .HasColumnType("smallint") + .HasColumnName("primary_stat"); + + b.Property("Role") + .HasColumnType("smallint") + .HasColumnName("role"); + + b.HasKey("Id") + .HasName("pk_wow_character_specialization"); + + b.ToTable("wow_character_specialization", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowCurrency", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CategoryId") + .HasColumnType("smallint") + .HasColumnName("category_id"); + + b.Property("Flags") + .HasColumnType("smallint") + .HasColumnName("flags"); + + b.Property("MaxPerWeek") + .HasColumnType("integer") + .HasColumnName("max_per_week"); + + b.Property("MaxTotal") + .HasColumnType("integer") + .HasColumnName("max_total"); + + b.Property("RechargeAmount") + .HasColumnType("smallint") + .HasColumnName("recharge_amount"); + + b.Property("RechargeInterval") + .HasColumnType("bigint") + .HasColumnName("recharge_interval"); + + b.Property("TransferPercent") + .HasColumnType("smallint") + .HasColumnName("transfer_percent"); + + b.HasKey("Id") + .HasName("pk_wow_currency"); + + b.ToTable("wow_currency", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowCurrencyCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Expansion") + .HasColumnType("smallint") + .HasColumnName("expansion"); + + b.Property("Flags") + .HasColumnType("smallint") + .HasColumnName("flags"); + + b.HasKey("Id") + .HasName("pk_wow_currency_category"); + + b.ToTable("wow_currency_category", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowDecor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("Type") + .HasColumnType("smallint") + .HasColumnName("type"); + + b.HasKey("Id") + .HasName("pk_wow_decor"); + + b.ToTable("wow_decor", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowHoliday", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DescriptionId") + .HasColumnType("smallint") + .HasColumnName("description_id"); + + b.PrimitiveCollection>("Durations") + .HasColumnType("smallint[]") + .HasColumnName("durations"); + + b.Property("FilterType") + .HasColumnType("smallint") + .HasColumnName("filter_type"); + + b.Property("Flags") + .HasColumnType("smallint") + .HasColumnName("flags"); + + b.Property("Looping") + .HasColumnType("smallint") + .HasColumnName("looping"); + + b.Property("NameId") + .HasColumnType("smallint") + .HasColumnName("name_id"); + + b.Property("Priority") + .HasColumnType("smallint") + .HasColumnName("priority"); + + b.Property("Region") + .HasColumnType("smallint") + .HasColumnName("region"); + + b.PrimitiveCollection>("StartDates") + .HasColumnType("timestamp with time zone[]") + .HasColumnName("start_dates"); + + b.HasKey("Id") + .HasName("pk_wow_holiday"); + + b.ToTable("wow_holiday", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BindType") + .HasColumnType("smallint") + .HasColumnName("bind_type"); + + b.Property("ClassId") + .HasColumnType("smallint") + .HasColumnName("class_id"); + + b.Property("ClassMask") + .HasColumnType("integer") + .HasColumnName("class_mask"); + + b.PrimitiveCollection("CompletesQuestIds") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("integer[]") + .HasDefaultValue(new int[0]) + .HasColumnName("completes_quest_ids"); + + b.Property("ContainerSlots") + .HasColumnType("smallint") + .HasColumnName("container_slots"); + + b.Property("CraftingQuality") + .HasColumnType("smallint") + .HasColumnName("crafting_quality"); + + b.Property("Expansion") + .HasColumnType("smallint") + .HasColumnName("expansion"); + + b.Property("Flags") + .HasColumnType("smallint") + .HasColumnName("flags"); + + b.Property("InventoryType") + .HasColumnType("smallint") + .HasColumnName("inventory_type"); + + b.Property("ItemLevel") + .HasColumnType("smallint") + .HasColumnName("item_level"); + + b.Property("LimitCategory") + .HasColumnType("smallint") + .HasColumnName("limit_category"); + + b.Property("OppositeFactionId") + .HasColumnType("integer") + .HasColumnName("opposite_faction_id"); + + b.Property("PrimaryStat") + .HasColumnType("smallint") + .HasColumnName("primary_stat"); + + b.Property("Quality") + .HasColumnType("smallint") + .HasColumnName("quality"); + + b.Property("RaceMask") + .HasColumnType("bigint") + .HasColumnName("race_mask"); + + b.Property("RequiredAbility") + .HasColumnType("integer") + .HasColumnName("required_ability"); + + b.Property("RequiredLevel") + .HasColumnType("smallint") + .HasColumnName("required_level"); + + b.Property("RequiredSkill") + .HasColumnType("smallint") + .HasColumnName("required_skill"); + + b.Property("RequiredSkillRank") + .HasColumnType("smallint") + .HasColumnName("required_skill_rank"); + + b.PrimitiveCollection("Sockets") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("smallint[]") + .HasDefaultValue(new short[0]) + .HasColumnName("sockets"); + + b.Property("Stackable") + .HasColumnType("integer") + .HasColumnName("stackable"); + + b.Property("SubclassId") + .HasColumnType("smallint") + .HasColumnName("subclass_id"); + + b.PrimitiveCollection("TeachesDecorIds") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("integer[]") + .HasDefaultValue(new int[0]) + .HasColumnName("teaches_decor_ids"); + + b.PrimitiveCollection("TeachesSpellIds") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("integer[]") + .HasDefaultValue(new int[0]) + .HasColumnName("teaches_spell_ids"); + + b.PrimitiveCollection("TeachesTransmogIllusionIds") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("integer[]") + .HasDefaultValue(new int[0]) + .HasColumnName("teaches_transmog_illusion_ids"); + + b.PrimitiveCollection("TeachesTransmogSetIds") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("integer[]") + .HasDefaultValue(new int[0]) + .HasColumnName("teaches_transmog_set_ids"); + + b.Property("Unique") + .HasColumnType("smallint") + .HasColumnName("unique"); + + b.HasKey("Id") + .HasName("pk_wow_item"); + + b.ToTable("wow_item", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowItemBonus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BonusTypeFlags") + .HasColumnType("bigint") + .HasColumnName("bonus_type_flags"); + + b.Property>>("Bonuses") + .HasColumnType("jsonb") + .HasColumnName("bonuses"); + + b.HasKey("Id") + .HasName("pk_wow_item_bonus"); + + b.ToTable("wow_item_bonus", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowItemClass", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClassId") + .HasColumnType("smallint") + .HasColumnName("class_id"); + + b.HasKey("Id") + .HasName("pk_wow_item_class"); + + b.ToTable("wow_item_class", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowItemEffect", b => + { + b.Property("ItemXItemEffectId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("item_x_item_effect_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ItemXItemEffectId")); + + b.Property("Effect") + .HasColumnType("integer") + .HasColumnName("effect"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.PrimitiveCollection("Values") + .HasColumnType("integer[]") + .HasColumnName("values"); + + b.HasKey("ItemXItemEffectId") + .HasName("pk_wow_item_effect"); + + b.ToTable("wow_item_effect", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowItemEffectV2", b => + { + b.Property("ItemId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("item_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ItemId")); + + b.PrimitiveCollection>("ItemEffectIds") + .HasColumnType("integer[]") + .HasColumnName("item_effect_ids"); + + b.Property>>("SpellEffects") + .HasColumnType("jsonb") + .HasColumnName("spell_effects"); + + b.HasKey("ItemId") + .HasName("pk_wow_item_effect_v2"); + + b.ToTable("wow_item_effect_v2", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowItemModifiedAppearance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AppearanceId") + .HasColumnType("integer") + .HasColumnName("appearance_id"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("Modifier") + .HasColumnType("smallint") + .HasColumnName("modifier"); + + b.Property("Order") + .HasColumnType("smallint") + .HasColumnName("order"); + + b.Property("SourceType") + .HasColumnType("smallint") + .HasColumnName("source_type"); + + b.HasKey("Id") + .HasName("pk_wow_item_modified_appearance"); + + b.ToTable("wow_item_modified_appearance", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowItemSubclass", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AuctionHouseSortOrder") + .HasColumnType("smallint") + .HasColumnName("auction_house_sort_order"); + + b.Property("ClassId") + .HasColumnType("smallint") + .HasColumnName("class_id"); + + b.Property("SubclassId") + .HasColumnType("smallint") + .HasColumnName("subclass_id"); + + b.HasKey("Id") + .HasName("pk_wow_item_subclass"); + + b.ToTable("wow_item_subclass", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowJournalInstance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Flags") + .HasColumnType("integer") + .HasColumnName("flags"); + + b.Property("MapId") + .HasColumnType("smallint") + .HasColumnName("map_id"); + + b.HasKey("Id") + .HasName("pk_wow_journal_instance"); + + b.ToTable("wow_journal_instance", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowMount", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Flags") + .HasColumnType("integer") + .HasColumnName("flags"); + + b.PrimitiveCollection>("ItemIds") + .HasColumnType("integer[]") + .HasColumnName("item_ids"); + + b.Property("SourceType") + .HasColumnType("smallint") + .HasColumnName("source_type"); + + b.Property("SpellId") + .HasColumnType("integer") + .HasColumnName("spell_id"); + + b.HasKey("Id") + .HasName("pk_wow_mount"); + + b.ToTable("wow_mount", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowMythicPlusSeason", b => + { + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.HasKey("Region", "Id") + .HasName("pk_wow_mythic_plus_season"); + + b.ToTable("wow_mythic_plus_season", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowPeriod", b => + { + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Ends") + .HasColumnType("timestamp with time zone") + .HasColumnName("ends"); + + b.Property("Starts") + .HasColumnType("timestamp with time zone") + .HasColumnName("starts"); + + b.HasKey("Region", "Id") + .HasName("pk_wow_period"); + + b.ToTable("wow_period", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowPet", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatureId") + .HasColumnType("integer") + .HasColumnName("creature_id"); + + b.Property("Flags") + .HasColumnType("integer") + .HasColumnName("flags"); + + b.PrimitiveCollection>("ItemIds") + .HasColumnType("integer[]") + .HasColumnName("item_ids"); + + b.Property("PetType") + .HasColumnType("smallint") + .HasColumnName("pet_type"); + + b.Property("SourceType") + .HasColumnType("smallint") + .HasColumnName("source_type"); + + b.Property("SpellId") + .HasColumnType("integer") + .HasColumnName("spell_id"); + + b.HasKey("Id") + .HasName("pk_wow_pet"); + + b.ToTable("wow_pet", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowProfessionRecipeItem", b => + { + b.Property("SkillLineAbilityId") + .HasColumnType("integer") + .HasColumnName("skill_line_ability_id"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("SkillLineId") + .HasColumnType("integer") + .HasColumnName("skill_line_id"); + + b.HasKey("SkillLineAbilityId", "ItemId") + .HasName("pk_wow_profession_recipe_item"); + + b.ToTable("wow_profession_recipe_item", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowQuest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AreaId") + .HasColumnType("integer") + .HasColumnName("area_id"); + + b.Property("CategoryId") + .HasColumnType("integer") + .HasColumnName("category_id"); + + b.Property("LastApiCheck") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_api_check"); + + b.Property("MaximumLevel") + .HasColumnType("smallint") + .HasColumnName("maximum_level"); + + b.Property("MinimumLevel") + .HasColumnType("smallint") + .HasColumnName("minimum_level"); + + b.HasKey("Id") + .HasName("pk_wow_quest"); + + b.ToTable("wow_quest", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowQuestLine", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.PrimitiveCollection>("QuestIds") + .HasColumnType("integer[]") + .HasColumnName("quest_ids"); + + b.HasKey("Id") + .HasName("pk_wow_quest_line"); + + b.ToTable("wow_quest_line", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowRealm", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("ConnectedRealmId") + .HasColumnType("integer") + .HasColumnName("connected_realm_id"); + + b.Property("EnglishName") + .HasColumnType("text") + .HasColumnName("english_name"); + + b.Property("Locale") + .HasColumnType("text") + .HasColumnName("locale"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.Property("Slug") + .HasColumnType("text") + .HasColumnName("slug"); + + b.HasKey("Id") + .HasName("pk_wow_realm"); + + b.ToTable("wow_realm", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowReputation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountWide") + .HasColumnType("boolean") + .HasColumnName("account_wide"); + + b.PrimitiveCollection>("BaseValues") + .HasColumnType("integer[]") + .HasColumnName("base_values"); + + b.Property("Expansion") + .HasColumnType("smallint") + .HasColumnName("expansion"); + + b.PrimitiveCollection>("MaxValues") + .HasColumnType("integer[]") + .HasColumnName("max_values"); + + b.Property("ParagonId") + .HasColumnType("smallint") + .HasColumnName("paragon_id"); + + b.Property("ParagonQuestId") + .HasColumnType("integer") + .HasColumnName("paragon_quest_id"); + + b.Property("ParagonThreshold") + .HasColumnType("integer") + .HasColumnName("paragon_threshold"); + + b.Property("ParentId") + .HasColumnType("smallint") + .HasColumnName("parent_id"); + + b.Property("RenownCurrencyId") + .HasColumnType("smallint") + .HasColumnName("renown_currency_id"); + + b.Property("TierId") + .HasColumnType("smallint") + .HasColumnName("tier_id"); + + b.HasKey("Id") + .HasName("pk_wow_reputation"); + + b.ToTable("wow_reputation", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowReputationTier", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.PrimitiveCollection("MinValues") + .HasColumnType("integer[]") + .HasColumnName("min_values"); + + b.HasKey("Id") + .HasName("pk_wow_reputation_tier"); + + b.ToTable("wow_reputation_tier", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowToy", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Flags") + .HasColumnType("integer") + .HasColumnName("flags"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("SourceType") + .HasColumnType("smallint") + .HasColumnName("source_type"); + + b.HasKey("Id") + .HasName("pk_wow_toy"); + + b.ToTable("wow_toy", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowTransmogSet", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClassMask") + .HasColumnType("integer") + .HasColumnName("class_mask"); + + b.Property("Flags") + .HasColumnType("smallint") + .HasColumnName("flags"); + + b.Property("GroupId") + .HasColumnType("smallint") + .HasColumnName("group_id"); + + b.PrimitiveCollection>("ItemModifiedAppearanceIds") + .HasColumnType("integer[]") + .HasColumnName("item_modified_appearance_ids"); + + b.Property("ItemNameDescriptionId") + .HasColumnType("integer") + .HasColumnName("item_name_description_id"); + + b.HasKey("Id") + .HasName("pk_wow_transmog_set"); + + b.ToTable("wow_transmog_set", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowWorldQuest", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Expansion") + .HasColumnType("smallint") + .HasColumnName("expansion"); + + b.Property("Faction") + .HasColumnType("smallint") + .HasColumnName("faction"); + + b.Property("MaxLevel") + .HasColumnType("smallint") + .HasColumnName("max_level"); + + b.Property("MinLevel") + .HasColumnType("smallint") + .HasColumnName("min_level"); + + b.PrimitiveCollection>("NeedQuestIds") + .HasColumnType("integer[]") + .HasColumnName("need_quest_ids"); + + b.Property("QuestInfoId") + .HasColumnType("smallint") + .HasColumnName("quest_info_id"); + + b.PrimitiveCollection>("SkipQuestIds") + .HasColumnType("integer[]") + .HasColumnName("skip_quest_ids"); + + b.HasKey("Id") + .HasName("pk_wow_world_quest"); + + b.ToTable("wow_world_quest", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_asp_net_role_claims_asp_net_roles_role_id"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_asp_net_user_claims_asp_net_users_user_id"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_asp_net_user_logins_asp_net_users_user_id"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_asp_net_user_roles_asp_net_roles_role_id"); + + b.HasOne("Wowthing.Lib.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_asp_net_user_roles_asp_net_users_user_id"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_asp_net_user_tokens_asp_net_users_user_id"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.BackgroundImage", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", "Role") + .WithMany() + .HasForeignKey("RoleId") + .HasConstraintName("fk_background_image_roles_role_id"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.MiscReport", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_misc_report_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccount", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .HasConstraintName("fk_player_account_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountAddonData", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("AddonData") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountAddonData", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_addon_data_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountGoldSnapshot", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithMany() + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_gold_snapshot_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountHeirlooms", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("Heirlooms") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountHeirlooms", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_heirlooms_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountMounts", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("Mounts") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountMounts", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_mounts_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountPets", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("Pets") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountPets", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_pets_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountToys", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("Toys") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountToys", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_toys_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountTransmogIds", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("TransmogIds") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountTransmogIds", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_transmog_ids_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountTransmogSources", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("TransmogSources") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountTransmogSources", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_transmog_sources_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacter", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithMany("Characters") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("fk_player_character_player_account_account_id"); + + b.HasOne("Wowthing.Lib.Models.Player.PlayerGuild", "Guild") + .WithMany() + .HasForeignKey("GuildId") + .HasConstraintName("fk_player_character_player_guild_guild_id"); + + b.Navigation("Account"); + + b.Navigation("Guild"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAchievements", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Achievements") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterAchievements", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_achievements_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonAchievements", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("AddonAchievements") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterAddonAchievements", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_addon_achievements_player_character_charac"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonData", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("AddonData") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterAddonData", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_addon_data_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonMounts", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("AddonMounts") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterAddonMounts", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_addon_mounts_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonQuests", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("AddonQuests") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterAddonQuests", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_addon_quests_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterConfiguration", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Configuration") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterConfiguration", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_configuration_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterEquippedItems", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("EquippedItems") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterEquippedItems", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_equipped_items_player_character_character_"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterItem", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithMany("Items") + .HasForeignKey("CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_item_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterLockouts", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Lockouts") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterLockouts", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_lockouts_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMedia", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Media") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterMedia", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_media_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMounts", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Mounts") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterMounts", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_mounts_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlus", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("MythicPlus") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlus", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_mythic_plus_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlusAddon", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("MythicPlusAddon") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlusAddon", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_mythic_plus_addon_player_character_charact"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlusSeason", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithMany("MythicPlusSeasons") + .HasForeignKey("CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_mythic_plus_season_player_character_charac"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterProfessions", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Professions") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterProfessions", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_professions_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterQuests", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Quests") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterQuests", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_quests_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterRaiderIo", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("RaiderIo") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterRaiderIo", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_raider_io_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterReputations", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Reputations") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterReputations", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_reputations_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterShadowlands", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Shadowlands") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterShadowlands", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_shadowlands_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterSpecializations", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Specializations") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterSpecializations", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_specializations_player_character_character"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterStatistics", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithMany() + .HasForeignKey("CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_statistics_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterStats", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Stats") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterStats", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_stats_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterTransmog", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Transmog") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterTransmog", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_transmog_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterWeekly", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Weekly") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterWeekly", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_weekly_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerGuild", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_guild_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerGuildItem", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerGuild", "Guild") + .WithMany("Items") + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_guild_item_player_guild_guild_id"); + + b.Navigation("Guild"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerWarbankItem", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_warbank_item_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Team.Team", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_team_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Team.TeamCharacter", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithMany() + .HasForeignKey("CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_team_character_player_character_character_id"); + + b.HasOne("Wowthing.Lib.Models.Team.Team", "Team") + .WithMany("Characters") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_team_character_team_team_id"); + + b.Navigation("Character"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserAddonData", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_addon_data_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserBulkData", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_bulk_data_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserCache", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_cache_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserGoldSnapshot", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .HasConstraintName("fk_user_gold_snapshot_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserLeaderboardSnapshot", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_leaderboard_snapshot_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.WorldQuestReport", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_world_quest_report_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccount", b => + { + b.Navigation("AddonData"); + + b.Navigation("Characters"); + + b.Navigation("Heirlooms"); + + b.Navigation("Mounts"); + + b.Navigation("Pets"); + + b.Navigation("Toys"); + + b.Navigation("TransmogIds"); + + b.Navigation("TransmogSources"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacter", b => + { + b.Navigation("Achievements"); + + b.Navigation("AddonAchievements"); + + b.Navigation("AddonData"); + + b.Navigation("AddonMounts"); + + b.Navigation("AddonQuests"); + + b.Navigation("Configuration"); + + b.Navigation("EquippedItems"); + + b.Navigation("Items"); + + b.Navigation("Lockouts"); + + b.Navigation("Media"); + + b.Navigation("Mounts"); + + b.Navigation("MythicPlus"); + + b.Navigation("MythicPlusAddon"); + + b.Navigation("MythicPlusSeasons"); + + b.Navigation("Professions"); + + b.Navigation("Quests"); + + b.Navigation("RaiderIo"); + + b.Navigation("Reputations"); + + b.Navigation("Shadowlands"); + + b.Navigation("Specializations"); + + b.Navigation("Stats"); + + b.Navigation("Transmog"); + + b.Navigation("Weekly"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerGuild", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Team.Team", b => + { + b.Navigation("Characters"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/packages/csharp-lib/Migrations/20260704181432_More_PlayerCharacterQuests_Things.cs b/packages/csharp-lib/Migrations/20260704181432_More_PlayerCharacterQuests_Things.cs new file mode 100644 index 000000000..489d37341 --- /dev/null +++ b/packages/csharp-lib/Migrations/20260704181432_More_PlayerCharacterQuests_Things.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Wowthing.Lib.Migrations +{ + /// + public partial class More_PlayerCharacterQuests_Things : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "daily_quests", + table: "player_character_addon_quests"); + + migrationBuilder.DropColumn( + name: "other_quests", + table: "player_character_addon_quests"); + + migrationBuilder.AddColumn( + name: "scanned_at", + table: "player_character_quests", + type: "timestamp with time zone", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AddColumn( + name: "compressed_completed_ids", + table: "player_character_addon_quests", + type: "bytea", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "scanned_at", + table: "player_character_quests"); + + migrationBuilder.DropColumn( + name: "compressed_completed_ids", + table: "player_character_addon_quests"); + + migrationBuilder.AddColumn>( + name: "daily_quests", + table: "player_character_addon_quests", + type: "integer[]", + nullable: true); + + migrationBuilder.AddColumn>( + name: "other_quests", + table: "player_character_addon_quests", + type: "integer[]", + nullable: true); + } + } +} diff --git a/packages/csharp-lib/Migrations/WowDbContextModelSnapshot.cs b/packages/csharp-lib/Migrations/WowDbContextModelSnapshot.cs index 21bca6266..839e6437b 100644 --- a/packages/csharp-lib/Migrations/WowDbContextModelSnapshot.cs +++ b/packages/csharp-lib/Migrations/WowDbContextModelSnapshot.cs @@ -1122,22 +1122,18 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("timestamp with time zone") .HasColumnName("completed_quests_scanned_at"); + b.Property("CompressedCompletedIds") + .HasColumnType("bytea") + .HasColumnName("compressed_completed_ids"); + b.Property>>>("Dailies") .HasColumnType("jsonb") .HasColumnName("dailies"); - b.PrimitiveCollection>("DailyQuests") - .HasColumnType("integer[]") - .HasColumnName("daily_quests"); - b.Property>>("GoldWorldQuests") .HasColumnType("jsonb") .HasColumnName("gold_world_quests"); - b.PrimitiveCollection>("OtherQuests") - .HasColumnType("integer[]") - .HasColumnName("other_quests"); - b.Property>("ProgressQuests") .HasColumnType("jsonb") .HasColumnName("progress_quests"); @@ -1443,6 +1439,14 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("integer[]") .HasColumnName("completed_ids"); + b.Property("CompressedCompletedIds") + .HasColumnType("bytea") + .HasColumnName("compressed_completed_ids"); + + b.Property("ScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("scanned_at"); + b.HasKey("CharacterId") .HasName("pk_player_character_quests"); diff --git a/packages/csharp-lib/Models/API/ApiUserQuests.cs b/packages/csharp-lib/Models/API/ApiUserQuests.cs index 93df9a41b..4949b8899 100644 --- a/packages/csharp-lib/Models/API/ApiUserQuests.cs +++ b/packages/csharp-lib/Models/API/ApiUserQuests.cs @@ -14,7 +14,6 @@ public class ApiUserQuestsCharacter public DateTime ScannedAt { get; set; } public Dictionary>> Dailies { get; set; } - public List DailyQuestList { get; set; } public List> GoldWorldQuests { get; set; } public List QuestList { get; set; } = new(); @@ -24,7 +23,6 @@ public ApiUserQuestsCharacter(PlayerCharacterAddonQuests addonQuests, List { ScannedAt = addonQuests?.QuestsScannedAt ?? MiscConstants.DefaultDateTime; Dailies = addonQuests?.Dailies.EmptyIfNull(); - DailyQuestList = addonQuests?.DailyQuests ?? []; GoldWorldQuests = addonQuests?.GoldWorldQuests ?? []; RawProgressQuests = addonQuests?.ProgressQuests.EmptyIfNull(); QuestList = quests; diff --git a/packages/csharp-lib/Models/Player/PlayerCharacterAddonQuests.cs b/packages/csharp-lib/Models/Player/PlayerCharacterAddonQuests.cs index ea10a57b0..c502b3036 100644 --- a/packages/csharp-lib/Models/Player/PlayerCharacterAddonQuests.cs +++ b/packages/csharp-lib/Models/Player/PlayerCharacterAddonQuests.cs @@ -1,6 +1,7 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using Wowthing.Lib.Constants; +using Wowthing.Lib.Utilities; namespace Wowthing.Lib.Models.Player; @@ -17,8 +18,8 @@ public class PlayerCharacterAddonQuests(int characterId) public DateTime WorldQuestsScannedAt { get; set; } = MiscConstants.DefaultDateTime; public List CompletedQuests { get; set; } - public List DailyQuests { get; set; } - public List OtherQuests { get; set; } + // RoaringBitmap compressed data + public byte[] CompressedCompletedIds { get; set; } [Column(TypeName = "jsonb")] public Dictionary>> Dailies { get; set; } @@ -29,6 +30,11 @@ public class PlayerCharacterAddonQuests(int characterId) [Column(TypeName = "jsonb")] public Dictionary ProgressQuests { get; set; } + + [NotMapped] + public List UsableCompletedIds => CompressedCompletedIds != null + ? SerializationUtilities.DeserializeFromBitmap(CompressedCompletedIds) + : CompletedQuests; } public class PlayerCharacterAddonQuestsProgress diff --git a/packages/csharp-lib/Models/Player/PlayerCharacterQuests.cs b/packages/csharp-lib/Models/Player/PlayerCharacterQuests.cs index a4ae29898..dd9bf518b 100644 --- a/packages/csharp-lib/Models/Player/PlayerCharacterQuests.cs +++ b/packages/csharp-lib/Models/Player/PlayerCharacterQuests.cs @@ -1,5 +1,7 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using Wowthing.Lib.Constants; +using Wowthing.Lib.Utilities; namespace Wowthing.Lib.Models.Player; @@ -9,5 +11,15 @@ public class PlayerCharacterQuests public int CharacterId { get; set; } public PlayerCharacter Character { get; set; } + public DateTime ScannedAt { get; set; } = MiscConstants.DefaultDateTime; + + // Deprecated at this point public List CompletedIds { get; set; } -} \ No newline at end of file + // RoaringBitmap compressed data + public byte[] CompressedCompletedIds { get; set; } + + [NotMapped] + public List UsableCompletedIds => CompressedCompletedIds != null + ? SerializationUtilities.DeserializeFromBitmap(CompressedCompletedIds) + : CompletedIds; +} diff --git a/packages/csharp-lib/Services/CacheService.cs b/packages/csharp-lib/Services/CacheService.cs index 8a697375b..94d735a97 100644 --- a/packages/csharp-lib/Services/CacheService.cs +++ b/packages/csharp-lib/Services/CacheService.cs @@ -406,17 +406,35 @@ public async Task> GetRaiderIoTiers() }) .ToArrayAsync(); - var characterData = characters.ToDictionary( - c => c.Id, - c => new ApiUserQuestsCharacter( - c.AddonQuests, - SerializationUtilities.AsDiffedList( - (c.Quests?.CompletedIds ?? []) - .Union(c.AddonQuests?.OtherQuests ?? []) - .Union(c.AddonQuests?.CompletedQuests ?? []) - ) - ) - ); + var characterData = new Dictionary(); + foreach (var character in characters) + { + List questIds = null; + + bool hasQuests = character.Quests?.ScannedAt != null; + bool hasAddonQuests = character.AddonQuests?.CompletedQuestsScannedAt != null; + if (hasQuests && hasAddonQuests) + { + // Only use API quests if they're at least an hour newer than addon data, API sucks + var difference = character.Quests.ScannedAt - character.AddonQuests.CompletedQuestsScannedAt; + questIds = difference.TotalHours < 1 + ? character.AddonQuests.UsableCompletedIds + : character.Quests.UsableCompletedIds; + } + else if (hasQuests) + { + questIds = character.Quests.UsableCompletedIds; + } + else if (hasAddonQuests) + { + questIds = character.AddonQuests.UsableCompletedIds; + } + + characterData[character.Id] = new ApiUserQuestsCharacter( + character.AddonQuests, + SerializationUtilities.AsDiffedList(questIds ?? []) + ); + } timer.AddPoint("Database"); diff --git a/packages/csharp-lib/Utilities/SerializationUtilities.cs b/packages/csharp-lib/Utilities/SerializationUtilities.cs index 57b9da7a7..9790a6461 100644 --- a/packages/csharp-lib/Utilities/SerializationUtilities.cs +++ b/packages/csharp-lib/Utilities/SerializationUtilities.cs @@ -1,4 +1,5 @@ using System.Buffers.Binary; +using Equativ.RoaringBitmaps; namespace Wowthing.Lib.Utilities; @@ -52,4 +53,19 @@ public static List AsDiffedList(IEnumerable input) return ret; } + + public static byte[] SerializeToBitmap(IEnumerable values) + { + var bitmap = RoaringBitmap.Create(values); + using var stream = new MemoryStream(); + RoaringBitmap.Serialize(bitmap, stream); + return stream.ToArray(); + } + + public static List DeserializeFromBitmap(byte[] data) + { + using var stream = new MemoryStream(data); + var bitmap = RoaringBitmap.Deserialize(stream); + return bitmap.ToArray(); + } } diff --git a/packages/csharp-lib/Wowthing.Lib.csproj b/packages/csharp-lib/Wowthing.Lib.csproj index e205bae27..6e06c53bb 100644 --- a/packages/csharp-lib/Wowthing.Lib.csproj +++ b/packages/csharp-lib/Wowthing.Lib.csproj @@ -6,6 +6,7 @@ +