diff --git a/apps/backend/Helpers/UserUploadCharacterProcessor.cs b/apps/backend/Helpers/UserUploadCharacterProcessor.cs index 83481f471..5649f4ff3 100644 --- a/apps/backend/Helpers/UserUploadCharacterProcessor.cs +++ b/apps/backend/Helpers/UserUploadCharacterProcessor.cs @@ -172,6 +172,7 @@ private void InitializeCharacterThings() private void HandleAddonData() { + _character.AddonData.BankTabs = _characterData.BankTabs; _character.AddonData.Level = _characterData.Level; _character.AddonData.LevelXp = _characterData.LevelXp; diff --git a/apps/backend/Jobs/Magic/MagicAggregateMiscReportsJob.cs b/apps/backend/Jobs/Magic/MagicAggregateMiscReportsJob.cs new file mode 100644 index 000000000..3149f9af8 --- /dev/null +++ b/apps/backend/Jobs/Magic/MagicAggregateMiscReportsJob.cs @@ -0,0 +1,66 @@ +using Wowthing.Lib.Enums; +using Wowthing.Lib.Jobs; +using Wowthing.Lib.Models; +using Wowthing.Lib.Utilities; + +namespace Wowthing.Backend.Jobs.Magic; + +public class MagicAggregateMiscReportsJob : JobBase, IScheduledJob +{ + public static readonly ScheduledJob Schedule = new ScheduledJob + { + Type = JobType.MagicAggregateMiscReports, + Priority = JobPriority.High, + Interval = TimeSpan.FromMinutes(1), + Version = 1, + }; + + public override async Task Run(string[] data) + { + var timer = new JankTimer(); + + var aggregateMap = await Context.MiscAggregate + .ToDictionaryAsync(ma => (ma.ReportType, ma.Region)); + + // Delves + foreach (var reportType in Enum.GetValues()) + { + foreach (var region in Enum.GetValues()) + { + var aggregateKey = (reportType, (short)region); + + var dataCounts = new Dictionary(); + var reportQuery = Context.MiscReport + .AsNoTracking() + .Where(mr => mr.Region == (short)region && + mr.ExpiresAt > DateTime.UtcNow) + .AsAsyncEnumerable(); + await foreach (var report in reportQuery) + { + dataCounts.TryAdd(report.Data, 0); + dataCounts[report.Data]++; + } + + if (!aggregateMap.TryGetValue(aggregateKey, out var dbAggregate)) + { + dbAggregate = new MiscAggregate + { + ReportType = reportType, + Region = (short)region, + }; + Context.MiscAggregate.Add(dbAggregate); + } + + dbAggregate.JsonData = dataCounts.Count > 0 + ? dataCounts.OrderByDescending(x => x.Value).First().Key + : null; + } + } + + await Context.SaveChangesAsync(); + + timer.AddPoint("Save", true); + + Logger.Information("{timer}", timer.ToString()); + } +} diff --git a/apps/backend/Jobs/Maintenance/MaintenanceDeleteMiscReportsJob.cs b/apps/backend/Jobs/Maintenance/MaintenanceDeleteMiscReportsJob.cs new file mode 100644 index 000000000..c0ddc22a6 --- /dev/null +++ b/apps/backend/Jobs/Maintenance/MaintenanceDeleteMiscReportsJob.cs @@ -0,0 +1,41 @@ +using Npgsql; +using Wowthing.Lib.Jobs; + +namespace Wowthing.Backend.Jobs.Maintenance; + +public class MaintenanceDeleteMiscReportsJob : JobBase, IScheduledJob +{ + public static readonly ScheduledJob Schedule = new ScheduledJob + { + Type = JobType.MaintenanceDeleteMiscReports, + Priority = JobPriority.High, + Interval = TimeSpan.FromMinutes(1), + Version = 1, + }; + + private const string DeleteQuery = @" +DELETE FROM misc_report +WHERE id IN ( + SELECT id + FROM misc_report + WHERE expires_at < $1 + LIMIT 10000 +) +"; + + public override async Task Run(string[] data) + { + await using var connection = Context.GetConnection(); + await connection.OpenAsync(); + + await using var command = connection.CreateCommand(); + command.CommandText = DeleteQuery; + command.Parameters.Add(new NpgsqlParameter { Value = DateTime.UtcNow.AddHours(-1) }); + + int deleted = await command.ExecuteNonQueryAsync(); + if (deleted > 0) + { + Logger.Information("Deleted {count} misc report(s)", deleted); + } + } +} diff --git a/apps/backend/Jobs/User/UserUploadJob.cs b/apps/backend/Jobs/User/UserUploadJob.cs index 0aea6b746..696b5e3ba 100644 --- a/apps/backend/Jobs/User/UserUploadJob.cs +++ b/apps/backend/Jobs/User/UserUploadJob.cs @@ -556,6 +556,17 @@ await HandleWarbank(accountRegion.Value, userAddonData, parsed.ScanTimes.EmptyIf } } + try + { + await HandleMiscReports(accountRegion.Value, parsed); + } + catch (Exception ex) + { + { + Logger.Error(ex, "HandleBattlePets failed!"); + } + } + _timer.AddPoint("Account"); } @@ -1040,6 +1051,76 @@ await localContext.PlayerWarbankItem } } + private async Task HandleMiscReports(WowRegion accountRegion, Upload parsedData) + { + if (parsedData.Delves == null) + { + return; + } + + await using var localContext = await ContextFactory.CreateDbContextAsync(); + + var reportMap = await localContext.MiscReport + .Where(mr => mr.UserId == _userId && mr.Region == (short)accountRegion) + .ToDictionaryAsync(mr => mr.ReportType); + + long currentTimestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); + DateTime? expiresAt = null; + List<(int, string)> delves = []; + foreach (string delveString in parsedData.Delves) + { + string[] parts = delveString.Split(":"); + if (parts.Length != 3) + { + continue; + } + + // unixTimestamp:poiId:story + int.TryParse(parts[0], out int validUntil); + int.TryParse(parts[1], out int poiId); + if (validUntil < currentTimestamp || poiId == 0 || string.IsNullOrWhiteSpace(parts[2])) + { + // log + continue; + } + + expiresAt ??= validUntil.AsUtcDateTime(); + + delves.Add((poiId, parts[2])); + } + + if (expiresAt != null && delves.Count > 0) + { + List dataParts = []; + foreach ((int poiId, string story) in delves.OrderBy(tup => tup.Item1)) + { + dataParts.Add([poiId, story]); + } + + string data = JsonSerializer.Serialize(dataParts); + + if (reportMap.TryGetValue(MiscReportType.Delve, out var dbReport)) + { + dbReport.Data = data; + } + else + { + dbReport = new MiscReport + { + UserId = _userId, + ExpiresAt = expiresAt.Value, + ReportedAt = DateTime.UtcNow, + ReportType = MiscReportType.Delve, + Region = (short)accountRegion, + Data = data, + }; + localContext.MiscReport.Add(dbReport); + } + } + + await localContext.SaveChangesAsync(); + } + private async Task HandleWorldQuestReports(WowRegion accountRegion, Dictionary newReports) { diff --git a/apps/backend/Models/Uploads/Upload.cs b/apps/backend/Models/Uploads/Upload.cs index c9d7080a7..c0a9905ee 100644 --- a/apps/backend/Models/Uploads/Upload.cs +++ b/apps/backend/Models/Uploads/Upload.cs @@ -20,6 +20,7 @@ public class Upload public List Heirlooms { get; set; } public Dictionary Decor { get; set; } + public List Delves { get; set; } public List Illusions { get; set; } public List Quests { get; set; } public Dictionary QuestsV2 { get; set; } diff --git a/apps/frontend/components/characters/paperdoll/CharactersPaperdoll.svelte b/apps/frontend/components/characters/paperdoll/CharactersPaperdoll.svelte index 177351b64..213d5ee43 100644 --- a/apps/frontend/components/characters/paperdoll/CharactersPaperdoll.svelte +++ b/apps/frontend/components/characters/paperdoll/CharactersPaperdoll.svelte @@ -48,6 +48,10 @@ let characterImage = $derived.by(() => { const imagePath = $userStore.images[`${character.id}-2`]; + if (!imagePath) { + return undefined; + } + const imageUrl = document.getElementById('app').getAttribute('data-image-url'); return imageUrl ? `${imageUrl}${imagePath}` : imagePath; }); diff --git a/apps/frontend/components/home/view-switcher/Holiday.svelte b/apps/frontend/components/home/view-switcher/Holiday.svelte index 720f393cc..c0f66b61a 100644 --- a/apps/frontend/components/home/view-switcher/Holiday.svelte +++ b/apps/frontend/components/home/view-switcher/Holiday.svelte @@ -35,13 +35,15 @@ stats.total += dropStats.overall.total; } - const vendorStats = lazyState.vendors.stats[everything.vendorsKey.join('--')]; - if (vendorStats) { - stats.have += vendorStats.have; - stats.total += vendorStats.total; + if (everything?.vendorsKey?.length > 0) { + const vendorStats = lazyState.vendors.stats[everything?.vendorsKey.join('--')]; + if (vendorStats) { + stats.have += vendorStats.have; + stats.total += vendorStats.total; + } } - if (everything.achievementsKey?.length > 0) { + if (everything?.achievementsKey?.length > 0) { let cat = wowthingData.achievements.categories?.find( (cat) => cat?.slug === everything.achievementsKey[0] ); diff --git a/apps/frontend/components/items/ItemsItem.svelte b/apps/frontend/components/items/ItemsItem.svelte index 26c440bed..27b8f3144 100644 --- a/apps/frontend/components/items/ItemsItem.svelte +++ b/apps/frontend/components/items/ItemsItem.svelte @@ -7,7 +7,8 @@ } from './convertible/data'; import { Constants } from '@/data/constants'; import { iconStrings } from '@/data/icons'; - import { iconLibrary } from '@/shared/icons'; + import { InventoryType } from '@/enums/inventory-type'; + import { iconLibrary, uiIcons } from '@/shared/icons'; import { wowthingData } from '@/shared/stores/data'; import { getItemUrl } from '@/utils/get-item-url'; import { getBonusIdCraftingStat } from '@/utils/items/get-bonus-id-crafting-stat'; @@ -102,14 +103,20 @@ } }; + const statEnchants: Record = { + 7977: uiIcons.circleR, // Resourcefulness + 8005: uiIcons.circleM, // Multicrafting + 8035: uiIcons.circleI, // Ingenuity + }; + const statModifiers: Record = { - 76: iconLibrary.mdiLetterR, // Resourcefulness - 77: iconLibrary.mdiLetterF, // Finesse - 78: iconLibrary.mdiLetterD, // Deftness - 79: iconLibrary.mdiLetterP, // Perception - 80: iconLibrary.mdiLetterS, // Speed - 81: iconLibrary.mdiLetterM, // Multicrafting - 82: iconLibrary.mdiLetterI, // Ingenuity + 76: uiIcons.circleR, // Resourcefulness + 77: uiIcons.circleF, // Finesse + 78: uiIcons.circleD, // Deftness + 79: uiIcons.circleP, // Perception + 80: uiIcons.circleS, // Speed + 81: uiIcons.circleM, // Multicrafting + 82: uiIcons.circleI, // Ingenuity }; @@ -191,18 +198,23 @@ --image-border-color: #bbb; } } - .crafted-modifier { - --image-margin-top: -6px; + .crafted-modifier, + .crafted-enchant { --scale: 1.2; border-radius: 50%; pointer-events: none; position: absolute; - left: 0px; - top: 1px; height: 23px; + left: 0px; width: 23px; } + .crafted-modifier { + top: -1px; + } + .crafted-enchant { + bottom: 2px; + } .crafted-quality { pointer-events: none; position: absolute; @@ -290,6 +302,19 @@ )} /> + + {#if item?.inventoryType === InventoryType.ProfessionTool} + {@const statEnchantIcon = statEnchants[gear.equipped.enchantmentIds[0]]} + {#if statEnchantIcon} +
+ +
+ {:else} +
+ +
+ {/if} + {/if} {:else} {@const upgradeData = getUpgradeData()} {#if upgradeData?.[0] > 0} diff --git a/apps/frontend/components/items/ItemsSearch.svelte b/apps/frontend/components/items/ItemsSearch.svelte index 9d2d41de5..a1566758d 100644 --- a/apps/frontend/components/items/ItemsSearch.svelte +++ b/apps/frontend/components/items/ItemsSearch.svelte @@ -76,12 +76,17 @@ form { align-items: center; display: flex; + flex-wrap: wrap; gap: 0.8rem; } .option { align-items: center; display: flex; gap: 0.2rem; + + > span { + white-space: nowrap; + } } .results-container { column-count: max(2, var(--column-count, 1)); diff --git a/apps/frontend/components/items/ItemsTableRowBags.svelte b/apps/frontend/components/items/ItemsTableRowBags.svelte index 4156217c9..669d47fa6 100644 --- a/apps/frontend/components/items/ItemsTableRowBags.svelte +++ b/apps/frontend/components/items/ItemsTableRowBags.svelte @@ -2,50 +2,45 @@ import { bankBagSlots, characterBagSlots } from '@/data/inventory-slot'; import { browserState } from '@/shared/state/browser.svelte'; import { wowthingData } from '@/shared/stores/data'; - import { CharacterEquippedItem, type Character, type CharacterGear } from '@/types'; + import { CharacterEquippedItem, type CharacterGear } from '@/types'; + import type { CharacterProps } from '@/types/props'; import Empty from './ItemsEmpty.svelte'; import Item from './ItemsItem.svelte'; - export let character: Character; + let { character }: CharacterProps = $props(); - let bagSets: [number, Partial][][]; - $: { - bagSets = []; - for (const bagSlots of [characterBagSlots, bankBagSlots]) { - const bagThings: [number, Partial][] = []; + let bags = $derived.by(() => { + const ret: [number, Partial][] = []; + for (const bagSlot of characterBagSlots) { + const itemId = character.bags[bagSlot]; + const bag = wowthingData.static.bagById.get(itemId); - for (const bagSlot of bagSlots) { - const itemId = character.bags[bagSlot]; - const bag = wowthingData.static.bagById.get(itemId); - - if (itemId && bag) { - bagThings.push([ - bagSlot, - { - equipped: new CharacterEquippedItem( - 0, - 0, - itemId, - bag.slots, - bag.quality, - [], - [], - [] - ), - highlight: - browserState.current.items.minimumBagSize > 0 && - bag.slots < browserState.current.items.minimumBagSize, - }, - ]); - } else { - bagThings.push([bagSlot, null]); - } + if (itemId && bag) { + ret.push([ + bagSlot, + { + equipped: new CharacterEquippedItem( + 0, + 0, + itemId, + bag.slots, + bag.quality, + [], + [], + [] + ), + highlight: + browserState.current.items.minimumBagSize > 0 && + bag.slots < browserState.current.items.minimumBagSize, + }, + ]); + } else { + ret.push([bagSlot, null]); } - - bagSets.push(bagThings); } - } + return ret; + }); const getSlotText = function (slot: number): string { if (slot < 5) { @@ -58,18 +53,24 @@ }; -{#each bagSets as bagSlots} - + +{#each bags as [bagSlot, gear] (bagSlot)} + {#if gear} + 0} + /> + {:else} + + {/if} +{/each} - {#each bagSlots as [bagSlot, gear]} - {#if gear} - 0} - /> - {:else} - - {/if} - {/each} + +{#each bankBagSlots as bankBagSlot (bankBagSlot)} + {#if character.bankTabs > bankBagSlot - 6} + + {:else} + + {/if} {/each} diff --git a/apps/frontend/components/professions/equipment/some.ts b/apps/frontend/components/professions/equipment/some.ts index 1549dc189..0862bf4ba 100644 --- a/apps/frontend/components/professions/equipment/some.ts +++ b/apps/frontend/components/professions/equipment/some.ts @@ -4,4 +4,5 @@ export const someProfessions = [ Profession.Alchemy, Profession.Enchanting, Profession.Jewelcrafting, + Profession.Tailoring, ]; diff --git a/apps/frontend/components/tooltips/task/TooltipTaskRow.svelte b/apps/frontend/components/tooltips/task/TooltipTaskRow.svelte index 0aa1abf95..87ea02064 100644 --- a/apps/frontend/components/tooltips/task/TooltipTaskRow.svelte +++ b/apps/frontend/components/tooltips/task/TooltipTaskRow.svelte @@ -2,7 +2,7 @@ import { Strings } from '@/data/constants'; import { taskChoreMap, taskMap } from '@/data/tasks'; import { QuestStatus } from '@/enums/quest-status'; - import { iconLibrary, uiIcons } from '@/shared/icons'; + import { uiIcons } from '@/shared/icons'; import { settingsState } from '@/shared/state/settings.svelte'; import { DbResetType } from '@/shared/stores/db/enums'; import { userState } from '@/user-home/state/user'; @@ -151,21 +151,12 @@ class:status-shrug={charTaskChore.status === QuestStatus.Error} > {#if chore.questReset === DbResetType.Daily && settingsState.value.tasks.showDailyIcon} - + {:else if chore.questReset === DbResetType.Weekly && settingsState.value.tasks.showWeeklyIcon} - + {/if} {#if chore.accountWide && settingsState.value.tasks.showAccountIcon} - + {/if} @@ -239,13 +230,13 @@ {#if settingsState.value.tasks.showIconLegend}
- Daily + Daily - Weekly + Weekly - Account + Account
{/if} diff --git a/apps/frontend/data/holidays.ts b/apps/frontend/data/holidays.ts index dcfb2fd5e..9742905dc 100644 --- a/apps/frontend/data/holidays.ts +++ b/apps/frontend/data/holidays.ts @@ -93,7 +93,6 @@ export const holidayIds: Record = { [Holiday.CupBrokenIsles]: [[433]], // Legion [Holiday.PrepatchMidnight]: [[450]], - [Holiday.RemixLegion]: [[447]], }; export type FancyHoliday = { @@ -162,6 +161,59 @@ export const fancyHolidays: FancyHoliday[] = [ shortName: '🎅', everything: 'winter-veil', }, + + // Timewalking + { + holiday: Holiday.TimewalkingClassic, + shortName: '⏳Classic', + everything: 'timewalking-classic', + }, + { + holiday: Holiday.TimewalkingTbc, + shortName: '⏳TBC', + everything: 'timewalking-tbc', + }, + { + holiday: Holiday.TimewalkingWotlk, + shortName: '⏳WotLK', + everything: 'timewalking-wotlk', + }, + { + holiday: Holiday.TimewalkingCata, + shortName: '⏳Cata', + everything: 'timewalking-cata', + }, + { + holiday: Holiday.TimewalkingMop, + shortName: '⏳MoP', + everything: 'timewalking-mop', + }, + { + holiday: Holiday.TimewalkingWod, + shortName: '⏳WoD', + everything: 'timewalking-wod', + }, + { + holiday: Holiday.TimewalkingLegion, + shortName: '⏳Legion', + everything: 'timewalking-legion', + }, + { + holiday: Holiday.TimewalkingBfa, + shortName: '⏳BfA', + everything: 'timewalking-bfa', + }, + { + holiday: Holiday.TimewalkingSl, + shortName: '⏳SL', + everything: 'timewalking-sl', + }, + { + holiday: Holiday.TimewalkingDf, + shortName: '⏳DF', + everything: 'timewalking-df', + }, + // Flying Cups { holiday: Holiday.CupEasternKingdoms, // Classic @@ -200,14 +252,4 @@ export const fancyHolidays: FancyHoliday[] = [ shortName: 'Anni', everything: 'anniversary', }, - { - holiday: Holiday.PrepatchMidnight, - shortName: 'Prepatch', - everything: 'prepatch-midnight', - }, - { - holiday: Holiday.RemixLegion, - shortName: 'Lemix', - everything: 'remix-legion', - }, ]; diff --git a/apps/frontend/data/inventory-slot.ts b/apps/frontend/data/inventory-slot.ts index 6b07404c7..0dc412040 100644 --- a/apps/frontend/data/inventory-slot.ts +++ b/apps/frontend/data/inventory-slot.ts @@ -47,4 +47,4 @@ export const characterBagSlots: number[] = [ 5, // Reagent bag ]; -export const bankBagSlots: number[] = [6, 7, 8, 9, 10, 11, 12]; +export const bankBagSlots: number[] = [6, 7, 8, 9, 10, 11]; diff --git a/apps/frontend/enums/holiday.ts b/apps/frontend/enums/holiday.ts index 500db13de..4170af91e 100644 --- a/apps/frontend/enums/holiday.ts +++ b/apps/frontend/enums/holiday.ts @@ -30,6 +30,7 @@ export enum Holiday { TimewalkingLegion, TimewalkingBfa, TimewalkingSl, + TimewalkingDf, BrawlArathiBlizzard, BrawlClassicAshran, @@ -53,7 +54,6 @@ export enum Holiday { // Temporary PrepatchMidnight, - RemixLegion, } export const timewalkingHolidays = [ diff --git a/apps/frontend/scss/layout/subnav.scss b/apps/frontend/scss/layout/subnav.scss index ea94dfeb8..d52e59790 100644 --- a/apps/frontend/scss/layout/subnav.scss +++ b/apps/frontend/scss/layout/subnav.scss @@ -3,6 +3,7 @@ // border: 1px solid var(--border-color); display: flex; + flex-wrap: wrap; overflow: hidden; padding: 0; width: 100%; @@ -14,6 +15,7 @@ border-top: 1px solid var(--border-color); display: inline-block; padding: 0.25rem 1rem; + white-space: nowrap; &:first-child { border-left: 1px solid var(--border-color); diff --git a/apps/frontend/shared/icons/library.ts b/apps/frontend/shared/icons/library.ts index edd5ae6ef..419681af6 100644 --- a/apps/frontend/shared/icons/library.ts +++ b/apps/frontend/shared/icons/library.ts @@ -155,6 +155,7 @@ export { default as mdiLetterM } from '~icons/mdi/alpha-m-circle-outline'; export { default as mdiLetterP } from '~icons/mdi/alpha-p-circle-outline'; export { default as mdiLetterR } from '~icons/mdi/alpha-r-circle-outline'; export { default as mdiLetterS } from '~icons/mdi/alpha-s-circle-outline'; +export { default as mdiLetterX } from '~icons/mdi/alpha-x-circle-outline'; export { default as mdiLightningBoltOutline } from '~icons/mdi/lightning-bolt-outline'; export { default as mdiListStatus } from '~icons/mdi/list-status'; export { default as mdiLockOutline } from '~icons/mdi/lock-outline'; @@ -200,10 +201,17 @@ export { default as mdiWizardHat } from '~icons/mdi/wizard-hat'; export { default as mynauiLetterASquare } from '~icons/mynaui/letter-a-square'; export { default as mynauiLetterCSquare } from '~icons/mynaui/letter-c-square'; +export { default as mynauiLetterDCircle } from '~icons/mynaui/letter-d-circle'; export { default as mynauiLetterDSquare } from '~icons/mynaui/letter-d-square'; +export { default as mynauiLetterFCircle } from '~icons/mynaui/letter-f-circle'; +export { default as mynauiLetterICircle } from '~icons/mynaui/letter-i-circle'; export { default as mynauiLetterLSquare } from '~icons/mynaui/letter-l-square'; +export { default as mynauiLetterMCircle } from '~icons/mynaui/letter-m-circle'; export { default as mynauiLetterMSquare } from '~icons/mynaui/letter-m-square'; +export { default as mynauiLetterPCircle } from '~icons/mynaui/letter-p-circle'; export { default as mynauiLetterPSquare } from '~icons/mynaui/letter-p-square'; +export { default as mynauiLetterRCircle } from '~icons/mynaui/letter-r-circle'; +export { default as mynauiLetterSCircle } from '~icons/mynaui/letter-s-circle'; export { default as mynauiLetterWSquare } from '~icons/mynaui/letter-w-square'; export { default as notoAngryFaceWithHorns } from '~icons/noto/angry-face-with-horns'; diff --git a/apps/frontend/shared/icons/mappings/armor-type.ts b/apps/frontend/shared/icons/mappings/armor-type.ts index 601153e8a..23af8ea88 100644 --- a/apps/frontend/shared/icons/mappings/armor-type.ts +++ b/apps/frontend/shared/icons/mappings/armor-type.ts @@ -1,17 +1,14 @@ -import * as iconLibrary from '../library'; import { ArmorType } from '@/enums/armor-type'; import type { Icon } from '@/types/icons'; +import * as iconLibrary from '../library'; +import { uiIcons } from '../ui'; export const armorTypeIcons: Record = { [ArmorType.Cloak]: iconLibrary.gameCape, - [ArmorType.Cloth]: iconLibrary.mynauiLetterCSquare, - [ArmorType.Leather]: iconLibrary.mynauiLetterLSquare, - [ArmorType.Mail]: iconLibrary.mynauiLetterMSquare, - [ArmorType.Plate]: iconLibrary.mynauiLetterPSquare, - // [ArmorType.Cloth]: iconLibrary.mdiLetterC, - // [ArmorType.Leather]: iconLibrary.mdiLetterL, - // [ArmorType.Mail]: iconLibrary.mdiLetterM, - // [ArmorType.Plate]: iconLibrary.mdiLetterP, + [ArmorType.Cloth]: uiIcons.squareC, + [ArmorType.Leather]: uiIcons.squareL, + [ArmorType.Mail]: uiIcons.squareM, + [ArmorType.Plate]: uiIcons.squareP, [ArmorType.Tabard]: null, [ArmorType.None]: null, }; diff --git a/apps/frontend/shared/icons/ui.ts b/apps/frontend/shared/icons/ui.ts index 7082fed9c..a1526f479 100644 --- a/apps/frontend/shared/icons/ui.ts +++ b/apps/frontend/shared/icons/ui.ts @@ -12,6 +12,21 @@ export const uiIcons = { starHalf: iconLibrary.mdiStarHalfFull, starFull: iconLibrary.mdiStarFace, yes: iconLibrary.mdiCheck, + + circleD: iconLibrary.mynauiLetterDCircle, + circleF: iconLibrary.mynauiLetterFCircle, + circleI: iconLibrary.mynauiLetterICircle, + circleM: iconLibrary.mynauiLetterMCircle, + circleP: iconLibrary.mynauiLetterPCircle, + circleR: iconLibrary.mynauiLetterRCircle, + circleS: iconLibrary.mynauiLetterSCircle, + squareA: iconLibrary.mynauiLetterASquare, + squareC: iconLibrary.mynauiLetterCSquare, + squareD: iconLibrary.mynauiLetterDSquare, + squareL: iconLibrary.mynauiLetterLSquare, + squareM: iconLibrary.mynauiLetterMSquare, + squareP: iconLibrary.mynauiLetterPSquare, + squareW: iconLibrary.mynauiLetterWSquare, }; export const aliasedIcons = { diff --git a/apps/frontend/types/character/character.svelte.ts b/apps/frontend/types/character/character.svelte.ts index ba2f61aee..acbd9cd67 100644 --- a/apps/frontend/types/character/character.svelte.ts +++ b/apps/frontend/types/character/character.svelte.ts @@ -103,6 +103,7 @@ export class Character implements ContainsItems, HasNameAndRealm { // Reactive public activeSpecId = $state(0); + public bankTabs = $state(0); public equippedItemLevel = $state(0); public gold = $state(0); public level = $state(0); @@ -189,6 +190,7 @@ export class Character implements ContainsItems, HasNameAndRealm { realmId: number, restedExperience: number, gold: number, + bankTabs: number, currentLocation: string, hearthLocation: string, lastApiUpdateUnix: number, @@ -250,6 +252,7 @@ export class Character implements ContainsItems, HasNameAndRealm { this.realmId = realmId; this.restedExperience = restedExperience; this.gold = gold; + this.bankTabs = bankTabs; this.currentLocation = currentLocation; this.hearthLocation = hearthLocation; this.lastApiUpdateUnix = lastApiUpdateUnix; diff --git a/apps/frontend/user-home/components/everything/Something.svelte b/apps/frontend/user-home/components/everything/Something.svelte index f82dd1a89..75bba2048 100644 --- a/apps/frontend/user-home/components/everything/Something.svelte +++ b/apps/frontend/user-home/components/everything/Something.svelte @@ -74,16 +74,6 @@ >Collected - - {#if slug === 'remix-legion'} - - {/if} @@ -118,7 +108,7 @@ -
+
{#each dbThings as dbThing} {/each} diff --git a/apps/frontend/user-home/components/everything/data.ts b/apps/frontend/user-home/components/everything/data.ts index b7378305f..749567d15 100644 --- a/apps/frontend/user-home/components/everything/data.ts +++ b/apps/frontend/user-home/components/everything/data.ts @@ -77,6 +77,56 @@ export const everythingData: Record = { achievementsKey: ['world-events', 'winter-veil'], vendorsKey: ['world-events', 'winter-veil'], }, + + // Timewalking + 'timewalking-classic': { + name: 'Classic Timewalking', + tag: 'event:timewalking-classic', + vendorsKey: ['classic', 'timewalking'], + }, + 'timewalking-tbc': { + name: 'TBC Timewalking', + tag: 'event:timewalking-tbc', + vendorsKey: ['burning-crusade', 'timewalking'], + }, + 'timewalking-wotlk': { + name: 'WotLK Timewalking', + tag: 'event:timewalking-wotlk', + }, + 'timewalking-cata': { + name: 'Cata Timewalking', + tag: 'event:timewalking-cata', + vendorsKey: ['cataclysm', 'timewalking'], + }, + 'timewalking-mop': { + name: 'MoP Timewalking', + tag: 'event:timewalking-mop', + vendorsKey: ['mists-of-pandaria', 'timewalking'], + }, + 'timewalking-wod': { + name: 'WoD Timewalking', + tag: 'event:timewalking-wod', + vendorsKey: ['warlords-of-draenor', 'timewalking'], + }, + 'timewalking-legion': { + name: 'Legion Timewalking', + tag: 'event:timewalking-legion', + vendorsKey: ['legion', 'timewalking'], + }, + 'timewalking-bfa': { + name: 'BfA Timewalking', + tag: 'event:timewalking-bfa', + vendorsKey: ['battle-for-azeroth', 'timewalking'], + }, + 'timewalking-sl': { + name: 'SL Timewalking', + tag: 'event:timewalking-sl', + }, + 'timewalking-df': { + name: 'DF Timewalking', + tag: 'event:timewalking-df', + }, + // 'cup-outland': { name: 'Outland Cup', @@ -91,10 +141,4 @@ export const everythingData: Record = { achievementsKey: ['world-events', 'anniversary-celebration'], vendorsKey: ['world-events', 'anniversary'], }, - 'remix-legion': { - name: 'Remix: Legion', - tag: 'event:remix-legion', - achievementsKey: ['legion-remix'], - vendorsKey: ['remix', 'legion'], - }, }; diff --git a/apps/frontend/user-home/components/settings/sections/SettingsTasks.svelte b/apps/frontend/user-home/components/settings/sections/SettingsTasks.svelte index 05b228fc4..19021bb57 100644 --- a/apps/frontend/user-home/components/settings/sections/SettingsTasks.svelte +++ b/apps/frontend/user-home/components/settings/sections/SettingsTasks.svelte @@ -2,7 +2,6 @@ import xor from 'lodash/xor'; import { Constants, MAX_TASKS } from '@/data/constants'; - import { iconLibrary } from '@/shared/icons'; import { uiIcons } from '@/shared/icons/ui'; import { settingsState } from '@/shared/state/settings.svelte'; import { DbResetType } from '@/shared/stores/db/enums'; @@ -110,7 +109,7 @@ name="tasks_show_account_icon" bind:value={settingsState.value.tasks.showAccountIcon} > - + Show account icon @@ -118,7 +117,7 @@ name="tasks_show_daily_icon" bind:value={settingsState.value.tasks.showDailyIcon} > - + Show daily icon @@ -126,7 +125,7 @@ name="tasks_show_weekly_icon" bind:value={settingsState.value.tasks.showWeeklyIcon} > - + Show weekly icon
diff --git a/apps/frontend/user-home/state/user/general.svelte.ts b/apps/frontend/user-home/state/user/general.svelte.ts index b34a6d605..18f9aead2 100644 --- a/apps/frontend/user-home/state/user/general.svelte.ts +++ b/apps/frontend/user-home/state/user/general.svelte.ts @@ -105,9 +105,9 @@ export class DataUserGeneral { const existed = !!character; if (existed) { - const lastApiUpdateUnix = characterArray[21]; - const lastSeenAddonUnix = characterArray[22]; - const lastScannedCurrencies = characterArray[25]; + const lastApiUpdateUnix = characterArray[22]; + const lastSeenAddonUnix = characterArray[23]; + const lastScannedCurrencies = characterArray[26]; if ( lastApiUpdateUnix > character.lastApiUpdateUnix || lastSeenAddonUnix > character.lastSeenAddonUnix || diff --git a/apps/tool/Data/TransmogSetItemPrimaryOverride.cs b/apps/tool/Data/TransmogSetItemPrimaryOverride.cs index 24c93da74..d3f0c5cec 100644 --- a/apps/tool/Data/TransmogSetItemPrimaryOverride.cs +++ b/apps/tool/Data/TransmogSetItemPrimaryOverride.cs @@ -26,5 +26,8 @@ public static partial class Hardcoded // The War Within - Liberation of Undermine - Rogue Normal { 73806, 0x0 }, // Hitman's Holster (wrong belt) { 73807, 0x1 }, // Spectral Gambler's ? (correct belt) + // Midnight - The Voidspire - Monk Heroic + { 101896, 0x0 }, // Power Stance Breeches (wrong legs) + { 101895, 0x1 }, // Swiftsweepers of Ra-den's Chosen (correct legs) }; } diff --git a/apps/tool/Models/Items/DumpItemSparse.cs b/apps/tool/Models/Items/DumpItemSparse.cs index a9522c133..ded7417b0 100644 --- a/apps/tool/Models/Items/DumpItemSparse.cs +++ b/apps/tool/Models/Items/DumpItemSparse.cs @@ -9,7 +9,6 @@ public class DumpItemSparse public int ID { get; set; } public int AllowableClass { get; set; } - public long AllowableRace { get; set; } public WowBindType Bonding { get; set; } public short ContainerSlots { get; set; } public short ExpansionID { get; set; } @@ -29,6 +28,13 @@ public class DumpItemSparse [Name("Display_lang")] public string Name { get; set; } = string.Empty; + [Name("AllowableRaces[0]")] + public int AllowableRaces0 { get; set; } + [Name("AllowableRaces[1]")] + public int AllowableRaces1 { get; set; } + + public long AllowableRace => AllowableRaces0 & (AllowableRaces1 > 0 ? (long)AllowableRaces1 << 32 : 0); + [Name("Flags[0]")] public WowItemFlags1 Flags1 { get; set; } [Name("Flags[1]")] diff --git a/apps/tool/Models/Quests/DumpQuestV2CliTask.cs b/apps/tool/Models/Quests/DumpQuestV2CliTask.cs index c2e437ffe..9aed1eab2 100644 --- a/apps/tool/Models/Quests/DumpQuestV2CliTask.cs +++ b/apps/tool/Models/Quests/DumpQuestV2CliTask.cs @@ -10,7 +10,6 @@ public class DumpQuestV2CliTask public int ID { get; set; } public short ContentTuningID { get; set; } - public long FiltRaces { get; set; } public short QuestInfoID { get; set; } [Name("FiltCompletedQuest[0]")] @@ -22,6 +21,14 @@ public class DumpQuestV2CliTask [Name("FiltCompletedQuest[2]")] public int FiltCompletedQuest2 { get; set; } + [Name("FiltRaceMasks[0]")] + public int FiltRaceMasks0 { get; set; } + [Name("FiltRaceMasks[1]")] + public int FiltRaceMasks1 { get; set; } + + public long FiltRaces => + (FiltRaceMasks0 > 0 || FiltRaceMasks1 > 0) ? (FiltRaceMasks0 & ((long)FiltRaceMasks1 << 32)) : -1; + [Name("QuestTitle_lang")] public string Title { get; set; } = string.Empty; } diff --git a/apps/tool/Tools/JournalTool.cs b/apps/tool/Tools/JournalTool.cs index 0c35ceafc..18677add9 100644 --- a/apps/tool/Tools/JournalTool.cs +++ b/apps/tool/Tools/JournalTool.cs @@ -253,6 +253,7 @@ await context.WowMount await context.WowPet .AsNoTracking() .Where(pet => pet.ItemIds.Count > 0 && (pet.Flags & 32) == 0) + .Where(pet => pet.Id != 5073) // FIXME dupe in data? .ToArrayAsync() ) .ToManyDictionary(pet => pet.ItemIds, pet => pet); diff --git a/apps/web/Converters/ApiUserCharacterConverter.cs b/apps/web/Converters/ApiUserCharacterConverter.cs index 64bb630e8..d134a48d7 100644 --- a/apps/web/Converters/ApiUserCharacterConverter.cs +++ b/apps/web/Converters/ApiUserCharacterConverter.cs @@ -33,43 +33,44 @@ public override void Write(Utf8JsonWriter writer, ApiUserCharacter character, Js writer.WriteNumberValue(character.RealmId); writer.WriteNumberValue(character.RestedExperience); writer.WriteNumberValue(character.Gold); + writer.WriteNumberValue(character.BankTabs); writer.WriteStringValue(character.CurrentLocation); writer.WriteStringValue(character.HearthLocation); - writer.WriteNumberValue(character.LastApiModified.ToUnixTimeSeconds()); // 21 - writer.WriteNumberValue(character.LastSeenAddon.ToUnixTimeSeconds()); // 22 - writer.WriteNumberValue(character.DailyReset?.ToUnixTimeSeconds() ?? 0); // 23 - writer.WriteNumberValue(character.WeeklyReset?.ToUnixTimeSeconds() ?? 0); // 24 - writer.WriteNumberValue(character.ScannedCurrencies?.ToUnixTimeSeconds() ?? 0); // 25 - writer.WriteNumberValue(character.TransferredCurrencies?.ToUnixTimeSeconds() ?? 0); // 26 + writer.WriteNumberValue(character.LastApiModified.ToUnixTimeSeconds()); // 22 + writer.WriteNumberValue(character.LastSeenAddon.ToUnixTimeSeconds()); // 23 + writer.WriteNumberValue(character.DailyReset?.ToUnixTimeSeconds() ?? 0); // 24 + writer.WriteNumberValue(character.WeeklyReset?.ToUnixTimeSeconds() ?? 0); // 25 + writer.WriteNumberValue(character.ScannedCurrencies?.ToUnixTimeSeconds() ?? 0); // 26 + writer.WriteNumberValue(character.TransferredCurrencies?.ToUnixTimeSeconds() ?? 0); // 27 - JsonSerializer.Serialize(writer, character.Configuration, options); // 27 + JsonSerializer.Serialize(writer, character.Configuration, options); // 28 - JsonSerializer.Serialize(writer, character.Auras, options); // 28 - JsonSerializer.Serialize(writer, character.EquippedItems, options); // 29 - JsonSerializer.Serialize(writer, character.Garrisons, options); // 30 - JsonSerializer.Serialize(writer, character.GarrisonTrees, options); // 31 - JsonSerializer.Serialize(writer, character.HighestItemLevel, options); // 32 - JsonSerializer.Serialize(writer, character.KnownSpells, options); // 33 - JsonSerializer.Serialize(writer, character.Lockouts, options); // 34 - JsonSerializer.Serialize(writer, character.MythicPlus, options); // 35 - JsonSerializer.Serialize(writer, character.MythicPlusAddon, options); // 36 - JsonSerializer.Serialize(writer, character.MythicPlusSeasons, options); // 37 - JsonSerializer.Serialize(writer, character.Paragons, options); // 38 - JsonSerializer.Serialize(writer, character.PatronOrders, options); // 39 - JsonSerializer.Serialize(writer, character.Professions, options); // 40 - JsonSerializer.Serialize(writer, character.ProfessionCooldowns, options); // 41 - JsonSerializer.Serialize(writer, character.ProfessionSpecializations, options); // 42 - JsonSerializer.Serialize(writer, character.ProfessionTraits, options); // 43 - JsonSerializer.Serialize(writer, character.RaiderIo, options); // 44 - JsonSerializer.Serialize(writer, character.Reputations, options); // 45 - JsonSerializer.Serialize(writer, character.Shadowlands, options); // 46 - JsonSerializer.Serialize(writer, character.Weekly, options); // 47 + JsonSerializer.Serialize(writer, character.Auras, options); // 29 + JsonSerializer.Serialize(writer, character.EquippedItems, options); // 30 + JsonSerializer.Serialize(writer, character.Garrisons, options); // 31 + JsonSerializer.Serialize(writer, character.GarrisonTrees, options); // 32 + JsonSerializer.Serialize(writer, character.HighestItemLevel, options); // 33 + JsonSerializer.Serialize(writer, character.KnownSpells, options); // 34 + JsonSerializer.Serialize(writer, character.Lockouts, options); // 35 + JsonSerializer.Serialize(writer, character.MythicPlus, options); // 36 + JsonSerializer.Serialize(writer, character.MythicPlusAddon, options); // 37 + JsonSerializer.Serialize(writer, character.MythicPlusSeasons, options); // 38 + JsonSerializer.Serialize(writer, character.Paragons, options); // 39 + JsonSerializer.Serialize(writer, character.PatronOrders, options); // 40 + JsonSerializer.Serialize(writer, character.Professions, options); // 41 + JsonSerializer.Serialize(writer, character.ProfessionCooldowns, options); // 42 + JsonSerializer.Serialize(writer, character.ProfessionSpecializations, options); // 43 + JsonSerializer.Serialize(writer, character.ProfessionTraits, options); // 44 + JsonSerializer.Serialize(writer, character.RaiderIo, options); // 45 + JsonSerializer.Serialize(writer, character.Reputations, options); // 46 + JsonSerializer.Serialize(writer, character.Shadowlands, options); // 47 + JsonSerializer.Serialize(writer, character.Weekly, options); // 48 - JsonSerializer.Serialize(writer, character.RawCurrencies, options); // 48 - JsonSerializer.Serialize(writer, character.RawItems, options); // 49 - JsonSerializer.Serialize(writer, character.RawMythicPlusWeeks, options); // 50 - JsonSerializer.Serialize(writer, character.RawSpecializations, options); // 51 - JsonSerializer.Serialize(writer, character.RawStatistics, options); // 52 + JsonSerializer.Serialize(writer, character.RawCurrencies, options); // 49 + JsonSerializer.Serialize(writer, character.RawItems, options); // 50 + JsonSerializer.Serialize(writer, character.RawMythicPlusWeeks, options); // 51 + JsonSerializer.Serialize(writer, character.RawSpecializations, options); // 52 + JsonSerializer.Serialize(writer, character.RawStatistics, options); // 53 writer.WriteEndArray(); } diff --git a/apps/web/Models/Api/User/ApiUserCharacter.cs b/apps/web/Models/Api/User/ApiUserCharacter.cs index 493e3924f..25cdb26f5 100644 --- a/apps/web/Models/Api/User/ApiUserCharacter.cs +++ b/apps/web/Models/Api/User/ApiUserCharacter.cs @@ -25,6 +25,7 @@ public class ApiUserCharacter public int RealmId { get; set; } public int RestedExperience { get; set; } public long Gold { get; } + public short BankTabs { get; set; } public string CurrentLocation { get; set; } public string HearthLocation { get; set; } public string Name { get; set; } @@ -121,6 +122,7 @@ public ApiUserCharacter( } Auras = character.AddonData?.Auras; + BankTabs = character.AddonData?.BankTabs ?? 0; Garrisons = character.AddonData?.Garrisons; GarrisonTrees = character.AddonData?.GarrisonTrees; HighestItemLevel = character.AddonData?.HighestItemLevel; diff --git a/apps/web/Startup.cs b/apps/web/Startup.cs index 9f1042102..dc568f4d8 100644 --- a/apps/web/Startup.cs +++ b/apps/web/Startup.cs @@ -16,6 +16,7 @@ using Wowthing.Lib.Services; using Wowthing.Web.Hubs; using Wowthing.Web.Models; +using IPNetwork = System.Net.IPNetwork; namespace Wowthing.Web; @@ -128,9 +129,9 @@ public void ConfigureServices(IServiceCollection services) services.Configure(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; - options.KnownNetworks.Add(new Microsoft.AspNetCore.HttpOverrides.IPNetwork(IPAddress.Parse("10.0.0.0"), 8)); - options.KnownNetworks.Add(new Microsoft.AspNetCore.HttpOverrides.IPNetwork(IPAddress.Parse("172.16.0.0"), 12)); - options.KnownNetworks.Add(new Microsoft.AspNetCore.HttpOverrides.IPNetwork(IPAddress.Parse("192.168.0.0"), 16)); + options.KnownIPNetworks.Add(new IPNetwork(IPAddress.Parse("10.0.0.0"), 8)); + options.KnownIPNetworks.Add(new IPNetwork(IPAddress.Parse("172.16.0.0"), 12)); + options.KnownIPNetworks.Add(new IPNetwork(IPAddress.Parse("192.168.0.0"), 16)); //options.ForwardedForHeaderName = "CF-Connecting-IP"; }); } diff --git a/packages/csharp-lib/Contexts/WowDbContext.cs b/packages/csharp-lib/Contexts/WowDbContext.cs index ba1c4fb68..487a1309a 100644 --- a/packages/csharp-lib/Contexts/WowDbContext.cs +++ b/packages/csharp-lib/Contexts/WowDbContext.cs @@ -112,6 +112,8 @@ public class WowDbContext : IdentityDbContext UserGoldSnapshot { get; set; } public DbSet UserLeaderboardSnapshot { get; set; } + public DbSet MiscAggregate { get; set; } + public DbSet MiscReport { get; set; } public DbSet WorldQuestAggregate { get; set; } public DbSet WorldQuestReport { get; set; } @@ -178,6 +180,9 @@ protected override void OnModelCreating(ModelBuilder builder) builder.Entity() .HasKey(gd => new { gd.Expansion, gd.Region }); + builder.Entity() + .HasKey(ma => new { ma.Region, ma.ReportType }); + builder.Entity() .HasKey(mps => new { mps.CharacterId, mps.Season }); diff --git a/packages/csharp-lib/Enums/MiscReportType.cs b/packages/csharp-lib/Enums/MiscReportType.cs new file mode 100644 index 000000000..c50fb13a8 --- /dev/null +++ b/packages/csharp-lib/Enums/MiscReportType.cs @@ -0,0 +1,6 @@ +namespace Wowthing.Lib.Enums; + +public enum MiscReportType : short +{ + Delve = 1, +} diff --git a/packages/csharp-lib/Jobs/JobType.cs b/packages/csharp-lib/Jobs/JobType.cs index 5ca92c37c..abb8796a5 100644 --- a/packages/csharp-lib/Jobs/JobType.cs +++ b/packages/csharp-lib/Jobs/JobType.cs @@ -50,6 +50,7 @@ public enum JobType : short DataQuest = 1022, MagicAggregateWorldQuests = 1100, + MagicAggregateMiscReports = 1101, MaintenanceUnlinkCharacters = 2000, // MaintenanceDeleteAchievements = 2001, @@ -58,4 +59,5 @@ public enum JobType : short MaintenanceBackfillUserCache = 2004, MaintenanceDeleteCharacters = 2005, MaintenanceAggregateHourlyAuctionData = 2006, + MaintenanceDeleteMiscReports = 2007, } diff --git a/packages/csharp-lib/Migrations/20260613004146_Add_PlayerCharacterAddonData_BankTabs.Designer.cs b/packages/csharp-lib/Migrations/20260613004146_Add_PlayerCharacterAddonData_BankTabs.Designer.cs new file mode 100644 index 000000000..ce7e773f4 --- /dev/null +++ b/packages/csharp-lib/Migrations/20260613004146_Add_PlayerCharacterAddonData_BankTabs.Designer.cs @@ -0,0 +1,4439 @@ +// +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("20260613004146_Add_PlayerCharacterAddonData_BankTabs")] + partial class Add_PlayerCharacterAddonData_BankTabs + { + /// + 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.Player.PlayerAccount", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("bigint") + .HasColumnName("account_id"); + + b.Property("Enabled") + .HasColumnType("boolean") + .HasColumnName("enabled"); + + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.Property("Tag") + .HasColumnType("text") + .HasColumnName("tag"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_player_account"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_player_account_user_id"); + + b.HasIndex("Region", "AccountId") + .IsUnique() + .HasDatabaseName("ix_player_account_region_account_id"); + + b.ToTable("player_account", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountAddonData", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property>>("Decor") + .HasColumnType("jsonb") + .HasColumnName("decor"); + + b.Property("DecorScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("decor_scanned_at"); + + b.Property>("Heirlooms") + .HasColumnType("jsonb") + .HasColumnName("heirlooms"); + + b.Property("HonorCurrent") + .HasColumnType("smallint") + .HasColumnName("honor_current"); + + b.Property("HonorLevel") + .HasColumnType("smallint") + .HasColumnName("honor_level"); + + b.Property("HonorMax") + .HasColumnType("smallint") + .HasColumnName("honor_max"); + + b.PrimitiveCollection>("Illusions") + .HasColumnType("integer[]") + .HasColumnName("illusions"); + + b.PrimitiveCollection>("Quests") + .HasColumnType("integer[]") + .HasColumnName("quests"); + + b.Property>("Reputations") + .HasColumnType("jsonb") + .HasColumnName("reputations"); + + b.Property("ReputationsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("reputations_scanned_at"); + + b.HasKey("AccountId") + .HasName("pk_player_account_addon_data"); + + b.ToTable("player_account_addon_data", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountGoldSnapshot", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property("Gold") + .HasColumnType("integer") + .HasColumnName("gold"); + + b.Property("RealmId") + .HasColumnType("integer") + .HasColumnName("realm_id"); + + b.Property("Time") + .HasColumnType("timestamp with time zone") + .HasColumnName("time"); + + b.HasKey("Id") + .HasName("pk_player_account_gold_snapshot"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_player_account_gold_snapshot_account_id"); + + b.ToTable("player_account_gold_snapshot", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountHeirlooms", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property>("Heirlooms") + .HasColumnType("jsonb") + .HasColumnName("heirlooms"); + + b.HasKey("AccountId") + .HasName("pk_player_account_heirlooms"); + + b.ToTable("player_account_heirlooms", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountMounts", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.PrimitiveCollection>("MountIds") + .HasColumnType("integer[]") + .HasColumnName("mount_ids"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("AccountId") + .HasName("pk_player_account_mounts"); + + b.ToTable("player_account_mounts", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountPets", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property>("Pets") + .HasColumnType("jsonb") + .HasColumnName("pets"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("AccountId") + .HasName("pk_player_account_pets"); + + b.ToTable("player_account_pets", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountToys", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.PrimitiveCollection>("ToyIds") + .HasColumnType("integer[]") + .HasColumnName("toy_ids"); + + b.HasKey("AccountId") + .HasName("pk_player_account_toys"); + + b.ToTable("player_account_toys", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountTransmogIds", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.PrimitiveCollection>("Ids") + .HasColumnType("integer[]") + .HasColumnName("ids"); + + b.HasKey("AccountId") + .HasName("pk_player_account_transmog_ids"); + + b.ToTable("player_account_transmog_ids", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountTransmogSources", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.PrimitiveCollection>("Sources") + .HasColumnType("text[]") + .HasColumnName("sources"); + + b.HasKey("AccountId") + .HasName("pk_player_account_transmog_sources"); + + b.ToTable("player_account_transmog_sources", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacter", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property("ActiveSpecId") + .HasColumnType("integer") + .HasColumnName("active_spec_id"); + + b.Property("ActiveTitleId") + .HasColumnType("integer") + .HasColumnName("active_title_id"); + + b.Property("AverageItemLevel") + .HasColumnType("integer") + .HasColumnName("average_item_level"); + + b.Property("CharacterId") + .HasColumnType("bigint") + .HasColumnName("character_id"); + + b.Property("ChromieTime") + .HasColumnType("integer") + .HasColumnName("chromie_time"); + + b.Property("ClassId") + .HasColumnType("integer") + .HasColumnName("class_id"); + + b.Property("Copper") + .HasColumnType("bigint") + .HasColumnName("copper"); + + b.Property("EquippedItemLevel") + .HasColumnType("integer") + .HasColumnName("equipped_item_level"); + + b.Property("Experience") + .HasColumnType("integer") + .HasColumnName("experience"); + + b.Property("Faction") + .HasColumnType("smallint") + .HasColumnName("faction"); + + b.Property("Gender") + .HasColumnType("integer") + .HasColumnName("gender"); + + b.Property("GuildId") + .HasColumnType("integer") + .HasColumnName("guild_id"); + + b.Property("IsResting") + .HasColumnType("boolean") + .HasColumnName("is_resting"); + + b.Property("IsWarMode") + .HasColumnType("boolean") + .HasColumnName("is_war_mode"); + + b.Property("LastApiCheck") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_api_check"); + + b.Property("LastApiModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_api_modified"); + + b.Property("LastSeenAddon") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_seen_addon"); + + b.Property("Level") + .HasColumnType("integer") + .HasColumnName("level"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("PlayedTotal") + .HasColumnType("integer") + .HasColumnName("played_total"); + + b.Property("RaceId") + .HasColumnType("integer") + .HasColumnName("race_id"); + + b.Property("RealmId") + .HasColumnType("integer") + .HasColumnName("realm_id"); + + b.Property("RestedExperience") + .HasColumnType("integer") + .HasColumnName("rested_experience"); + + b.Property("ShouldUpdate") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(true) + .HasColumnName("should_update"); + + b.HasKey("Id") + .HasName("pk_player_character"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_player_character_account_id"); + + b.HasIndex("GuildId") + .HasDatabaseName("ix_player_character_guild_id"); + + b.HasIndex("LastApiCheck") + .HasDatabaseName("ix_player_character_last_api_check") + .HasFilter("should_update = true AND account_id IS NOT NULL"); + + NpgsqlIndexBuilderExtensions.IncludeProperties(b.HasIndex("LastApiCheck"), new[] { "Id", "AccountId", "Name", "LastApiModified" }); + + b.HasIndex("CharacterId", "LastSeenAddon") + .HasDatabaseName("ix_player_character_character_id_last_seen_addon") + .HasFilter("account_id IS NOT NULL"); + + b.HasIndex("RealmId", "Name") + .IsUnique() + .HasDatabaseName("ix_player_character_realm_id_name"); + + b.ToTable("player_character", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAchievements", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("AchievementIds") + .HasColumnType("integer[]") + .HasColumnName("achievement_ids"); + + b.PrimitiveCollection>("AchievementTimestamps") + .HasColumnType("integer[]") + .HasColumnName("achievement_timestamps"); + + b.PrimitiveCollection>("CriteriaAmounts") + .HasColumnType("bigint[]") + .HasColumnName("criteria_amounts"); + + b.PrimitiveCollection>("CriteriaCompleted") + .HasColumnType("boolean[]") + .HasColumnName("criteria_completed"); + + b.PrimitiveCollection>("CriteriaIds") + .HasColumnType("integer[]") + .HasColumnName("criteria_ids"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_achievements"); + + b.ToTable("player_character_achievements", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonAchievements", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("Achievements") + .HasColumnType("jsonb") + .HasColumnName("achievements"); + + b.Property("ScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("scanned_at"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_addon_achievements"); + + b.ToTable("player_character_addon_achievements", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonData", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("Auras") + .HasColumnType("jsonb") + .HasColumnName("auras"); + + b.Property("BagsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("bags_scanned_at"); + + b.Property("BankScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("bank_scanned_at"); + + b.Property("BankTabs") + .HasColumnType("smallint") + .HasColumnName("bank_tabs"); + + b.Property("BindLocation") + .HasColumnType("text") + .HasColumnName("bind_location"); + + b.Property>("Currencies") + .HasColumnType("jsonb") + .HasColumnName("currencies"); + + b.Property("CurrenciesScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("currencies_scanned_at"); + + b.Property("CurrenciesTransferredAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("currencies_transferred_at"); + + b.Property("CurrentLocation") + .HasColumnType("text") + .HasColumnName("current_location"); + + b.Property("DailyReset") + .HasColumnType("timestamp with time zone") + .HasColumnName("daily_reset"); + + b.Property>("EquippedItems") + .HasColumnType("jsonb") + .HasColumnName("equipped_items"); + + b.Property>>>("GarrisonTrees") + .HasColumnType("jsonb") + .HasColumnName("garrison_trees"); + + b.Property("GarrisonTreesScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("garrison_trees_scanned_at"); + + b.Property>("Garrisons") + .HasColumnType("jsonb") + .HasColumnName("garrisons"); + + b.Property>("HighestItemLevel") + .HasColumnType("jsonb") + .HasColumnName("highest_item_level"); + + b.PrimitiveCollection>("KnownSpells") + .HasColumnType("integer[]") + .HasColumnName("known_spells"); + + b.Property("Level") + .HasColumnType("smallint") + .HasColumnName("level"); + + b.Property("LevelXp") + .HasColumnType("integer") + .HasColumnName("level_xp"); + + b.Property>("MythicPlus") + .HasColumnType("jsonb") + .HasColumnName("mythic_plus"); + + b.Property("MythicPlusScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("mythic_plus_scanned_at"); + + b.Property>>("MythicPlusSeasons") + .HasColumnType("jsonb") + .HasColumnName("mythic_plus_seasons"); + + b.Property>>("MythicPlusWeeks") + .HasColumnType("jsonb") + .HasColumnName("mythic_plus_weeks"); + + b.Property>("Paragons") + .HasColumnType("jsonb") + .HasColumnName("paragons"); + + b.Property>>("PatronOrders") + .HasColumnType("jsonb") + .HasColumnName("patron_orders"); + + b.Property("PatronOrdersScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("patron_orders_scanned_at"); + + b.Property>>("ProfessionCooldowns") + .HasColumnType("jsonb") + .HasColumnName("profession_cooldowns"); + + b.Property>>("ProfessionTraits") + .HasColumnType("jsonb") + .HasColumnName("profession_traits"); + + b.Property>("Professions") + .HasColumnType("jsonb") + .HasColumnName("professions"); + + b.Property>("Reputations") + .HasColumnType("jsonb") + .HasColumnName("reputations"); + + b.Property("ReputationsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("reputations_scanned_at"); + + b.Property("WeeklyReset") + .HasColumnType("timestamp with time zone") + .HasColumnName("weekly_reset"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_addon_data"); + + b.ToTable("player_character_addon_data", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonMounts", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("Mounts") + .HasColumnType("integer[]") + .HasColumnName("mounts"); + + b.Property("ScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("scanned_at"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_addon_mounts"); + + b.ToTable("player_character_addon_mounts", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonQuests", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("CallingsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("callings_scanned_at"); + + b.PrimitiveCollection>("CompletedQuests") + .HasColumnType("integer[]") + .HasColumnName("completed_quests"); + + b.Property("CompletedQuestsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("completed_quests_scanned_at"); + + b.Property>>>("Dailies") + .HasColumnType("jsonb") + .HasColumnName("dailies"); + + b.PrimitiveCollection>("DailyQuests") + .HasColumnType("integer[]") + .HasColumnName("daily_quests"); + + b.Property>>("GoldWorldQuests") + .HasColumnType("jsonb") + .HasColumnName("gold_world_quests"); + + b.PrimitiveCollection>("OtherQuests") + .HasColumnType("integer[]") + .HasColumnName("other_quests"); + + b.Property>("ProgressQuests") + .HasColumnType("jsonb") + .HasColumnName("progress_quests"); + + b.Property("QuestsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("quests_scanned_at"); + + b.Property("WorldQuestsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("world_quests_scanned_at"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_addon_quests"); + + b.ToTable("player_character_addon_quests", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterConfiguration", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("BackgroundBrightness") + .HasColumnType("smallint") + .HasColumnName("background_brightness"); + + b.Property("BackgroundId") + .HasColumnType("smallint") + .HasColumnName("background_id"); + + b.Property("BackgroundSaturation") + .HasColumnType("smallint") + .HasColumnName("background_saturation"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_configuration"); + + b.ToTable("player_character_configuration", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterEquippedItems", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("Items") + .HasColumnType("jsonb") + .HasColumnName("items"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_equipped_items"); + + b.ToTable("player_character_equipped_items", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BindType") + .HasColumnType("smallint") + .HasColumnName("bind_type"); + + b.PrimitiveCollection>("BonusIds") + .HasColumnType("smallint[]") + .HasColumnName("bonus_ids"); + + b.Property("Bound") + .HasColumnType("boolean") + .HasColumnName("bound"); + + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("ContainerId") + .HasColumnType("smallint") + .HasColumnName("container_id"); + + b.Property("Context") + .HasColumnType("smallint") + .HasColumnName("context"); + + b.Property("Count") + .HasColumnType("integer") + .HasColumnName("count"); + + b.Property("CraftedQuality") + .HasColumnType("smallint") + .HasColumnName("crafted_quality"); + + b.Property("EnchantId") + .HasColumnType("smallint") + .HasColumnName("enchant_id"); + + b.PrimitiveCollection>("Gems") + .HasColumnType("integer[]") + .HasColumnName("gems"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("ItemLevel") + .HasColumnType("smallint") + .HasColumnName("item_level"); + + b.Property("Location") + .HasColumnType("smallint") + .HasColumnName("location"); + + b.Property>("Modifiers") + .HasColumnType("jsonb") + .HasColumnName("modifiers"); + + b.Property("Quality") + .HasColumnType("smallint") + .HasColumnName("quality"); + + b.Property("Slot") + .HasColumnType("smallint") + .HasColumnName("slot"); + + b.Property("SuffixId") + .HasColumnType("smallint") + .HasColumnName("suffix_id"); + + b.HasKey("Id") + .HasName("pk_player_character_item"); + + b.HasIndex("CharacterId", "Slot") + .HasDatabaseName("ix_player_character_item_character_id_slot"); + + b.HasIndex("CharacterId", "ItemId", "Location") + .HasDatabaseName("ix_player_character_item_character_id_item_id_location"); + + b.ToTable("player_character_item", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterLockouts", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("LastUpdated") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_updated"); + + b.Property>("Lockouts") + .HasColumnType("jsonb") + .HasColumnName("lockouts"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_lockouts"); + + b.ToTable("player_character_lockouts", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMedia", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("AvatarUrl") + .HasColumnType("text") + .HasColumnName("avatar_url"); + + b.Property("InsetUrl") + .HasColumnType("text") + .HasColumnName("inset_url"); + + b.Property("MainRawUrl") + .HasColumnType("text") + .HasColumnName("main_raw_url"); + + b.Property("MainUrl") + .HasColumnType("text") + .HasColumnName("main_url"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_media"); + + b.ToTable("player_character_media", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMounts", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("Mounts") + .HasColumnType("integer[]") + .HasColumnName("mounts"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_mounts"); + + b.ToTable("player_character_mounts", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlus", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("CurrentPeriodId") + .HasColumnType("integer") + .HasColumnName("current_period_id"); + + b.Property>("PeriodRuns") + .HasColumnType("jsonb") + .HasColumnName("period_runs"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_mythic_plus"); + + b.ToTable("player_character_mythic_plus", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlusAddon", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("Maps") + .HasColumnType("jsonb") + .HasColumnName("maps"); + + b.Property("Season") + .HasColumnType("integer") + .HasColumnName("season"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_mythic_plus_addon"); + + b.ToTable("player_character_mythic_plus_addon", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlusSeason", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("Season") + .HasColumnType("integer") + .HasColumnName("season"); + + b.Property("Rating") + .HasColumnType("double precision") + .HasColumnName("rating"); + + b.Property>("Runs") + .HasColumnType("jsonb") + .HasColumnName("runs"); + + b.HasKey("CharacterId", "Season") + .HasName("pk_player_character_mythic_plus_season"); + + b.ToTable("player_character_mythic_plus_season", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterProfessions", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("ProfessionSpecializations") + .HasColumnType("jsonb") + .HasColumnName("profession_specializations"); + + b.Property>>("Professions") + .HasColumnType("jsonb") + .HasColumnName("professions"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_professions"); + + b.ToTable("player_character_professions", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterQuests", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("CompletedIds") + .HasColumnType("integer[]") + .HasColumnName("completed_ids"); + + b.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.Player.PlayerAccount", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .HasConstraintName("fk_player_account_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountAddonData", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("AddonData") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountAddonData", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_addon_data_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountGoldSnapshot", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithMany() + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_gold_snapshot_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountHeirlooms", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("Heirlooms") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountHeirlooms", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_heirlooms_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountMounts", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("Mounts") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountMounts", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_mounts_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountPets", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("Pets") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountPets", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_pets_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountToys", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("Toys") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountToys", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_toys_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountTransmogIds", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("TransmogIds") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountTransmogIds", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_transmog_ids_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountTransmogSources", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("TransmogSources") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountTransmogSources", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_transmog_sources_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacter", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithMany("Characters") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("fk_player_character_player_account_account_id"); + + b.HasOne("Wowthing.Lib.Models.Player.PlayerGuild", "Guild") + .WithMany() + .HasForeignKey("GuildId") + .HasConstraintName("fk_player_character_player_guild_guild_id"); + + b.Navigation("Account"); + + b.Navigation("Guild"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAchievements", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Achievements") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterAchievements", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_achievements_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonAchievements", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("AddonAchievements") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterAddonAchievements", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_addon_achievements_player_character_charac"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonData", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("AddonData") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterAddonData", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_addon_data_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonMounts", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("AddonMounts") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterAddonMounts", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_addon_mounts_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonQuests", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("AddonQuests") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterAddonQuests", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_addon_quests_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterConfiguration", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Configuration") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterConfiguration", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_configuration_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterEquippedItems", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("EquippedItems") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterEquippedItems", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_equipped_items_player_character_character_"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterItem", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithMany("Items") + .HasForeignKey("CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_item_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterLockouts", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Lockouts") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterLockouts", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_lockouts_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMedia", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Media") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterMedia", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_media_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMounts", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Mounts") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterMounts", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_mounts_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlus", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("MythicPlus") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlus", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_mythic_plus_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlusAddon", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("MythicPlusAddon") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlusAddon", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_mythic_plus_addon_player_character_charact"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlusSeason", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithMany("MythicPlusSeasons") + .HasForeignKey("CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_mythic_plus_season_player_character_charac"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterProfessions", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Professions") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterProfessions", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_professions_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterQuests", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Quests") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterQuests", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_quests_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterRaiderIo", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("RaiderIo") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterRaiderIo", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_raider_io_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterReputations", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Reputations") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterReputations", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_reputations_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterShadowlands", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Shadowlands") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterShadowlands", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_shadowlands_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterSpecializations", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Specializations") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterSpecializations", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_specializations_player_character_character"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterStatistics", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithMany() + .HasForeignKey("CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_statistics_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterStats", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Stats") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterStats", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_stats_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterTransmog", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Transmog") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterTransmog", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_transmog_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterWeekly", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Weekly") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterWeekly", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_weekly_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerGuild", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_guild_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerGuildItem", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerGuild", "Guild") + .WithMany("Items") + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_guild_item_player_guild_guild_id"); + + b.Navigation("Guild"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerWarbankItem", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_warbank_item_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Team.Team", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_team_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Team.TeamCharacter", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithMany() + .HasForeignKey("CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_team_character_player_character_character_id"); + + b.HasOne("Wowthing.Lib.Models.Team.Team", "Team") + .WithMany("Characters") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_team_character_team_team_id"); + + b.Navigation("Character"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserAddonData", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_addon_data_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserBulkData", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_bulk_data_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserCache", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_cache_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserGoldSnapshot", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .HasConstraintName("fk_user_gold_snapshot_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserLeaderboardSnapshot", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_leaderboard_snapshot_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.WorldQuestReport", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_world_quest_report_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccount", b => + { + b.Navigation("AddonData"); + + b.Navigation("Characters"); + + b.Navigation("Heirlooms"); + + b.Navigation("Mounts"); + + b.Navigation("Pets"); + + b.Navigation("Toys"); + + b.Navigation("TransmogIds"); + + b.Navigation("TransmogSources"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacter", b => + { + b.Navigation("Achievements"); + + b.Navigation("AddonAchievements"); + + b.Navigation("AddonData"); + + b.Navigation("AddonMounts"); + + b.Navigation("AddonQuests"); + + b.Navigation("Configuration"); + + b.Navigation("EquippedItems"); + + b.Navigation("Items"); + + b.Navigation("Lockouts"); + + b.Navigation("Media"); + + b.Navigation("Mounts"); + + b.Navigation("MythicPlus"); + + b.Navigation("MythicPlusAddon"); + + b.Navigation("MythicPlusSeasons"); + + b.Navigation("Professions"); + + b.Navigation("Quests"); + + b.Navigation("RaiderIo"); + + b.Navigation("Reputations"); + + b.Navigation("Shadowlands"); + + b.Navigation("Specializations"); + + b.Navigation("Stats"); + + b.Navigation("Transmog"); + + b.Navigation("Weekly"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerGuild", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Team.Team", b => + { + b.Navigation("Characters"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/packages/csharp-lib/Migrations/20260613004146_Add_PlayerCharacterAddonData_BankTabs.cs b/packages/csharp-lib/Migrations/20260613004146_Add_PlayerCharacterAddonData_BankTabs.cs new file mode 100644 index 000000000..fcefda45d --- /dev/null +++ b/packages/csharp-lib/Migrations/20260613004146_Add_PlayerCharacterAddonData_BankTabs.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Wowthing.Lib.Migrations +{ + /// + public partial class Add_PlayerCharacterAddonData_BankTabs : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "bank_tabs", + table: "player_character_addon_data", + type: "smallint", + nullable: false, + defaultValue: (short)0); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "bank_tabs", + table: "player_character_addon_data"); + } + } +} diff --git a/packages/csharp-lib/Migrations/20260614010028_Add_MiscAggregate_MiscReport.Designer.cs b/packages/csharp-lib/Migrations/20260614010028_Add_MiscAggregate_MiscReport.Designer.cs new file mode 100644 index 000000000..1a89cd57d --- /dev/null +++ b/packages/csharp-lib/Migrations/20260614010028_Add_MiscAggregate_MiscReport.Designer.cs @@ -0,0 +1,4518 @@ +// +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("20260614010028_Add_MiscAggregate_MiscReport")] + partial class Add_MiscAggregate_MiscReport + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text") + .HasColumnName("concurrency_stamp"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("name"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("normalized_name"); + + b.HasKey("Id") + .HasName("pk_asp_net_roles"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("asp_net_roles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text") + .HasColumnName("claim_type"); + + b.Property("ClaimValue") + .HasColumnType("text") + .HasColumnName("claim_value"); + + b.Property("RoleId") + .HasColumnType("bigint") + .HasColumnName("role_id"); + + b.HasKey("Id") + .HasName("pk_asp_net_role_claims"); + + b.HasIndex("RoleId") + .HasDatabaseName("ix_asp_net_role_claims_role_id"); + + b.ToTable("asp_net_role_claims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text") + .HasColumnName("claim_type"); + + b.Property("ClaimValue") + .HasColumnType("text") + .HasColumnName("claim_value"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_asp_net_user_claims"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_asp_net_user_claims_user_id"); + + b.ToTable("asp_net_user_claims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("text") + .HasColumnName("login_provider"); + + b.Property("ProviderKey") + .HasColumnType("text") + .HasColumnName("provider_key"); + + b.Property("ProviderDisplayName") + .HasColumnType("text") + .HasColumnName("provider_display_name"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("LoginProvider", "ProviderKey") + .HasName("pk_asp_net_user_logins"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_asp_net_user_logins_user_id"); + + b.ToTable("asp_net_user_logins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.Property("RoleId") + .HasColumnType("bigint") + .HasColumnName("role_id"); + + b.HasKey("UserId", "RoleId") + .HasName("pk_asp_net_user_roles"); + + b.HasIndex("RoleId") + .HasDatabaseName("ix_asp_net_user_roles_role_id"); + + b.ToTable("asp_net_user_roles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.Property("LoginProvider") + .HasColumnType("text") + .HasColumnName("login_provider"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("Value") + .HasColumnType("text") + .HasColumnName("value"); + + b.HasKey("UserId", "LoginProvider", "Name") + .HasName("pk_asp_net_user_tokens"); + + b.ToTable("asp_net_user_tokens", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.ApplicationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessFailedCount") + .HasColumnType("integer") + .HasColumnName("access_failed_count"); + + b.Property("ApiKey") + .HasColumnType("text") + .HasColumnName("api_key"); + + b.Property("CanUseSubdomain") + .HasColumnType("boolean") + .HasColumnName("can_use_subdomain"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text") + .HasColumnName("concurrency_stamp"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("email"); + + b.Property("EmailConfirmed") + .HasColumnType("boolean") + .HasColumnName("email_confirmed"); + + b.Property("LastApiCheck") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_api_check"); + + b.Property("LastVisit") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_visit"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean") + .HasColumnName("lockout_enabled"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone") + .HasColumnName("lockout_end"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("normalized_email"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("normalized_user_name"); + + b.Property("PasswordHash") + .HasColumnType("text") + .HasColumnName("password_hash"); + + b.Property("PhoneNumber") + .HasColumnType("text") + .HasColumnName("phone_number"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean") + .HasColumnName("phone_number_confirmed"); + + b.Property("SecurityStamp") + .HasColumnType("text") + .HasColumnName("security_stamp"); + + b.Property("Settings") + .HasColumnType("jsonb") + .HasColumnName("settings"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean") + .HasColumnName("two_factor_enabled"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("user_name"); + + b.HasKey("Id") + .HasName("pk_asp_net_users"); + + b.HasIndex("ApiKey") + .IsUnique() + .HasDatabaseName("ix_asp_net_users_api_key"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("asp_net_users", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Action") + .HasColumnType("text") + .HasColumnName("action"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone") + .HasColumnName("timestamp"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_audit_log"); + + b.ToTable("audit_log", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.BackgroundImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Attribution") + .HasColumnType("text") + .HasColumnName("attribution"); + + b.Property("DefaultBrightness") + .HasColumnType("smallint") + .HasColumnName("default_brightness"); + + b.Property("DefaultSaturate") + .HasColumnType("smallint") + .HasColumnName("default_saturate"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("Filename") + .HasColumnType("text") + .HasColumnName("filename"); + + b.Property("RoleId") + .HasColumnType("bigint") + .HasColumnName("role_id"); + + b.HasKey("Id") + .HasName("pk_background_image"); + + b.HasIndex("RoleId") + .HasDatabaseName("ix_background_image_role_id"); + + b.ToTable("background_image", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Global.GlobalDailies", b => + { + b.Property("Expansion") + .HasColumnType("integer") + .HasColumnName("expansion"); + + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.PrimitiveCollection>("QuestExpires") + .HasColumnType("integer[]") + .HasColumnName("quest_expires"); + + b.PrimitiveCollection>("QuestIds") + .HasColumnType("integer[]") + .HasColumnName("quest_ids"); + + b.Property>("QuestRewards") + .HasColumnType("jsonb") + .HasColumnName("quest_rewards"); + + b.HasKey("Expansion", "Region") + .HasName("pk_global_dailies"); + + b.ToTable("global_dailies", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Image", b => + { + b.Property("Type") + .HasColumnType("integer") + .HasColumnName("type"); + + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Format") + .HasColumnType("smallint") + .HasColumnName("format"); + + b.Property("Data") + .HasColumnType("bytea") + .HasColumnName("data"); + + b.Property("Sha256") + .HasColumnType("char(64)") + .HasColumnName("sha256"); + + b.HasKey("Type", "Id", "Format") + .HasName("pk_image"); + + b.HasIndex("Type", "Sha256", "Format") + .HasDatabaseName("ix_image_type_sha256_format"); + + b.ToTable("image", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.LanguageString", b => + { + b.Property("Language") + .HasColumnType("smallint") + .HasColumnName("language"); + + b.Property("Type") + .HasColumnType("smallint") + .HasColumnName("type"); + + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("String") + .HasColumnType("text") + .HasColumnName("string"); + + b.HasKey("Language", "Type", "Id") + .HasName("pk_language_string"); + + b.HasIndex("String") + .HasDatabaseName("ix_language_string_string"); + + NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("String"), "gin"); + NpgsqlIndexBuilderExtensions.HasOperators(b.HasIndex("String"), new[] { "gin_trgm_ops" }); + + b.HasIndex("Language", "Type", "Id") + .HasDatabaseName("ix_language_string_language_type_id"); + + b.ToTable("language_string", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.MiscAggregate", b => + { + b.Property("Region") + .HasColumnType("smallint") + .HasColumnName("region"); + + b.Property("ReportType") + .HasColumnType("smallint") + .HasColumnName("report_type"); + + b.Property("JsonData") + .HasColumnType("text") + .HasColumnName("json_data"); + + b.HasKey("Region", "ReportType") + .HasName("pk_misc_aggregate"); + + b.ToTable("misc_aggregate", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.MiscReport", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Data") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)") + .HasColumnName("data"); + + b.Property("ExpiresAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("expires_at"); + + b.Property("Region") + .HasColumnType("smallint") + .HasColumnName("region"); + + b.Property("ReportType") + .HasColumnType("smallint") + .HasColumnName("report_type"); + + b.Property("ReportedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("reported_at"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_misc_report"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_misc_report_user_id"); + + b.HasIndex("ReportType", "Region", "ExpiresAt") + .IsDescending(false, false, true) + .HasDatabaseName("ix_misc_report_report_type_region_expires_at"); + + b.ToTable("misc_report", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccount", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("bigint") + .HasColumnName("account_id"); + + b.Property("Enabled") + .HasColumnType("boolean") + .HasColumnName("enabled"); + + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.Property("Tag") + .HasColumnType("text") + .HasColumnName("tag"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_player_account"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_player_account_user_id"); + + b.HasIndex("Region", "AccountId") + .IsUnique() + .HasDatabaseName("ix_player_account_region_account_id"); + + b.ToTable("player_account", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountAddonData", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property>>("Decor") + .HasColumnType("jsonb") + .HasColumnName("decor"); + + b.Property("DecorScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("decor_scanned_at"); + + b.Property>("Heirlooms") + .HasColumnType("jsonb") + .HasColumnName("heirlooms"); + + b.Property("HonorCurrent") + .HasColumnType("smallint") + .HasColumnName("honor_current"); + + b.Property("HonorLevel") + .HasColumnType("smallint") + .HasColumnName("honor_level"); + + b.Property("HonorMax") + .HasColumnType("smallint") + .HasColumnName("honor_max"); + + b.PrimitiveCollection>("Illusions") + .HasColumnType("integer[]") + .HasColumnName("illusions"); + + b.PrimitiveCollection>("Quests") + .HasColumnType("integer[]") + .HasColumnName("quests"); + + b.Property>("Reputations") + .HasColumnType("jsonb") + .HasColumnName("reputations"); + + b.Property("ReputationsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("reputations_scanned_at"); + + b.HasKey("AccountId") + .HasName("pk_player_account_addon_data"); + + b.ToTable("player_account_addon_data", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountGoldSnapshot", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property("Gold") + .HasColumnType("integer") + .HasColumnName("gold"); + + b.Property("RealmId") + .HasColumnType("integer") + .HasColumnName("realm_id"); + + b.Property("Time") + .HasColumnType("timestamp with time zone") + .HasColumnName("time"); + + b.HasKey("Id") + .HasName("pk_player_account_gold_snapshot"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_player_account_gold_snapshot_account_id"); + + b.ToTable("player_account_gold_snapshot", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountHeirlooms", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property>("Heirlooms") + .HasColumnType("jsonb") + .HasColumnName("heirlooms"); + + b.HasKey("AccountId") + .HasName("pk_player_account_heirlooms"); + + b.ToTable("player_account_heirlooms", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountMounts", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.PrimitiveCollection>("MountIds") + .HasColumnType("integer[]") + .HasColumnName("mount_ids"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("AccountId") + .HasName("pk_player_account_mounts"); + + b.ToTable("player_account_mounts", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountPets", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property>("Pets") + .HasColumnType("jsonb") + .HasColumnName("pets"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.HasKey("AccountId") + .HasName("pk_player_account_pets"); + + b.ToTable("player_account_pets", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountToys", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.PrimitiveCollection>("ToyIds") + .HasColumnType("integer[]") + .HasColumnName("toy_ids"); + + b.HasKey("AccountId") + .HasName("pk_player_account_toys"); + + b.ToTable("player_account_toys", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountTransmogIds", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.PrimitiveCollection>("Ids") + .HasColumnType("integer[]") + .HasColumnName("ids"); + + b.HasKey("AccountId") + .HasName("pk_player_account_transmog_ids"); + + b.ToTable("player_account_transmog_ids", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountTransmogSources", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.PrimitiveCollection>("Sources") + .HasColumnType("text[]") + .HasColumnName("sources"); + + b.HasKey("AccountId") + .HasName("pk_player_account_transmog_sources"); + + b.ToTable("player_account_transmog_sources", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacter", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property("ActiveSpecId") + .HasColumnType("integer") + .HasColumnName("active_spec_id"); + + b.Property("ActiveTitleId") + .HasColumnType("integer") + .HasColumnName("active_title_id"); + + b.Property("AverageItemLevel") + .HasColumnType("integer") + .HasColumnName("average_item_level"); + + b.Property("CharacterId") + .HasColumnType("bigint") + .HasColumnName("character_id"); + + b.Property("ChromieTime") + .HasColumnType("integer") + .HasColumnName("chromie_time"); + + b.Property("ClassId") + .HasColumnType("integer") + .HasColumnName("class_id"); + + b.Property("Copper") + .HasColumnType("bigint") + .HasColumnName("copper"); + + b.Property("EquippedItemLevel") + .HasColumnType("integer") + .HasColumnName("equipped_item_level"); + + b.Property("Experience") + .HasColumnType("integer") + .HasColumnName("experience"); + + b.Property("Faction") + .HasColumnType("smallint") + .HasColumnName("faction"); + + b.Property("Gender") + .HasColumnType("integer") + .HasColumnName("gender"); + + b.Property("GuildId") + .HasColumnType("integer") + .HasColumnName("guild_id"); + + b.Property("IsResting") + .HasColumnType("boolean") + .HasColumnName("is_resting"); + + b.Property("IsWarMode") + .HasColumnType("boolean") + .HasColumnName("is_war_mode"); + + b.Property("LastApiCheck") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_api_check"); + + b.Property("LastApiModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_api_modified"); + + b.Property("LastSeenAddon") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_seen_addon"); + + b.Property("Level") + .HasColumnType("integer") + .HasColumnName("level"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("PlayedTotal") + .HasColumnType("integer") + .HasColumnName("played_total"); + + b.Property("RaceId") + .HasColumnType("integer") + .HasColumnName("race_id"); + + b.Property("RealmId") + .HasColumnType("integer") + .HasColumnName("realm_id"); + + b.Property("RestedExperience") + .HasColumnType("integer") + .HasColumnName("rested_experience"); + + b.Property("ShouldUpdate") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(true) + .HasColumnName("should_update"); + + b.HasKey("Id") + .HasName("pk_player_character"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_player_character_account_id"); + + b.HasIndex("GuildId") + .HasDatabaseName("ix_player_character_guild_id"); + + b.HasIndex("LastApiCheck") + .HasDatabaseName("ix_player_character_last_api_check") + .HasFilter("should_update = true AND account_id IS NOT NULL"); + + NpgsqlIndexBuilderExtensions.IncludeProperties(b.HasIndex("LastApiCheck"), new[] { "Id", "AccountId", "Name", "LastApiModified" }); + + b.HasIndex("CharacterId", "LastSeenAddon") + .HasDatabaseName("ix_player_character_character_id_last_seen_addon") + .HasFilter("account_id IS NOT NULL"); + + b.HasIndex("RealmId", "Name") + .IsUnique() + .HasDatabaseName("ix_player_character_realm_id_name"); + + b.ToTable("player_character", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAchievements", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("AchievementIds") + .HasColumnType("integer[]") + .HasColumnName("achievement_ids"); + + b.PrimitiveCollection>("AchievementTimestamps") + .HasColumnType("integer[]") + .HasColumnName("achievement_timestamps"); + + b.PrimitiveCollection>("CriteriaAmounts") + .HasColumnType("bigint[]") + .HasColumnName("criteria_amounts"); + + b.PrimitiveCollection>("CriteriaCompleted") + .HasColumnType("boolean[]") + .HasColumnName("criteria_completed"); + + b.PrimitiveCollection>("CriteriaIds") + .HasColumnType("integer[]") + .HasColumnName("criteria_ids"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_achievements"); + + b.ToTable("player_character_achievements", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonAchievements", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("Achievements") + .HasColumnType("jsonb") + .HasColumnName("achievements"); + + b.Property("ScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("scanned_at"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_addon_achievements"); + + b.ToTable("player_character_addon_achievements", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonData", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("Auras") + .HasColumnType("jsonb") + .HasColumnName("auras"); + + b.Property("BagsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("bags_scanned_at"); + + b.Property("BankScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("bank_scanned_at"); + + b.Property("BankTabs") + .HasColumnType("smallint") + .HasColumnName("bank_tabs"); + + b.Property("BindLocation") + .HasColumnType("text") + .HasColumnName("bind_location"); + + b.Property>("Currencies") + .HasColumnType("jsonb") + .HasColumnName("currencies"); + + b.Property("CurrenciesScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("currencies_scanned_at"); + + b.Property("CurrenciesTransferredAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("currencies_transferred_at"); + + b.Property("CurrentLocation") + .HasColumnType("text") + .HasColumnName("current_location"); + + b.Property("DailyReset") + .HasColumnType("timestamp with time zone") + .HasColumnName("daily_reset"); + + b.Property>("EquippedItems") + .HasColumnType("jsonb") + .HasColumnName("equipped_items"); + + b.Property>>>("GarrisonTrees") + .HasColumnType("jsonb") + .HasColumnName("garrison_trees"); + + b.Property("GarrisonTreesScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("garrison_trees_scanned_at"); + + b.Property>("Garrisons") + .HasColumnType("jsonb") + .HasColumnName("garrisons"); + + b.Property>("HighestItemLevel") + .HasColumnType("jsonb") + .HasColumnName("highest_item_level"); + + b.PrimitiveCollection>("KnownSpells") + .HasColumnType("integer[]") + .HasColumnName("known_spells"); + + b.Property("Level") + .HasColumnType("smallint") + .HasColumnName("level"); + + b.Property("LevelXp") + .HasColumnType("integer") + .HasColumnName("level_xp"); + + b.Property>("MythicPlus") + .HasColumnType("jsonb") + .HasColumnName("mythic_plus"); + + b.Property("MythicPlusScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("mythic_plus_scanned_at"); + + b.Property>>("MythicPlusSeasons") + .HasColumnType("jsonb") + .HasColumnName("mythic_plus_seasons"); + + b.Property>>("MythicPlusWeeks") + .HasColumnType("jsonb") + .HasColumnName("mythic_plus_weeks"); + + b.Property>("Paragons") + .HasColumnType("jsonb") + .HasColumnName("paragons"); + + b.Property>>("PatronOrders") + .HasColumnType("jsonb") + .HasColumnName("patron_orders"); + + b.Property("PatronOrdersScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("patron_orders_scanned_at"); + + b.Property>>("ProfessionCooldowns") + .HasColumnType("jsonb") + .HasColumnName("profession_cooldowns"); + + b.Property>>("ProfessionTraits") + .HasColumnType("jsonb") + .HasColumnName("profession_traits"); + + b.Property>("Professions") + .HasColumnType("jsonb") + .HasColumnName("professions"); + + b.Property>("Reputations") + .HasColumnType("jsonb") + .HasColumnName("reputations"); + + b.Property("ReputationsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("reputations_scanned_at"); + + b.Property("WeeklyReset") + .HasColumnType("timestamp with time zone") + .HasColumnName("weekly_reset"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_addon_data"); + + b.ToTable("player_character_addon_data", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonMounts", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("Mounts") + .HasColumnType("integer[]") + .HasColumnName("mounts"); + + b.Property("ScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("scanned_at"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_addon_mounts"); + + b.ToTable("player_character_addon_mounts", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonQuests", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("CallingsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("callings_scanned_at"); + + b.PrimitiveCollection>("CompletedQuests") + .HasColumnType("integer[]") + .HasColumnName("completed_quests"); + + b.Property("CompletedQuestsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("completed_quests_scanned_at"); + + b.Property>>>("Dailies") + .HasColumnType("jsonb") + .HasColumnName("dailies"); + + b.PrimitiveCollection>("DailyQuests") + .HasColumnType("integer[]") + .HasColumnName("daily_quests"); + + b.Property>>("GoldWorldQuests") + .HasColumnType("jsonb") + .HasColumnName("gold_world_quests"); + + b.PrimitiveCollection>("OtherQuests") + .HasColumnType("integer[]") + .HasColumnName("other_quests"); + + b.Property>("ProgressQuests") + .HasColumnType("jsonb") + .HasColumnName("progress_quests"); + + b.Property("QuestsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("quests_scanned_at"); + + b.Property("WorldQuestsScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("world_quests_scanned_at"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_addon_quests"); + + b.ToTable("player_character_addon_quests", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterConfiguration", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("BackgroundBrightness") + .HasColumnType("smallint") + .HasColumnName("background_brightness"); + + b.Property("BackgroundId") + .HasColumnType("smallint") + .HasColumnName("background_id"); + + b.Property("BackgroundSaturation") + .HasColumnType("smallint") + .HasColumnName("background_saturation"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_configuration"); + + b.ToTable("player_character_configuration", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterEquippedItems", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("Items") + .HasColumnType("jsonb") + .HasColumnName("items"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_equipped_items"); + + b.ToTable("player_character_equipped_items", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BindType") + .HasColumnType("smallint") + .HasColumnName("bind_type"); + + b.PrimitiveCollection>("BonusIds") + .HasColumnType("smallint[]") + .HasColumnName("bonus_ids"); + + b.Property("Bound") + .HasColumnType("boolean") + .HasColumnName("bound"); + + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("ContainerId") + .HasColumnType("smallint") + .HasColumnName("container_id"); + + b.Property("Context") + .HasColumnType("smallint") + .HasColumnName("context"); + + b.Property("Count") + .HasColumnType("integer") + .HasColumnName("count"); + + b.Property("CraftedQuality") + .HasColumnType("smallint") + .HasColumnName("crafted_quality"); + + b.Property("EnchantId") + .HasColumnType("smallint") + .HasColumnName("enchant_id"); + + b.PrimitiveCollection>("Gems") + .HasColumnType("integer[]") + .HasColumnName("gems"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("ItemLevel") + .HasColumnType("smallint") + .HasColumnName("item_level"); + + b.Property("Location") + .HasColumnType("smallint") + .HasColumnName("location"); + + b.Property>("Modifiers") + .HasColumnType("jsonb") + .HasColumnName("modifiers"); + + b.Property("Quality") + .HasColumnType("smallint") + .HasColumnName("quality"); + + b.Property("Slot") + .HasColumnType("smallint") + .HasColumnName("slot"); + + b.Property("SuffixId") + .HasColumnType("smallint") + .HasColumnName("suffix_id"); + + b.HasKey("Id") + .HasName("pk_player_character_item"); + + b.HasIndex("CharacterId", "Slot") + .HasDatabaseName("ix_player_character_item_character_id_slot"); + + b.HasIndex("CharacterId", "ItemId", "Location") + .HasDatabaseName("ix_player_character_item_character_id_item_id_location"); + + b.ToTable("player_character_item", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterLockouts", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("LastUpdated") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_updated"); + + b.Property>("Lockouts") + .HasColumnType("jsonb") + .HasColumnName("lockouts"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_lockouts"); + + b.ToTable("player_character_lockouts", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMedia", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("AvatarUrl") + .HasColumnType("text") + .HasColumnName("avatar_url"); + + b.Property("InsetUrl") + .HasColumnType("text") + .HasColumnName("inset_url"); + + b.Property("MainRawUrl") + .HasColumnType("text") + .HasColumnName("main_raw_url"); + + b.Property("MainUrl") + .HasColumnType("text") + .HasColumnName("main_url"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_media"); + + b.ToTable("player_character_media", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMounts", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("Mounts") + .HasColumnType("integer[]") + .HasColumnName("mounts"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_mounts"); + + b.ToTable("player_character_mounts", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlus", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("CurrentPeriodId") + .HasColumnType("integer") + .HasColumnName("current_period_id"); + + b.Property>("PeriodRuns") + .HasColumnType("jsonb") + .HasColumnName("period_runs"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_mythic_plus"); + + b.ToTable("player_character_mythic_plus", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlusAddon", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("Maps") + .HasColumnType("jsonb") + .HasColumnName("maps"); + + b.Property("Season") + .HasColumnType("integer") + .HasColumnName("season"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_mythic_plus_addon"); + + b.ToTable("player_character_mythic_plus_addon", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlusSeason", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("Season") + .HasColumnType("integer") + .HasColumnName("season"); + + b.Property("Rating") + .HasColumnType("double precision") + .HasColumnName("rating"); + + b.Property>("Runs") + .HasColumnType("jsonb") + .HasColumnName("runs"); + + b.HasKey("CharacterId", "Season") + .HasName("pk_player_character_mythic_plus_season"); + + b.ToTable("player_character_mythic_plus_season", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterProfessions", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("ProfessionSpecializations") + .HasColumnType("jsonb") + .HasColumnName("profession_specializations"); + + b.Property>>("Professions") + .HasColumnType("jsonb") + .HasColumnName("professions"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_professions"); + + b.ToTable("player_character_professions", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterQuests", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("CompletedIds") + .HasColumnType("integer[]") + .HasColumnName("completed_ids"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_quests"); + + b.ToTable("player_character_quests", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterRaiderIo", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("Seasons") + .HasColumnType("jsonb") + .HasColumnName("seasons"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_raider_io"); + + b.ToTable("player_character_raider_io", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterReputations", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("ExtraReputationIds") + .HasColumnType("integer[]") + .HasColumnName("extra_reputation_ids"); + + b.PrimitiveCollection>("ExtraReputationValues") + .HasColumnType("integer[]") + .HasColumnName("extra_reputation_values"); + + b.Property>("Paragons") + .HasColumnType("jsonb") + .HasColumnName("paragons"); + + b.PrimitiveCollection>("ReputationIds") + .HasColumnType("integer[]") + .HasColumnName("reputation_ids"); + + b.PrimitiveCollection>("ReputationValues") + .HasColumnType("integer[]") + .HasColumnName("reputation_values"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_reputations"); + + b.ToTable("player_character_reputations", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterShadowlands", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("ConduitIds") + .HasColumnType("integer[]") + .HasColumnName("conduit_ids"); + + b.PrimitiveCollection>("ConduitRanks") + .HasColumnType("integer[]") + .HasColumnName("conduit_ranks"); + + b.Property("CovenantId") + .HasColumnType("integer") + .HasColumnName("covenant_id"); + + b.Property>("Covenants") + .HasColumnType("jsonb") + .HasColumnName("covenants"); + + b.Property("RenownLevel") + .HasColumnType("integer") + .HasColumnName("renown_level"); + + b.Property("SoulbindId") + .HasColumnType("integer") + .HasColumnName("soulbind_id"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_shadowlands"); + + b.ToTable("player_character_shadowlands", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterSpecializations", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("Specializations") + .HasColumnType("jsonb") + .HasColumnName("specializations"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_specializations"); + + b.ToTable("player_character_specializations", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterStatistics", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("StatisticDescriptions") + .HasColumnType("text[]") + .HasColumnName("statistic_descriptions"); + + b.PrimitiveCollection>("StatisticIds") + .HasColumnType("integer[]") + .HasColumnName("statistic_ids"); + + b.PrimitiveCollection>("StatisticQuantities") + .HasColumnType("integer[]") + .HasColumnName("statistic_quantities"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_statistics"); + + b.ToTable("player_character_statistics", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterStats", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property>("Basic") + .HasColumnType("jsonb") + .HasColumnName("basic"); + + b.Property>("Misc") + .HasColumnType("jsonb") + .HasColumnName("misc"); + + b.Property>("Rating") + .HasColumnType("jsonb") + .HasColumnName("rating"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_stats"); + + b.ToTable("player_character_stats", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterTransmog", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.PrimitiveCollection>("IllusionIds") + .HasColumnType("integer[]") + .HasColumnName("illusion_ids"); + + b.PrimitiveCollection>("TransmogIds") + .HasColumnType("integer[]") + .HasColumnName("transmog_ids"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_transmog"); + + b.ToTable("player_character_transmog", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterWeekly", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("DelveGilded") + .HasColumnType("smallint") + .HasColumnName("delve_gilded"); + + b.PrimitiveCollection>("DelveLevels") + .HasColumnType("integer[]") + .HasColumnName("delve_levels"); + + b.PrimitiveCollection>("DelveMaps") + .HasColumnType("text[]") + .HasColumnName("delve_maps"); + + b.Property("DelveWeek") + .HasColumnType("integer") + .HasColumnName("delve_week"); + + b.Property("KeystoneDungeon") + .HasColumnType("integer") + .HasColumnName("keystone_dungeon"); + + b.Property("KeystoneLevel") + .HasColumnType("integer") + .HasColumnName("keystone_level"); + + b.Property("KeystoneScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("keystone_scanned_at"); + + b.Property>("Torghast") + .HasColumnType("jsonb") + .HasColumnName("torghast"); + + b.Property("TorghastScannedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("torghast_scanned_at"); + + b.Property("Vault") + .HasColumnType("jsonb") + .HasColumnName("vault"); + + b.HasKey("CharacterId") + .HasName("pk_player_character_weekly"); + + b.ToTable("player_character_weekly", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerGuild", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("RealmId") + .HasColumnType("integer") + .HasColumnName("realm_id"); + + b.Property>("Tabs") + .HasColumnType("jsonb") + .HasColumnName("tabs"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_player_guild"); + + b.HasIndex("UserId", "RealmId", "Name") + .IsUnique() + .HasDatabaseName("ix_player_guild_user_id_realm_id_name"); + + b.ToTable("player_guild", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerGuildItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BindType") + .HasColumnType("smallint") + .HasColumnName("bind_type"); + + b.PrimitiveCollection>("BonusIds") + .HasColumnType("smallint[]") + .HasColumnName("bonus_ids"); + + b.Property("Bound") + .HasColumnType("boolean") + .HasColumnName("bound"); + + b.Property("ContainerId") + .HasColumnType("smallint") + .HasColumnName("container_id"); + + b.Property("Context") + .HasColumnType("smallint") + .HasColumnName("context"); + + b.Property("Count") + .HasColumnType("integer") + .HasColumnName("count"); + + b.Property("CraftedQuality") + .HasColumnType("smallint") + .HasColumnName("crafted_quality"); + + b.Property("EnchantId") + .HasColumnType("smallint") + .HasColumnName("enchant_id"); + + b.PrimitiveCollection>("Gems") + .HasColumnType("integer[]") + .HasColumnName("gems"); + + b.Property("GuildId") + .HasColumnType("integer") + .HasColumnName("guild_id"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("ItemLevel") + .HasColumnType("smallint") + .HasColumnName("item_level"); + + b.Property>("Modifiers") + .HasColumnType("jsonb") + .HasColumnName("modifiers"); + + b.Property("Quality") + .HasColumnType("smallint") + .HasColumnName("quality"); + + b.Property("Slot") + .HasColumnType("smallint") + .HasColumnName("slot"); + + b.Property("SuffixId") + .HasColumnType("smallint") + .HasColumnName("suffix_id"); + + b.HasKey("Id") + .HasName("pk_player_guild_item"); + + b.HasIndex("GuildId", "ItemId") + .HasDatabaseName("ix_player_guild_item_guild_id_item_id"); + + b.ToTable("player_guild_item", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerWarbankItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BindType") + .HasColumnType("smallint") + .HasColumnName("bind_type"); + + b.PrimitiveCollection>("BonusIds") + .HasColumnType("smallint[]") + .HasColumnName("bonus_ids"); + + b.Property("Bound") + .HasColumnType("boolean") + .HasColumnName("bound"); + + b.Property("ContainerId") + .HasColumnType("smallint") + .HasColumnName("container_id"); + + b.Property("Context") + .HasColumnType("smallint") + .HasColumnName("context"); + + b.Property("Count") + .HasColumnType("integer") + .HasColumnName("count"); + + b.Property("CraftedQuality") + .HasColumnType("smallint") + .HasColumnName("crafted_quality"); + + b.Property("EnchantId") + .HasColumnType("smallint") + .HasColumnName("enchant_id"); + + b.PrimitiveCollection>("Gems") + .HasColumnType("integer[]") + .HasColumnName("gems"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("ItemLevel") + .HasColumnType("smallint") + .HasColumnName("item_level"); + + b.Property>("Modifiers") + .HasColumnType("jsonb") + .HasColumnName("modifiers"); + + b.Property("Quality") + .HasColumnType("smallint") + .HasColumnName("quality"); + + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.Property("Slot") + .HasColumnType("smallint") + .HasColumnName("slot"); + + b.Property("SuffixId") + .HasColumnType("smallint") + .HasColumnName("suffix_id"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_player_warbank_item"); + + b.HasIndex("UserId", "ItemId") + .HasDatabaseName("ix_player_warbank_item_user_id_item_id"); + + b.ToTable("player_warbank_item", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.AccountTransmogQuery", b => + { + b.PrimitiveCollection>("IllusionIds") + .HasColumnType("integer[]") + .HasColumnName("illusion_ids"); + + b.PrimitiveCollection>("TransmogIds") + .HasColumnType("integer[]") + .HasColumnName("transmog_ids"); + + b.ToTable("AccountTransmogQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.AchievementCriteriaQuery", b => + { + b.Property("Amount") + .HasColumnType("bigint") + .HasColumnName("amount"); + + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("CriteriaId") + .HasColumnType("integer") + .HasColumnName("criteria_id"); + + b.ToTable("AchievementCriteriaQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.ActiveConnectedRealmQuery", b => + { + b.Property("ConnectedRealmId") + .HasColumnType("integer") + .HasColumnName("connected_realm_id"); + + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.ToTable("ActiveConnectedRealmQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.AuctionBrowseQuery", b => + { + b.Property("GroupKey") + .HasColumnType("text") + .HasColumnName("group_key"); + + b.Property("LowestBuyoutPrice") + .HasColumnType("bigint") + .HasColumnName("lowest_buyout_price"); + + b.Property("TotalQuantity") + .HasColumnType("bigint") + .HasColumnName("total_quantity"); + + b.ToTable("AuctionBrowseQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.CompletedAchievementsQuery", b => + { + b.Property("AchievementId") + .HasColumnType("integer") + .HasColumnName("achievement_id"); + + b.Property("Timestamp") + .HasColumnType("integer") + .HasColumnName("timestamp"); + + b.ToTable("CompletedAchievementsQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.LatestPlayerAccountGoldSnapshotQuery", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property("Gold") + .HasColumnType("integer") + .HasColumnName("gold"); + + b.Property("RealmId") + .HasColumnType("integer") + .HasColumnName("realm_id"); + + b.ToTable("LatestPlayerAccountGoldSnapshotQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.LatestUserGoldSnapshotQuery", b => + { + b.Property("Gold") + .HasColumnType("integer") + .HasColumnName("gold"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.ToTable("LatestUserGoldSnapshotQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.MountQuery", b => + { + b.PrimitiveCollection>("AddonMounts") + .HasColumnType("integer[]") + .HasColumnName("addon_mounts"); + + b.PrimitiveCollection>("Mounts") + .HasColumnType("integer[]") + .HasColumnName("mounts"); + + b.ToTable("MountQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.PlayerAccountGoldSnapshotQuery", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property("RealmId") + .HasColumnType("integer") + .HasColumnName("realm_id"); + + b.Property("TotalGold") + .HasColumnType("integer") + .HasColumnName("total_gold"); + + b.ToTable("PlayerAccountGoldSnapshotQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.SchedulerCharacterQuery", b => + { + b.Property("AccountId") + .HasColumnType("integer") + .HasColumnName("account_id"); + + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("CharacterName") + .HasColumnType("text") + .HasColumnName("character_name"); + + b.Property("LastApiCheck") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_api_check"); + + b.Property("LastApiModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_api_modified"); + + b.Property("RealmSlug") + .HasColumnType("text") + .HasColumnName("realm_slug"); + + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.ToTable("SchedulerCharacterQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.SchedulerUserQuery", b => + { + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.ToTable("SchedulerUserQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.StatisticsQuery", b => + { + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("Quantity") + .HasColumnType("integer") + .HasColumnName("quantity"); + + b.Property("StatisticId") + .HasColumnType("integer") + .HasColumnName("statistic_id"); + + b.ToTable("StatisticsQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.UserGoldSnapshotQuery", b => + { + b.Property("TotalGold") + .HasColumnType("integer") + .HasColumnName("total_gold"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.ToTable("UserGoldSnapshotQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Query.UserLeaderboardQuery", b => + { + b.Property("AppearanceIdCount") + .HasColumnType("integer") + .HasColumnName("appearance_id_count"); + + b.Property("AppearanceSourceCount") + .HasColumnType("integer") + .HasColumnName("appearance_source_count"); + + b.Property("CompletedQuestCount") + .HasColumnType("integer") + .HasColumnName("completed_quest_count"); + + b.Property("IllusionCount") + .HasColumnType("smallint") + .HasColumnName("illusion_count"); + + b.Property("MountCount") + .HasColumnType("smallint") + .HasColumnName("mount_count"); + + b.Property("ToyCount") + .HasColumnType("smallint") + .HasColumnName("toy_count"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.ToTable("UserLeaderboardQuery", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.QueuedJob", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Data") + .HasColumnType("text") + .HasColumnName("data"); + + b.Property("DataHash") + .HasColumnType("text") + .HasColumnName("data_hash"); + + b.Property("Failures") + .HasColumnType("smallint") + .HasColumnName("failures"); + + b.Property("Priority") + .HasColumnType("smallint") + .HasColumnName("priority"); + + b.Property("StartedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("started_at"); + + b.Property("Type") + .HasColumnType("smallint") + .HasColumnName("type"); + + b.HasKey("Id") + .HasName("pk_queued_job"); + + b.HasIndex("Priority") + .HasDatabaseName("ix_queued_job_priority") + .HasFilter("started_at IS NULL"); + + b.HasIndex("Priority", "Type", "DataHash") + .IsUnique() + .HasDatabaseName("ix_queued_job_priority_type_data_hash"); + + b.ToTable("queued_job", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Team.Team", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DefaultRealmId") + .HasColumnType("integer") + .HasColumnName("default_realm_id"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("guid"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.Property("Slug") + .HasColumnType("text") + .HasColumnName("slug"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_team"); + + b.HasIndex("Guid") + .IsUnique() + .HasDatabaseName("ix_team_guid"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_team_user_id"); + + b.ToTable("team", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Team.TeamCharacter", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CharacterId") + .HasColumnType("integer") + .HasColumnName("character_id"); + + b.Property("Note") + .HasColumnType("text") + .HasColumnName("note"); + + b.Property("PrimaryRole") + .HasColumnType("smallint") + .HasColumnName("primary_role"); + + b.Property("SecondaryRole") + .HasColumnType("smallint") + .HasColumnName("secondary_role"); + + b.Property("TeamId") + .HasColumnType("integer") + .HasColumnName("team_id"); + + b.HasKey("Id") + .HasName("pk_team_character"); + + b.HasIndex("CharacterId") + .HasDatabaseName("ix_team_character_character_id"); + + b.HasIndex("TeamId") + .HasDatabaseName("ix_team_character_team_id"); + + b.ToTable("team_character", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserAddonData", b => + { + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.Property("WarbankCopper") + .HasColumnType("bigint") + .HasColumnName("warbank_copper"); + + b.Property("WarbankGoldUpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("warbank_gold_updated_at"); + + b.Property("WarbankUpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("warbank_updated_at"); + + b.HasKey("UserId") + .HasName("pk_user_addon_data"); + + b.ToTable("user_addon_data", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserBulkData", b => + { + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.Property>("Heirlooms") + .HasColumnType("jsonb") + .HasColumnName("heirlooms"); + + b.Property("HeirloomsUpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("heirlooms_updated_at"); + + b.PrimitiveCollection>("MountIds") + .HasColumnType("smallint[]") + .HasColumnName("mount_ids"); + + b.Property("MountsUpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("mounts_updated_at"); + + b.Property>("Pets") + .HasColumnType("jsonb") + .HasColumnName("pets"); + + b.Property("PetsUpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("pets_updated_at"); + + b.PrimitiveCollection>("ToyIds") + .HasColumnType("smallint[]") + .HasColumnName("toy_ids"); + + b.Property("ToysUpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("toys_updated_at"); + + b.PrimitiveCollection>("TransmogIds") + .HasColumnType("integer[]") + .HasColumnName("transmog_ids"); + + b.Property("TransmogsUpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("transmogs_updated_at"); + + b.HasKey("UserId") + .HasName("pk_user_bulk_data"); + + b.ToTable("user_bulk_data", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserCache", b => + { + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.PrimitiveCollection>("AppearanceIds") + .HasColumnType("integer[]") + .HasColumnName("appearance_ids"); + + b.PrimitiveCollection>("AppearanceSources") + .HasColumnType("text[]") + .HasColumnName("appearance_sources"); + + b.Property("CompletedQuests") + .HasColumnType("integer") + .HasColumnName("completed_quests"); + + b.PrimitiveCollection>("IllusionIds") + .HasColumnType("smallint[]") + .HasColumnName("illusion_ids"); + + b.PrimitiveCollection>("MountIds") + .HasColumnType("smallint[]") + .HasColumnName("mount_ids"); + + b.Property("MountsUpdated") + .HasColumnType("timestamp with time zone") + .HasColumnName("mounts_updated"); + + b.PrimitiveCollection>("ToyIds") + .HasColumnType("smallint[]") + .HasColumnName("toy_ids"); + + b.Property("ToysUpdated") + .HasColumnType("timestamp with time zone") + .HasColumnName("toys_updated"); + + b.Property("TransmogUpdated") + .HasColumnType("timestamp with time zone") + .HasColumnName("transmog_updated"); + + b.HasKey("UserId") + .HasName("pk_user_cache"); + + b.ToTable("user_cache", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserGoldSnapshot", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Gold") + .HasColumnType("integer") + .HasColumnName("gold"); + + b.Property("Time") + .HasColumnType("timestamp with time zone") + .HasColumnName("time"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_user_gold_snapshot"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_user_gold_snapshot_user_id"); + + b.ToTable("user_gold_snapshot", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserLeaderboardSnapshot", b => + { + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.Property("Date") + .HasColumnType("date") + .HasColumnName("date"); + + b.Property("AchievementPointsAlliance") + .HasColumnType("integer") + .HasColumnName("achievement_points_alliance"); + + b.Property("AchievementPointsHorde") + .HasColumnType("integer") + .HasColumnName("achievement_points_horde"); + + b.Property("AchievementPointsOverall") + .HasColumnType("integer") + .HasColumnName("achievement_points_overall"); + + b.Property("AppearanceIdCount") + .HasColumnType("integer") + .HasColumnName("appearance_id_count"); + + b.Property("AppearanceSourceCount") + .HasColumnType("integer") + .HasColumnName("appearance_source_count"); + + b.Property("CompletedQuestCount") + .HasColumnType("integer") + .HasColumnName("completed_quest_count"); + + b.Property("HeirloomCount") + .HasColumnType("smallint") + .HasColumnName("heirloom_count"); + + b.Property("HeirloomLevels") + .HasColumnType("smallint") + .HasColumnName("heirloom_levels"); + + b.Property("IllusionCount") + .HasColumnType("smallint") + .HasColumnName("illusion_count"); + + b.Property("MountCount") + .HasColumnType("smallint") + .HasColumnName("mount_count"); + + b.Property("PetCount") + .HasColumnType("smallint") + .HasColumnName("pet_count"); + + b.Property("RecipeCount") + .HasColumnType("smallint") + .HasColumnName("recipe_count"); + + b.Property("ReputationCount") + .HasColumnType("smallint") + .HasColumnName("reputation_count"); + + b.Property("TitleCount") + .HasColumnType("smallint") + .HasColumnName("title_count"); + + b.Property("ToyCount") + .HasColumnType("smallint") + .HasColumnName("toy_count"); + + b.HasKey("UserId", "Date") + .HasName("pk_user_leaderboard_snapshot"); + + b.HasIndex("UserId", "Date") + .IsDescending(false, true) + .HasDatabaseName("ix_user_leaderboard_snapshot_user_id_date"); + + b.ToTable("user_leaderboard_snapshot", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.WorldQuestAggregate", b => + { + b.Property("Region") + .HasColumnType("smallint") + .HasColumnName("region"); + + b.Property("ZoneId") + .HasColumnType("integer") + .HasColumnName("zone_id"); + + b.Property("QuestId") + .HasColumnType("integer") + .HasColumnName("quest_id"); + + b.Property("JsonData") + .HasColumnType("text") + .HasColumnName("json_data"); + + b.HasKey("Region", "ZoneId", "QuestId") + .HasName("pk_world_quest_aggregate"); + + b.ToTable("world_quest_aggregate", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.WorldQuestReport", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Class") + .HasColumnType("smallint") + .HasColumnName("class"); + + b.Property("Expansion") + .HasColumnType("smallint") + .HasColumnName("expansion"); + + b.Property("ExpiresAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("expires_at"); + + b.Property("Faction") + .HasColumnType("smallint") + .HasColumnName("faction"); + + b.Property("Location") + .HasColumnType("text") + .HasColumnName("location"); + + b.Property("QuestId") + .HasColumnType("integer") + .HasColumnName("quest_id"); + + b.Property("Region") + .HasColumnType("smallint") + .HasColumnName("region"); + + b.Property("ReportedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("reported_at"); + + b.Property>("Rewards") + .HasColumnType("jsonb") + .HasColumnName("rewards"); + + b.Property("UserId") + .HasColumnType("bigint") + .HasColumnName("user_id"); + + b.Property("ZoneId") + .HasColumnType("integer") + .HasColumnName("zone_id"); + + b.HasKey("Id") + .HasName("pk_world_quest_report"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_world_quest_report_user_id"); + + b.HasIndex("Region", "ExpiresAt") + .IsDescending(false, true) + .HasDatabaseName("ix_world_quest_report_region_expires_at"); + + b.ToTable("world_quest_report", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowAuction", b => + { + b.Property("ConnectedRealmId") + .HasColumnType("integer") + .HasColumnName("connected_realm_id"); + + b.Property("AuctionId") + .HasColumnType("integer") + .HasColumnName("auction_id"); + + b.Property("AppearanceId") + .HasColumnType("integer") + .HasColumnName("appearance_id"); + + b.Property("AppearanceSource") + .HasColumnType("text") + .HasColumnName("appearance_source"); + + b.Property("BidPrice") + .HasColumnType("bigint") + .HasColumnName("bid_price"); + + b.PrimitiveCollection>("BonusIds") + .HasColumnType("integer[]") + .HasColumnName("bonus_ids"); + + b.Property("BuyoutPrice") + .HasColumnType("bigint") + .HasColumnName("buyout_price"); + + b.Property("Context") + .HasColumnType("smallint") + .HasColumnName("context"); + + b.Property("GroupKey") + .HasColumnType("text") + .HasColumnName("group_key"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.PrimitiveCollection>("ModifierTypes") + .HasColumnType("smallint[]") + .HasColumnName("modifier_types"); + + b.PrimitiveCollection>("ModifierValues") + .HasColumnType("integer[]") + .HasColumnName("modifier_values"); + + b.Property("PetBreedId") + .HasColumnType("smallint") + .HasColumnName("pet_breed_id"); + + b.Property("PetLevel") + .HasColumnType("smallint") + .HasColumnName("pet_level"); + + b.Property("PetQuality") + .HasColumnType("smallint") + .HasColumnName("pet_quality"); + + b.Property("PetSpeciesId") + .HasColumnType("smallint") + .HasColumnName("pet_species_id"); + + b.Property("Quantity") + .HasColumnType("integer") + .HasColumnName("quantity"); + + b.Property("TimeLeft") + .HasColumnType("smallint") + .HasColumnName("time_left"); + + b.HasKey("ConnectedRealmId", "AuctionId") + .HasName("pk_wow_auction"); + + b.HasIndex("ItemId") + .HasDatabaseName("ix_wow_auction_item_id"); + + b.HasIndex("PetSpeciesId") + .HasDatabaseName("ix_wow_auction_pet_species_id"); + + b.HasIndex("AppearanceId", "BuyoutPrice") + .HasDatabaseName("ix_wow_auction_appearance_id_buyout_price") + .HasFilter("appearance_id IS NOT NULL"); + + b.HasIndex("AppearanceSource", "BuyoutPrice") + .HasDatabaseName("ix_wow_auction_appearance_source_buyout_price") + .HasFilter("appearance_source IS NOT NULL"); + + b.ToTable("wow_auction", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowAuctionCheapestByAppearanceId", b => + { + b.Property("ConnectedRealmId") + .HasColumnType("integer") + .HasColumnName("connected_realm_id"); + + b.Property("AppearanceId") + .HasColumnType("integer") + .HasColumnName("appearance_id"); + + b.Property("AuctionId") + .HasColumnType("integer") + .HasColumnName("auction_id"); + + b.HasKey("ConnectedRealmId", "AppearanceId") + .HasName("pk_wow_auction_cheapest_by_appearance_id"); + + b.ToTable("wow_auction_cheapest_by_appearance_id", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowAuctionCheapestByAppearanceSource", b => + { + b.Property("ConnectedRealmId") + .HasColumnType("integer") + .HasColumnName("connected_realm_id"); + + b.Property("AppearanceSource") + .HasColumnType("text") + .HasColumnName("appearance_source"); + + b.Property("AuctionId") + .HasColumnType("integer") + .HasColumnName("auction_id"); + + b.HasKey("ConnectedRealmId", "AppearanceSource") + .HasName("pk_wow_auction_cheapest_by_appearance_source"); + + b.ToTable("wow_auction_cheapest_by_appearance_source", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowAuctionCommodityDaily", b => + { + b.Property("Region") + .HasColumnType("smallint") + .HasColumnName("region"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("Date") + .HasColumnType("date") + .HasColumnName("date"); + + b.PrimitiveCollection>("AvgData") + .HasColumnType("integer[]") + .HasColumnName("avg_data"); + + b.Property("ListedMax") + .HasColumnType("integer") + .HasColumnName("listed_max"); + + b.Property("ListedMin") + .HasColumnType("integer") + .HasColumnName("listed_min"); + + b.PrimitiveCollection>("MaxData") + .HasColumnType("integer[]") + .HasColumnName("max_data"); + + b.PrimitiveCollection>("MinData") + .HasColumnType("integer[]") + .HasColumnName("min_data"); + + b.HasKey("Region", "ItemId", "Date") + .HasName("pk_wow_auction_commodity_daily"); + + b.ToTable("wow_auction_commodity_daily", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowAuctionCommodityHourly", b => + { + b.Property("Region") + .HasColumnType("smallint") + .HasColumnName("region"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone") + .HasColumnName("timestamp"); + + b.PrimitiveCollection>("Data") + .HasColumnType("integer[]") + .HasColumnName("data"); + + b.Property("Listed") + .HasColumnType("integer") + .HasColumnName("listed"); + + b.HasKey("Region", "ItemId", "Timestamp") + .HasName("pk_wow_auction_commodity_hourly"); + + b.ToTable("wow_auction_commodity_hourly", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowCampaign", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.PrimitiveCollection>("QuestLineIds") + .HasColumnType("integer[]") + .HasColumnName("quest_line_ids"); + + b.HasKey("Id") + .HasName("pk_wow_campaign"); + + b.ToTable("wow_campaign", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowChallengeDungeon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Expansion") + .HasColumnType("smallint") + .HasColumnName("expansion"); + + b.Property("MapId") + .HasColumnType("smallint") + .HasColumnName("map_id"); + + b.PrimitiveCollection>("TimerBreakpoints") + .HasColumnType("smallint[]") + .HasColumnName("timer_breakpoints"); + + b.HasKey("Id") + .HasName("pk_wow_challenge_dungeon"); + + b.ToTable("wow_challenge_dungeon", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowCharacterClass", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ArmorMask") + .HasColumnType("smallint") + .HasColumnName("armor_mask"); + + b.Property("RolesMask") + .HasColumnType("smallint") + .HasColumnName("roles_mask"); + + b.Property("Slug") + .HasColumnType("text") + .HasColumnName("slug"); + + b.HasKey("Id") + .HasName("pk_wow_character_class"); + + b.ToTable("wow_character_class", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowCharacterRace", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Bit") + .HasColumnType("smallint") + .HasColumnName("bit"); + + b.Property("Faction") + .HasColumnType("smallint") + .HasColumnName("faction"); + + b.HasKey("Id") + .HasName("pk_wow_character_race"); + + b.ToTable("wow_character_race", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowCharacterSpecialization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClassId") + .HasColumnType("smallint") + .HasColumnName("class_id"); + + b.Property("Order") + .HasColumnType("smallint") + .HasColumnName("order"); + + b.Property("PrimaryStat") + .HasColumnType("smallint") + .HasColumnName("primary_stat"); + + b.Property("Role") + .HasColumnType("smallint") + .HasColumnName("role"); + + b.HasKey("Id") + .HasName("pk_wow_character_specialization"); + + b.ToTable("wow_character_specialization", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowCurrency", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CategoryId") + .HasColumnType("smallint") + .HasColumnName("category_id"); + + b.Property("Flags") + .HasColumnType("smallint") + .HasColumnName("flags"); + + b.Property("MaxPerWeek") + .HasColumnType("integer") + .HasColumnName("max_per_week"); + + b.Property("MaxTotal") + .HasColumnType("integer") + .HasColumnName("max_total"); + + b.Property("RechargeAmount") + .HasColumnType("smallint") + .HasColumnName("recharge_amount"); + + b.Property("RechargeInterval") + .HasColumnType("bigint") + .HasColumnName("recharge_interval"); + + b.Property("TransferPercent") + .HasColumnType("smallint") + .HasColumnName("transfer_percent"); + + b.HasKey("Id") + .HasName("pk_wow_currency"); + + b.ToTable("wow_currency", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowCurrencyCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Expansion") + .HasColumnType("smallint") + .HasColumnName("expansion"); + + b.Property("Flags") + .HasColumnType("smallint") + .HasColumnName("flags"); + + b.HasKey("Id") + .HasName("pk_wow_currency_category"); + + b.ToTable("wow_currency_category", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowDecor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("Type") + .HasColumnType("smallint") + .HasColumnName("type"); + + b.HasKey("Id") + .HasName("pk_wow_decor"); + + b.ToTable("wow_decor", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowHoliday", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DescriptionId") + .HasColumnType("smallint") + .HasColumnName("description_id"); + + b.PrimitiveCollection>("Durations") + .HasColumnType("smallint[]") + .HasColumnName("durations"); + + b.Property("FilterType") + .HasColumnType("smallint") + .HasColumnName("filter_type"); + + b.Property("Flags") + .HasColumnType("smallint") + .HasColumnName("flags"); + + b.Property("Looping") + .HasColumnType("smallint") + .HasColumnName("looping"); + + b.Property("NameId") + .HasColumnType("smallint") + .HasColumnName("name_id"); + + b.Property("Priority") + .HasColumnType("smallint") + .HasColumnName("priority"); + + b.Property("Region") + .HasColumnType("smallint") + .HasColumnName("region"); + + b.PrimitiveCollection>("StartDates") + .HasColumnType("timestamp with time zone[]") + .HasColumnName("start_dates"); + + b.HasKey("Id") + .HasName("pk_wow_holiday"); + + b.ToTable("wow_holiday", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BindType") + .HasColumnType("smallint") + .HasColumnName("bind_type"); + + b.Property("ClassId") + .HasColumnType("smallint") + .HasColumnName("class_id"); + + b.Property("ClassMask") + .HasColumnType("integer") + .HasColumnName("class_mask"); + + b.PrimitiveCollection("CompletesQuestIds") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("integer[]") + .HasDefaultValue(new int[0]) + .HasColumnName("completes_quest_ids"); + + b.Property("ContainerSlots") + .HasColumnType("smallint") + .HasColumnName("container_slots"); + + b.Property("CraftingQuality") + .HasColumnType("smallint") + .HasColumnName("crafting_quality"); + + b.Property("Expansion") + .HasColumnType("smallint") + .HasColumnName("expansion"); + + b.Property("Flags") + .HasColumnType("smallint") + .HasColumnName("flags"); + + b.Property("InventoryType") + .HasColumnType("smallint") + .HasColumnName("inventory_type"); + + b.Property("ItemLevel") + .HasColumnType("smallint") + .HasColumnName("item_level"); + + b.Property("LimitCategory") + .HasColumnType("smallint") + .HasColumnName("limit_category"); + + b.Property("OppositeFactionId") + .HasColumnType("integer") + .HasColumnName("opposite_faction_id"); + + b.Property("PrimaryStat") + .HasColumnType("smallint") + .HasColumnName("primary_stat"); + + b.Property("Quality") + .HasColumnType("smallint") + .HasColumnName("quality"); + + b.Property("RaceMask") + .HasColumnType("bigint") + .HasColumnName("race_mask"); + + b.Property("RequiredAbility") + .HasColumnType("integer") + .HasColumnName("required_ability"); + + b.Property("RequiredLevel") + .HasColumnType("smallint") + .HasColumnName("required_level"); + + b.Property("RequiredSkill") + .HasColumnType("smallint") + .HasColumnName("required_skill"); + + b.Property("RequiredSkillRank") + .HasColumnType("smallint") + .HasColumnName("required_skill_rank"); + + b.PrimitiveCollection("Sockets") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("smallint[]") + .HasDefaultValue(new short[0]) + .HasColumnName("sockets"); + + b.Property("Stackable") + .HasColumnType("integer") + .HasColumnName("stackable"); + + b.Property("SubclassId") + .HasColumnType("smallint") + .HasColumnName("subclass_id"); + + b.PrimitiveCollection("TeachesDecorIds") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("integer[]") + .HasDefaultValue(new int[0]) + .HasColumnName("teaches_decor_ids"); + + b.PrimitiveCollection("TeachesSpellIds") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("integer[]") + .HasDefaultValue(new int[0]) + .HasColumnName("teaches_spell_ids"); + + b.PrimitiveCollection("TeachesTransmogIllusionIds") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("integer[]") + .HasDefaultValue(new int[0]) + .HasColumnName("teaches_transmog_illusion_ids"); + + b.PrimitiveCollection("TeachesTransmogSetIds") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("integer[]") + .HasDefaultValue(new int[0]) + .HasColumnName("teaches_transmog_set_ids"); + + b.Property("Unique") + .HasColumnType("smallint") + .HasColumnName("unique"); + + b.HasKey("Id") + .HasName("pk_wow_item"); + + b.ToTable("wow_item", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowItemBonus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BonusTypeFlags") + .HasColumnType("bigint") + .HasColumnName("bonus_type_flags"); + + b.Property>>("Bonuses") + .HasColumnType("jsonb") + .HasColumnName("bonuses"); + + b.HasKey("Id") + .HasName("pk_wow_item_bonus"); + + b.ToTable("wow_item_bonus", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowItemClass", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClassId") + .HasColumnType("smallint") + .HasColumnName("class_id"); + + b.HasKey("Id") + .HasName("pk_wow_item_class"); + + b.ToTable("wow_item_class", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowItemEffect", b => + { + b.Property("ItemXItemEffectId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("item_x_item_effect_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ItemXItemEffectId")); + + b.Property("Effect") + .HasColumnType("integer") + .HasColumnName("effect"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.PrimitiveCollection("Values") + .HasColumnType("integer[]") + .HasColumnName("values"); + + b.HasKey("ItemXItemEffectId") + .HasName("pk_wow_item_effect"); + + b.ToTable("wow_item_effect", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowItemEffectV2", b => + { + b.Property("ItemId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("item_id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ItemId")); + + b.PrimitiveCollection>("ItemEffectIds") + .HasColumnType("integer[]") + .HasColumnName("item_effect_ids"); + + b.Property>>("SpellEffects") + .HasColumnType("jsonb") + .HasColumnName("spell_effects"); + + b.HasKey("ItemId") + .HasName("pk_wow_item_effect_v2"); + + b.ToTable("wow_item_effect_v2", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowItemModifiedAppearance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AppearanceId") + .HasColumnType("integer") + .HasColumnName("appearance_id"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("Modifier") + .HasColumnType("smallint") + .HasColumnName("modifier"); + + b.Property("Order") + .HasColumnType("smallint") + .HasColumnName("order"); + + b.Property("SourceType") + .HasColumnType("smallint") + .HasColumnName("source_type"); + + b.HasKey("Id") + .HasName("pk_wow_item_modified_appearance"); + + b.ToTable("wow_item_modified_appearance", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowItemSubclass", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AuctionHouseSortOrder") + .HasColumnType("smallint") + .HasColumnName("auction_house_sort_order"); + + b.Property("ClassId") + .HasColumnType("smallint") + .HasColumnName("class_id"); + + b.Property("SubclassId") + .HasColumnType("smallint") + .HasColumnName("subclass_id"); + + b.HasKey("Id") + .HasName("pk_wow_item_subclass"); + + b.ToTable("wow_item_subclass", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowJournalInstance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Flags") + .HasColumnType("integer") + .HasColumnName("flags"); + + b.Property("MapId") + .HasColumnType("smallint") + .HasColumnName("map_id"); + + b.HasKey("Id") + .HasName("pk_wow_journal_instance"); + + b.ToTable("wow_journal_instance", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowMount", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Flags") + .HasColumnType("integer") + .HasColumnName("flags"); + + b.PrimitiveCollection>("ItemIds") + .HasColumnType("integer[]") + .HasColumnName("item_ids"); + + b.Property("SourceType") + .HasColumnType("smallint") + .HasColumnName("source_type"); + + b.Property("SpellId") + .HasColumnType("integer") + .HasColumnName("spell_id"); + + b.HasKey("Id") + .HasName("pk_wow_mount"); + + b.ToTable("wow_mount", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowMythicPlusSeason", b => + { + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.HasKey("Region", "Id") + .HasName("pk_wow_mythic_plus_season"); + + b.ToTable("wow_mythic_plus_season", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowPeriod", b => + { + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Ends") + .HasColumnType("timestamp with time zone") + .HasColumnName("ends"); + + b.Property("Starts") + .HasColumnType("timestamp with time zone") + .HasColumnName("starts"); + + b.HasKey("Region", "Id") + .HasName("pk_wow_period"); + + b.ToTable("wow_period", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowPet", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatureId") + .HasColumnType("integer") + .HasColumnName("creature_id"); + + b.Property("Flags") + .HasColumnType("integer") + .HasColumnName("flags"); + + b.PrimitiveCollection>("ItemIds") + .HasColumnType("integer[]") + .HasColumnName("item_ids"); + + b.Property("PetType") + .HasColumnType("smallint") + .HasColumnName("pet_type"); + + b.Property("SourceType") + .HasColumnType("smallint") + .HasColumnName("source_type"); + + b.Property("SpellId") + .HasColumnType("integer") + .HasColumnName("spell_id"); + + b.HasKey("Id") + .HasName("pk_wow_pet"); + + b.ToTable("wow_pet", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowProfessionRecipeItem", b => + { + b.Property("SkillLineAbilityId") + .HasColumnType("integer") + .HasColumnName("skill_line_ability_id"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("SkillLineId") + .HasColumnType("integer") + .HasColumnName("skill_line_id"); + + b.HasKey("SkillLineAbilityId", "ItemId") + .HasName("pk_wow_profession_recipe_item"); + + b.ToTable("wow_profession_recipe_item", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowQuest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AreaId") + .HasColumnType("integer") + .HasColumnName("area_id"); + + b.Property("CategoryId") + .HasColumnType("integer") + .HasColumnName("category_id"); + + b.Property("LastApiCheck") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_api_check"); + + b.Property("MaximumLevel") + .HasColumnType("smallint") + .HasColumnName("maximum_level"); + + b.Property("MinimumLevel") + .HasColumnType("smallint") + .HasColumnName("minimum_level"); + + b.HasKey("Id") + .HasName("pk_wow_quest"); + + b.ToTable("wow_quest", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowQuestLine", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.PrimitiveCollection>("QuestIds") + .HasColumnType("integer[]") + .HasColumnName("quest_ids"); + + b.HasKey("Id") + .HasName("pk_wow_quest_line"); + + b.ToTable("wow_quest_line", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowRealm", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("ConnectedRealmId") + .HasColumnType("integer") + .HasColumnName("connected_realm_id"); + + b.Property("EnglishName") + .HasColumnType("text") + .HasColumnName("english_name"); + + b.Property("Locale") + .HasColumnType("text") + .HasColumnName("locale"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("Region") + .HasColumnType("integer") + .HasColumnName("region"); + + b.Property("Slug") + .HasColumnType("text") + .HasColumnName("slug"); + + b.HasKey("Id") + .HasName("pk_wow_realm"); + + b.ToTable("wow_realm", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowReputation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountWide") + .HasColumnType("boolean") + .HasColumnName("account_wide"); + + b.PrimitiveCollection>("BaseValues") + .HasColumnType("integer[]") + .HasColumnName("base_values"); + + b.Property("Expansion") + .HasColumnType("smallint") + .HasColumnName("expansion"); + + b.PrimitiveCollection>("MaxValues") + .HasColumnType("integer[]") + .HasColumnName("max_values"); + + b.Property("ParagonId") + .HasColumnType("smallint") + .HasColumnName("paragon_id"); + + b.Property("ParagonQuestId") + .HasColumnType("integer") + .HasColumnName("paragon_quest_id"); + + b.Property("ParagonThreshold") + .HasColumnType("integer") + .HasColumnName("paragon_threshold"); + + b.Property("ParentId") + .HasColumnType("smallint") + .HasColumnName("parent_id"); + + b.Property("RenownCurrencyId") + .HasColumnType("smallint") + .HasColumnName("renown_currency_id"); + + b.Property("TierId") + .HasColumnType("smallint") + .HasColumnName("tier_id"); + + b.HasKey("Id") + .HasName("pk_wow_reputation"); + + b.ToTable("wow_reputation", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowReputationTier", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.PrimitiveCollection("MinValues") + .HasColumnType("integer[]") + .HasColumnName("min_values"); + + b.HasKey("Id") + .HasName("pk_wow_reputation_tier"); + + b.ToTable("wow_reputation_tier", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowToy", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Flags") + .HasColumnType("integer") + .HasColumnName("flags"); + + b.Property("ItemId") + .HasColumnType("integer") + .HasColumnName("item_id"); + + b.Property("SourceType") + .HasColumnType("smallint") + .HasColumnName("source_type"); + + b.HasKey("Id") + .HasName("pk_wow_toy"); + + b.ToTable("wow_toy", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowTransmogSet", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClassMask") + .HasColumnType("integer") + .HasColumnName("class_mask"); + + b.Property("Flags") + .HasColumnType("smallint") + .HasColumnName("flags"); + + b.Property("GroupId") + .HasColumnType("smallint") + .HasColumnName("group_id"); + + b.PrimitiveCollection>("ItemModifiedAppearanceIds") + .HasColumnType("integer[]") + .HasColumnName("item_modified_appearance_ids"); + + b.Property("ItemNameDescriptionId") + .HasColumnType("integer") + .HasColumnName("item_name_description_id"); + + b.HasKey("Id") + .HasName("pk_wow_transmog_set"); + + b.ToTable("wow_transmog_set", (string)null); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Wow.WowWorldQuest", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id"); + + b.Property("Expansion") + .HasColumnType("smallint") + .HasColumnName("expansion"); + + b.Property("Faction") + .HasColumnType("smallint") + .HasColumnName("faction"); + + b.Property("MaxLevel") + .HasColumnType("smallint") + .HasColumnName("max_level"); + + b.Property("MinLevel") + .HasColumnType("smallint") + .HasColumnName("min_level"); + + b.PrimitiveCollection>("NeedQuestIds") + .HasColumnType("integer[]") + .HasColumnName("need_quest_ids"); + + b.Property("QuestInfoId") + .HasColumnType("smallint") + .HasColumnName("quest_info_id"); + + b.PrimitiveCollection>("SkipQuestIds") + .HasColumnType("integer[]") + .HasColumnName("skip_quest_ids"); + + b.HasKey("Id") + .HasName("pk_wow_world_quest"); + + b.ToTable("wow_world_quest", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_asp_net_role_claims_asp_net_roles_role_id"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_asp_net_user_claims_asp_net_users_user_id"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_asp_net_user_logins_asp_net_users_user_id"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_asp_net_user_roles_asp_net_roles_role_id"); + + b.HasOne("Wowthing.Lib.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_asp_net_user_roles_asp_net_users_user_id"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_asp_net_user_tokens_asp_net_users_user_id"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.BackgroundImage", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", "Role") + .WithMany() + .HasForeignKey("RoleId") + .HasConstraintName("fk_background_image_roles_role_id"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.MiscReport", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_misc_report_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccount", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .HasConstraintName("fk_player_account_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountAddonData", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("AddonData") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountAddonData", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_addon_data_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountGoldSnapshot", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithMany() + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_gold_snapshot_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountHeirlooms", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("Heirlooms") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountHeirlooms", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_heirlooms_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountMounts", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("Mounts") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountMounts", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_mounts_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountPets", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("Pets") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountPets", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_pets_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountToys", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("Toys") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountToys", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_toys_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountTransmogIds", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("TransmogIds") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountTransmogIds", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_transmog_ids_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccountTransmogSources", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithOne("TransmogSources") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerAccountTransmogSources", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_account_transmog_sources_player_account_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacter", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerAccount", "Account") + .WithMany("Characters") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("fk_player_character_player_account_account_id"); + + b.HasOne("Wowthing.Lib.Models.Player.PlayerGuild", "Guild") + .WithMany() + .HasForeignKey("GuildId") + .HasConstraintName("fk_player_character_player_guild_guild_id"); + + b.Navigation("Account"); + + b.Navigation("Guild"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAchievements", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Achievements") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterAchievements", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_achievements_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonAchievements", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("AddonAchievements") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterAddonAchievements", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_addon_achievements_player_character_charac"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonData", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("AddonData") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterAddonData", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_addon_data_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonMounts", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("AddonMounts") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterAddonMounts", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_addon_mounts_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterAddonQuests", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("AddonQuests") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterAddonQuests", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_addon_quests_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterConfiguration", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Configuration") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterConfiguration", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_configuration_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterEquippedItems", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("EquippedItems") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterEquippedItems", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_equipped_items_player_character_character_"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterItem", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithMany("Items") + .HasForeignKey("CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_item_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterLockouts", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Lockouts") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterLockouts", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_lockouts_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMedia", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Media") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterMedia", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_media_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMounts", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Mounts") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterMounts", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_mounts_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlus", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("MythicPlus") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlus", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_mythic_plus_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlusAddon", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("MythicPlusAddon") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlusAddon", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_mythic_plus_addon_player_character_charact"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterMythicPlusSeason", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithMany("MythicPlusSeasons") + .HasForeignKey("CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_mythic_plus_season_player_character_charac"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterProfessions", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Professions") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterProfessions", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_professions_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterQuests", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Quests") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterQuests", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_quests_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterRaiderIo", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("RaiderIo") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterRaiderIo", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_raider_io_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterReputations", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Reputations") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterReputations", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_reputations_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterShadowlands", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Shadowlands") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterShadowlands", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_shadowlands_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterSpecializations", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Specializations") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterSpecializations", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_specializations_player_character_character"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterStatistics", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithMany() + .HasForeignKey("CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_statistics_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterStats", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Stats") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterStats", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_stats_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterTransmog", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Transmog") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterTransmog", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_transmog_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacterWeekly", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithOne("Weekly") + .HasForeignKey("Wowthing.Lib.Models.Player.PlayerCharacterWeekly", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_character_weekly_player_character_character_id"); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerGuild", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_guild_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerGuildItem", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerGuild", "Guild") + .WithMany("Items") + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_guild_item_player_guild_guild_id"); + + b.Navigation("Guild"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerWarbankItem", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_player_warbank_item_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Team.Team", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_team_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Team.TeamCharacter", b => + { + b.HasOne("Wowthing.Lib.Models.Player.PlayerCharacter", "Character") + .WithMany() + .HasForeignKey("CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_team_character_player_character_character_id"); + + b.HasOne("Wowthing.Lib.Models.Team.Team", "Team") + .WithMany("Characters") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_team_character_team_team_id"); + + b.Navigation("Character"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserAddonData", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_addon_data_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserBulkData", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_bulk_data_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserCache", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_cache_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserGoldSnapshot", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .HasConstraintName("fk_user_gold_snapshot_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.User.UserLeaderboardSnapshot", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_leaderboard_snapshot_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.WorldQuestReport", b => + { + b.HasOne("Wowthing.Lib.Models.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_world_quest_report_application_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerAccount", b => + { + b.Navigation("AddonData"); + + b.Navigation("Characters"); + + b.Navigation("Heirlooms"); + + b.Navigation("Mounts"); + + b.Navigation("Pets"); + + b.Navigation("Toys"); + + b.Navigation("TransmogIds"); + + b.Navigation("TransmogSources"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerCharacter", b => + { + b.Navigation("Achievements"); + + b.Navigation("AddonAchievements"); + + b.Navigation("AddonData"); + + b.Navigation("AddonMounts"); + + b.Navigation("AddonQuests"); + + b.Navigation("Configuration"); + + b.Navigation("EquippedItems"); + + b.Navigation("Items"); + + b.Navigation("Lockouts"); + + b.Navigation("Media"); + + b.Navigation("Mounts"); + + b.Navigation("MythicPlus"); + + b.Navigation("MythicPlusAddon"); + + b.Navigation("MythicPlusSeasons"); + + b.Navigation("Professions"); + + b.Navigation("Quests"); + + b.Navigation("RaiderIo"); + + b.Navigation("Reputations"); + + b.Navigation("Shadowlands"); + + b.Navigation("Specializations"); + + b.Navigation("Stats"); + + b.Navigation("Transmog"); + + b.Navigation("Weekly"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Player.PlayerGuild", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("Wowthing.Lib.Models.Team.Team", b => + { + b.Navigation("Characters"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/packages/csharp-lib/Migrations/20260614010028_Add_MiscAggregate_MiscReport.cs b/packages/csharp-lib/Migrations/20260614010028_Add_MiscAggregate_MiscReport.cs new file mode 100644 index 000000000..46f4bd6d7 --- /dev/null +++ b/packages/csharp-lib/Migrations/20260614010028_Add_MiscAggregate_MiscReport.cs @@ -0,0 +1,74 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Wowthing.Lib.Migrations +{ + /// + public partial class Add_MiscAggregate_MiscReport : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "misc_aggregate", + columns: table => new + { + report_type = table.Column(type: "smallint", nullable: false), + region = table.Column(type: "smallint", nullable: false), + json_data = table.Column(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("pk_misc_aggregate", x => new { x.region, x.report_type }); + }); + + migrationBuilder.CreateTable( + name: "misc_report", + columns: table => new + { + id = table.Column(type: "bigint", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + user_id = table.Column(type: "bigint", nullable: false), + expires_at = table.Column(type: "timestamp with time zone", nullable: false), + reported_at = table.Column(type: "timestamp with time zone", nullable: false), + report_type = table.Column(type: "smallint", nullable: false), + region = table.Column(type: "smallint", nullable: false), + data = table.Column(type: "character varying(1024)", maxLength: 1024, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("pk_misc_report", x => x.id); + table.ForeignKey( + name: "fk_misc_report_application_user_user_id", + column: x => x.user_id, + principalTable: "asp_net_users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "ix_misc_report_report_type_region_expires_at", + table: "misc_report", + columns: new[] { "report_type", "region", "expires_at" }, + descending: new[] { false, false, true }); + + migrationBuilder.CreateIndex( + name: "ix_misc_report_user_id", + table: "misc_report", + column: "user_id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "misc_aggregate"); + + migrationBuilder.DropTable( + name: "misc_report"); + } + } +} diff --git a/packages/csharp-lib/Migrations/WowDbContextModelSnapshot.cs b/packages/csharp-lib/Migrations/WowDbContextModelSnapshot.cs index bedfdb4e2..21bca6266 100644 --- a/packages/csharp-lib/Migrations/WowDbContextModelSnapshot.cs +++ b/packages/csharp-lib/Migrations/WowDbContextModelSnapshot.cs @@ -460,6 +460,73 @@ protected override void BuildModel(ModelBuilder modelBuilder) 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") @@ -899,6 +966,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) .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"); @@ -3798,6 +3869,18 @@ protected override void BuildModel(ModelBuilder modelBuilder) 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") diff --git a/packages/csharp-lib/Models/MiscAggregate.cs b/packages/csharp-lib/Models/MiscAggregate.cs new file mode 100644 index 000000000..83cee1503 --- /dev/null +++ b/packages/csharp-lib/Models/MiscAggregate.cs @@ -0,0 +1,13 @@ +using Wowthing.Lib.Enums; + +namespace Wowthing.Lib.Models; + +public class MiscAggregate +{ + // 2 bytes + public MiscReportType ReportType { get; set; } + public short Region { get; set; } + + // variable + public string JsonData { get; set; } +} diff --git a/packages/csharp-lib/Models/MiscReport.cs b/packages/csharp-lib/Models/MiscReport.cs new file mode 100644 index 000000000..1c348e8fa --- /dev/null +++ b/packages/csharp-lib/Models/MiscReport.cs @@ -0,0 +1,31 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using Wowthing.Lib.Constants; +using Wowthing.Lib.Enums; + +namespace Wowthing.Lib.Models; + +[Index(nameof(UserId))] +[Index(nameof(ReportType), nameof(Region), nameof(ExpiresAt), IsDescending = [false, false, true])] +public class MiscReport +{ + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public long Id { get; set; } + + // 8 bytes + [ForeignKey("User")] + public long UserId { get; set; } + public ApplicationUser User { get; set; } + + public DateTime ExpiresAt { get; set; } = MiscConstants.DefaultDateTime; + public DateTime ReportedAt { get; set; } = MiscConstants.DefaultDateTime; + + // 2 bytes + public MiscReportType ReportType { get; set; } + public short Region { get; set; } + + // variable + [MaxLength(1024)] + public string Data { get; set; } +} diff --git a/packages/csharp-lib/Models/Player/PlayerCharacterAddonData.cs b/packages/csharp-lib/Models/Player/PlayerCharacterAddonData.cs index 193d2a94b..9a4f74d92 100644 --- a/packages/csharp-lib/Models/Player/PlayerCharacterAddonData.cs +++ b/packages/csharp-lib/Models/Player/PlayerCharacterAddonData.cs @@ -12,6 +12,7 @@ public class PlayerCharacterAddonData(int characterId) public PlayerCharacter Character { get; set; } + public short BankTabs { get; set; } public short Level { get; set; } public int LevelXp { get; set; }