From 791c35bc94c4a24b6e5a51ae6c5225dc44ae2db7 Mon Sep 17 00:00:00 2001 From: Freddie Date: Tue, 20 Oct 2026 10:02:59 -0700 Subject: [PATCH 1/5] Add PlayerAccountAddonData.Paragons --- apps/backend/Jobs/User/UserUploadJob.cs | 71 +- apps/backend/Models/Uploads/Upload.cs | 1 + apps/frontend/types/user-data.ts | 10 + .../user-home/state/user/general.svelte.ts | 9 + apps/web/Controllers/ApiController.cs | 9 +- apps/web/Models/Api/User/ApiUser.cs | 1 + ...layerAccountAddonData_Paragons.Designer.cs | 4554 +++++++++++++++++ ...045_Add_PlayerAccountAddonData_Paragons.cs | 29 + .../Migrations/WowDbContextModelSnapshot.cs | 4 + .../Models/Player/PlayerAccountAddonData.cs | 3 + 10 files changed, 4668 insertions(+), 23 deletions(-) create mode 100644 packages/csharp-lib/Migrations/20261020154045_Add_PlayerAccountAddonData_Paragons.Designer.cs create mode 100644 packages/csharp-lib/Migrations/20261020154045_Add_PlayerAccountAddonData_Paragons.cs diff --git a/apps/backend/Jobs/User/UserUploadJob.cs b/apps/backend/Jobs/User/UserUploadJob.cs index 696b5e3ba..20266d731 100644 --- a/apps/backend/Jobs/User/UserUploadJob.cs +++ b/apps/backend/Jobs/User/UserUploadJob.cs @@ -443,7 +443,12 @@ private async Task Process(string luaData) { // Reputations try { - await HandleAccountReputations(accountAddonData, parsed.ScanTimes.EmptyIfNull(), parsed.Reputations); + await HandleAccountReputations( + accountAddonData, + parsed.ScanTimes.EmptyIfNull(), + parsed.Paragons, + parsed.Reputations + ); } catch (Exception ex) { @@ -718,37 +723,59 @@ private async Task HandleBattlePets(int accountId, Dictionary pars private async Task HandleAccountReputations( PlayerAccountAddonData accountAddonData, Dictionary globalScanTimes, + Dictionary paragons, List reputations ) { var localContext = Context; - if (globalScanTimes.TryGetValue("reputations", out int reputationsTimestamp)) + if (!globalScanTimes.TryGetValue("reputations", out int reputationsTimestamp)) { - var reputationsScannedAt = reputationsTimestamp.AsUtcDateTime(); - if (reputationsScannedAt > accountAddonData.ReputationsScannedAt) - { - accountAddonData.ReputationsScannedAt = reputationsScannedAt; - accountAddonData.Reputations ??= new(); + return; + } - foreach (string repString in reputations) - { - string[] parts = repString.Split(":"); - if (parts.Length == 2 && - int.TryParse(parts[0], out int factionId) && - int.TryParse(parts[1], out int value)) - { - accountAddonData.Reputations[factionId] = value; - } - } + var reputationsScannedAt = reputationsTimestamp.AsUtcDateTime(); + if (reputationsScannedAt <= accountAddonData.ReputationsScannedAt) + { + return; + } - // Change detection for this is obnoxious, just update it - localContext.Entry(accountAddonData) - .Property(aad => aad.Reputations) - .IsModified = true; + accountAddonData.ReputationsScannedAt = reputationsScannedAt; - await localContext.SaveChangesAsync(CancellationToken); + accountAddonData.Paragons ??= new(); + foreach ((int factionId, string paragonString) in paragons.EmptyIfNull()) + { + string[] parts = paragonString.Split(':'); + if (parts.Length >= 2 && + long.TryParse(parts[0], out long totalRep) && + int.TryParse(parts[1], out int perLevel)) + { + int count = (int)(totalRep / perLevel); + int remainder = (int)(totalRep % perLevel); + accountAddonData.Paragons[factionId] = [count, perLevel, remainder]; + } + } + + accountAddonData.Reputations ??= new(); + foreach (string repString in reputations.EmptyIfNull()) + { + string[] parts = repString.Split(":"); + if (parts.Length == 2 && + int.TryParse(parts[0], out int factionId) && + int.TryParse(parts[1], out int value)) + { + accountAddonData.Reputations[factionId] = value; } } + + // Change detection for this is obnoxious, just update it + localContext.Entry(accountAddonData) + .Property(aad => aad.Paragons) + .IsModified = true; + localContext.Entry(accountAddonData) + .Property(aad => aad.Reputations) + .IsModified = true; + + await localContext.SaveChangesAsync(CancellationToken); } private async Task HandleDecor(PlayerAccountAddonData accountAddonData, Dictionary globalScanTimes, Dictionary decorData) diff --git a/apps/backend/Models/Uploads/Upload.cs b/apps/backend/Models/Uploads/Upload.cs index c0a9905ee..35b68375d 100644 --- a/apps/backend/Models/Uploads/Upload.cs +++ b/apps/backend/Models/Uploads/Upload.cs @@ -22,6 +22,7 @@ public class Upload public Dictionary Decor { get; set; } public List Delves { get; set; } public List Illusions { get; set; } + public Dictionary Paragons { get; set; } public List Quests { get; set; } public Dictionary QuestsV2 { get; set; } public List Reputations { get; set; } diff --git a/apps/frontend/types/user-data.ts b/apps/frontend/types/user-data.ts index e042355e0..645a734bc 100644 --- a/apps/frontend/types/user-data.ts +++ b/apps/frontend/types/user-data.ts @@ -23,6 +23,7 @@ export interface UserData { guildsRaw: GuildArray[]; heirlooms: Record; illusionIds: number[]; + paragons: Record; raiderIoScoreTiers: Record; reputations: Record; warbankItems: WarbankItem[]; @@ -112,6 +113,15 @@ export class UserDataCurrentPeriod { } } +export class UserDataParagon { + constructor( + public count: number, + public perLevel: number, + public value: number + ) {} +} +export type UserDataParagonArray = ConstructorParameters; + export class UserDataPet { constructor( public level: number, diff --git a/apps/frontend/user-home/state/user/general.svelte.ts b/apps/frontend/user-home/state/user/general.svelte.ts index b11f091a4..51a143552 100644 --- a/apps/frontend/user-home/state/user/general.svelte.ts +++ b/apps/frontend/user-home/state/user/general.svelte.ts @@ -18,6 +18,7 @@ import { Character, Guild, UserDataCurrentPeriod, + UserDataParagon, UserDataPet, type Account, type CharacterLockout, @@ -52,6 +53,7 @@ export class DataUserGeneral { public currentPeriod: Record = $state({}); public decor: Record = $state({}); public guildById: Record = $state({}); + public paragons: Record = $state({}); public petsById: Record = $state({}); public reputations: Record = $state({}); public warbankItems: WarbankItem[] = $state([]); @@ -211,6 +213,13 @@ export class DataUserGeneral { .filter(([, [a, b]]) => a + b > 0) .map(([decorId]) => decorId) ); + + this.paragons = Object.fromEntries( + getNumberKeyedEntries(userData.paragons || {}).map(([factionId, paragonArray]) => [ + factionId, + new UserDataParagon(...paragonArray), + ]) + ); this.reputations = cloneDeep(userData.reputations || {}); this.honorCurrent = userData.honorCurrent; diff --git a/apps/web/Controllers/ApiController.cs b/apps/web/Controllers/ApiController.cs index 43a0d7bde..96332411d 100644 --- a/apps/web/Controllers/ApiController.cs +++ b/apps/web/Controllers/ApiController.cs @@ -451,13 +451,19 @@ await _cacheService.CreateOrUpdateTransmogCacheAsync( timer.AddPoint("RaiderIO"); // Reputations + var paragons = new Dictionary>(); var reputations = new Dictionary(); var repAccounts = accounts .Where(account => account.AddonData?.Reputations != null) .OrderBy(account => account.AddonData.ReputationsScannedAt); foreach (var account in repAccounts) { - foreach ((int factionId, int value) in account.AddonData.Reputations) + foreach ((int factionId, var values) in account.AddonData.Paragons.EmptyIfNull()) + { + paragons[factionId] = values; + } + + foreach ((int factionId, int value) in account.AddonData.Reputations.EmptyIfNull()) { reputations[factionId] = value; } @@ -528,6 +534,7 @@ await _cacheService.CreateOrUpdateTransmogCacheAsync( HonorLevel = maxHonorAccount?.AddonData?.HonorLevel ?? 0, HonorMax = maxHonorAccount?.AddonData?.HonorMax ?? 0, Images = images, + Paragons = paragons, Public = apiResult.Public, RaiderIoScoreTiers = raiderIoScoreTiers, Reputations = reputations, diff --git a/apps/web/Models/Api/User/ApiUser.cs b/apps/web/Models/Api/User/ApiUser.cs index 876e311aa..cdc25a69a 100644 --- a/apps/web/Models/Api/User/ApiUser.cs +++ b/apps/web/Models/Api/User/ApiUser.cs @@ -31,6 +31,7 @@ public class ApiUser public Dictionary GlobalDailies { get; set; } public Dictionary Heirlooms { get; set; } public Dictionary Images { get; set; } + public Dictionary> Paragons { get; set; } public Dictionary RaiderIoScoreTiers { get; set; } public Dictionary Reputations { get; set; } diff --git a/packages/csharp-lib/Migrations/20261020154045_Add_PlayerAccountAddonData_Paragons.Designer.cs b/packages/csharp-lib/Migrations/20261020154045_Add_PlayerAccountAddonData_Paragons.Designer.cs new file mode 100644 index 000000000..4e271e207 --- /dev/null +++ b/packages/csharp-lib/Migrations/20261020154045_Add_PlayerAccountAddonData_Paragons.Designer.cs @@ -0,0 +1,4554 @@ +// +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("20261020154045_Add_PlayerAccountAddonData_Paragons")] + partial class Add_PlayerAccountAddonData_Paragons + { + /// + 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.PlayerAccountAchievements", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.PrimitiveCollection>("AchievementTimestamps") + .HasColumnType("integer[]") + .HasColumnName("achievement_timestamps"); + + b.Property("CompressedAchievementIds") + .HasColumnType("bytea") + .HasColumnName("compressed_achievement_ids"); + + b.HasKey("AccountId") + .HasName("pk_player_account_achievements"); + + b.ToTable("player_account_achievements", (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.Property>>("Paragons") + .HasColumnType("jsonb") + .HasColumnName("paragons"); + + 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.Property("CompressedCriteriaIds") + .HasColumnType("bytea") + .HasColumnName("compressed_criteria_ids"); + + 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.PlayerAccountAchievements", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithMany() + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_achievements_player_account_account_id"); + + b.Navigation("Account"); + }); + + 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/20261020154045_Add_PlayerAccountAddonData_Paragons.cs b/packages/csharp-lib/Migrations/20261020154045_Add_PlayerAccountAddonData_Paragons.cs new file mode 100644 index 000000000..a63bf9297 --- /dev/null +++ b/packages/csharp-lib/Migrations/20261020154045_Add_PlayerAccountAddonData_Paragons.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Wowthing.Lib.Migrations +{ + /// + public partial class Add_PlayerAccountAddonData_Paragons : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn>>( + name: "paragons", + table: "player_account_addon_data", + type: "jsonb", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "paragons", + table: "player_account_addon_data"); + } + } +} diff --git a/packages/csharp-lib/Migrations/WowDbContextModelSnapshot.cs b/packages/csharp-lib/Migrations/WowDbContextModelSnapshot.cs index 3c3b7880a..887575128 100644 --- a/packages/csharp-lib/Migrations/WowDbContextModelSnapshot.cs +++ b/packages/csharp-lib/Migrations/WowDbContextModelSnapshot.cs @@ -623,6 +623,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("integer[]") .HasColumnName("illusions"); + b.Property>>("Paragons") + .HasColumnType("jsonb") + .HasColumnName("paragons"); + b.PrimitiveCollection>("Quests") .HasColumnType("integer[]") .HasColumnName("quests"); diff --git a/packages/csharp-lib/Models/Player/PlayerAccountAddonData.cs b/packages/csharp-lib/Models/Player/PlayerAccountAddonData.cs index f717f1184..9253121de 100644 --- a/packages/csharp-lib/Models/Player/PlayerAccountAddonData.cs +++ b/packages/csharp-lib/Models/Player/PlayerAccountAddonData.cs @@ -26,6 +26,9 @@ public class PlayerAccountAddonData [Column(TypeName = "jsonb")] public Dictionary Heirlooms { get; set; } + [Column(TypeName = "jsonb")] + public Dictionary> Paragons { get; set; } + [Column(TypeName = "jsonb")] public Dictionary Reputations { get; set; } } From b2d616a2592fe1eac38ed87c9e07ea724d52c599 Mon Sep 17 00:00:00 2001 From: Freddie Date: Tue, 20 Oct 2026 10:19:29 -0700 Subject: [PATCH 2/5] Use account paragon data for Reputations display --- apps/frontend/types/user-data.ts | 16 +++++++++++++++- .../components/reputations/get-renown-data.ts | 17 ++++++++--------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/apps/frontend/types/user-data.ts b/apps/frontend/types/user-data.ts index 645a734bc..c17a88e43 100644 --- a/apps/frontend/types/user-data.ts +++ b/apps/frontend/types/user-data.ts @@ -3,7 +3,12 @@ import { DateTime } from 'luxon'; import parseApiTime from '@/utils/parse-api-time'; import type { Account } from './account'; -import type { Character, CharacterArray, CharacterLockout } from './character'; +import type { + Character, + CharacterArray, + CharacterLockout, + CharacterReputationParagon, +} from './character'; import type { InstanceDifficulty } from './dungeon'; import type { Guild, GuildArray } from './guild'; import type { HasNameAndRealm, UserItem } from './shared'; @@ -119,6 +124,15 @@ export class UserDataParagon { public perLevel: number, public value: number ) {} + + get asCharacterReputationParagon(): CharacterReputationParagon { + return { + rewardAvailable: false, + current: this.value, + max: this.perLevel, + received: this.count, + }; + } } export type UserDataParagonArray = ConstructorParameters; diff --git a/apps/frontend/user-home/components/reputations/get-renown-data.ts b/apps/frontend/user-home/components/reputations/get-renown-data.ts index 515e2cf86..c838a75ad 100644 --- a/apps/frontend/user-home/components/reputations/get-renown-data.ts +++ b/apps/frontend/user-home/components/reputations/get-renown-data.ts @@ -71,7 +71,10 @@ export function getRenownData({ ret.renownCurrent = repValue / (ret.dataRep.maxValues[0] || 2500); ret.cls = `quality${1 + Math.floor(ret.renownCurrent / (ret.renownMax / 4))}`; - ret.characterParagon = actualCharacter.paragons?.[ret.characterRep.reputationId]; + ret.characterParagon = ret.dataRep.accountWide + ? userState.general.paragons[ret.characterRep.reputationId] + ?.asCharacterReputationParagon + : actualCharacter.paragons?.[ret.characterRep.reputationId]; let tier = ret.renownCurrent; if (ret.characterParagon) { @@ -127,7 +130,10 @@ export function getRenownData({ ret.renownLevel = `${ret.repTier.percent}%`; if (ret.dataRep.paragonId) { - ret.characterParagon = actualCharacter.paragons?.[ret.dataRep.id]; + ret.characterParagon = ret.dataRep.accountWide + ? userState.general.paragons[ret.characterRep.reputationId] + ?.asCharacterReputationParagon + : actualCharacter.paragons?.[ret.dataRep.id]; if (ret.repTier.tier === 1) { ret.cls = 'reputation0 reputation0-border'; } @@ -135,12 +141,5 @@ export function getRenownData({ } } - if ( - (ret.dataRep?.id >= 2375 && ret.dataRep?.id <= 2377) || - (ret.dataRep?.id >= 2388 && ret.dataRep?.id < 2390) - ) { - console.log(ret); - } - return ret; } From be29368bba526a5bfd2b914206207eabc6b13560 Mon Sep 17 00:00:00 2001 From: Freddie Date: Tue, 20 Oct 2026 10:32:13 -0700 Subject: [PATCH 3/5] Account-wide non-renown reps can have paragons too --- .../user-home/components/reputations/AccountWide.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/frontend/user-home/components/reputations/AccountWide.svelte b/apps/frontend/user-home/components/reputations/AccountWide.svelte index fa79891fa..1c60a1357 100644 --- a/apps/frontend/user-home/components/reputations/AccountWide.svelte +++ b/apps/frontend/user-home/components/reputations/AccountWide.svelte @@ -144,7 +144,7 @@ - {#if renownMax && renownCurrent === renownMax && characterParagon} + {#if characterParagon && ((renownMax && renownCurrent === renownMax) || repTier?.tier === 1)} Date: Tue, 20 Oct 2026 11:21:51 -0700 Subject: [PATCH 4/5] Hope/Unity chore needs to be Custom reset type --- apps/frontend/data/tasks/11-midnight/12-0.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/frontend/data/tasks/11-midnight/12-0.ts b/apps/frontend/data/tasks/11-midnight/12-0.ts index 16df6df2e..9f91dac10 100644 --- a/apps/frontend/data/tasks/11-midnight/12-0.ts +++ b/apps/frontend/data/tasks/11-midnight/12-0.ts @@ -93,7 +93,7 @@ export const midChores12_0: Task = { key: 'midHopeUnity', name: 'Hope/Unity', icon: aliasedIcons.planet, - questReset: DbResetType.Weekly, + questReset: DbResetType.Custom, showQuestName: true, sumObjectives: true, customExpiryFunc: (char, scannedAt) => customResetPeriod(char, scannedAt, 1079, 2), From de267d3fece160df469c5afc59b793fe6baaf630 Mon Sep 17 00:00:00 2001 From: Freddie Date: Tue, 20 Oct 2026 11:30:33 -0700 Subject: [PATCH 5/5] Tweak level range colors for Nazjatar friends --- apps/frontend/components/tooltips/reputation/hacks.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/frontend/components/tooltips/reputation/hacks.ts b/apps/frontend/components/tooltips/reputation/hacks.ts index 760b60139..37669b539 100644 --- a/apps/frontend/components/tooltips/reputation/hacks.ts +++ b/apps/frontend/components/tooltips/reputation/hacks.ts @@ -1,6 +1,6 @@ export function nazjatarHack(levelString: string): number { const level = parseInt(levelString.split(' ').at(-1)); - return level === 30 ? 0 : 6 - Math.max(0, Math.floor(level / 5)); + return level === 30 ? 1 : 4 - Math.floor(level / 10); } export function brannHack(levelString: string): number {