diff --git a/SVSim.Bootstrap/Data/seeds/daily-login-bonus.json b/SVSim.Bootstrap/Data/seeds/daily-login-bonus.json
deleted file mode 100644
index e31694c2..00000000
--- a/SVSim.Bootstrap/Data/seeds/daily-login-bonus.json
+++ /dev/null
@@ -1,14 +0,0 @@
-[
- {
- "id": 1,
- "bonus_data": []
- },
- {
- "id": 3,
- "bonus_data": []
- },
- {
- "id": 4,
- "bonus_data": []
- }
-]
diff --git a/SVSim.Bootstrap/Importers/DailyLoginBonusImporter.cs b/SVSim.Bootstrap/Importers/DailyLoginBonusImporter.cs
deleted file mode 100644
index 1c158f1f..00000000
--- a/SVSim.Bootstrap/Importers/DailyLoginBonusImporter.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System.Text.Json;
-using Microsoft.EntityFrameworkCore;
-using SVSim.Bootstrap.Models.Seed;
-using SVSim.Database;
-using SVSim.Database.Models;
-
-namespace SVSim.Bootstrap.Importers;
-
-///
-/// Idempotent upsert of daily-login-bonus campaign rows from seeds/daily-login-bonus.json.
-/// bonus_data array preserved verbatim — prod observed empty arrays outside active events.
-///
-public class DailyLoginBonusImporter
-{
- public async Task ImportAsync(SVSimDbContext context, string seedDir)
- {
- var seed = SeedLoader.LoadList(Path.Combine(seedDir, "daily-login-bonus.json"));
- if (seed.Count == 0) return 0;
-
- var existing = await context.DailyLoginBonuses.ToDictionaryAsync(e => e.Id);
- int created = 0, updated = 0;
- foreach (var s in seed)
- {
- if (s.Id == 0) continue;
- var entry = existing.TryGetValue(s.Id, out var ex) ? ex : new DailyLoginBonusEntry { Id = s.Id };
- entry.BonusData = s.BonusData.ValueKind == JsonValueKind.Undefined
- ? "[]"
- : JsonSerializer.Serialize(s.BonusData);
- if (ex is null) { context.DailyLoginBonuses.Add(entry); existing[s.Id] = entry; created++; }
- else updated++;
- }
-
- await context.SaveChangesAsync();
- Console.WriteLine($"[DailyLoginBonusImporter] +{created}/~{updated}");
- return created + updated;
- }
-}
diff --git a/SVSim.Bootstrap/Models/Seed/DailyLoginBonusSeed.cs b/SVSim.Bootstrap/Models/Seed/DailyLoginBonusSeed.cs
deleted file mode 100644
index e64ed76d..00000000
--- a/SVSim.Bootstrap/Models/Seed/DailyLoginBonusSeed.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using System.Text.Json;
-using System.Text.Json.Serialization;
-
-namespace SVSim.Bootstrap.Models.Seed;
-
-/// Mirrors seeds/daily-login-bonus.json. bonus_data preserved verbatim.
-public sealed class DailyLoginBonusSeed
-{
- [JsonPropertyName("id")] public int Id { get; set; }
- [JsonPropertyName("bonus_data")] public JsonElement BonusData { get; set; }
-}
diff --git a/SVSim.Bootstrap/Program.cs b/SVSim.Bootstrap/Program.cs
index 629c91e4..5baccc63 100644
--- a/SVSim.Bootstrap/Program.cs
+++ b/SVSim.Bootstrap/Program.cs
@@ -94,7 +94,6 @@ public static class Program
await new MissionCatalogImporter().ImportAsync(context, opts.SeedDir);
await new AchievementCatalogImporter().ImportAsync(context, opts.SeedDir);
await new BattlePassMonthlyMissionImporter().ImportAsync(context, opts.SeedDir);
- await new DailyLoginBonusImporter().ImportAsync(context, opts.SeedDir);
await new PreReleaseInfoImporter().ImportAsync(context, opts.SeedDir);
await new CardListsImporter().ImportAsync(context, opts.SeedDir);
await new RotationFlagUpdater().UpdateAsync(context);
diff --git a/SVSim.Database/Migrations/20260613193716_AddViewerLoginBonusState.Designer.cs b/SVSim.Database/Migrations/20260613193716_AddViewerLoginBonusState.Designer.cs
new file mode 100644
index 00000000..fca60dde
--- /dev/null
+++ b/SVSim.Database/Migrations/20260613193716_AddViewerLoginBonusState.Designer.cs
@@ -0,0 +1,4778 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+using SVSim.Database;
+
+#nullable disable
+
+namespace SVSim.Database.Migrations
+{
+ [DbContext(typeof(SVSimDbContext))]
+ [Migration("20260613193716_AddViewerLoginBonusState")]
+ partial class AddViewerLoginBonusState
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "8.0.8")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.HasSequence("ShortUdidSequence")
+ .StartsAt(400000000L);
+
+ modelBuilder.Entity("DegreeEntryViewer", b =>
+ {
+ b.Property("DegreesId")
+ .HasColumnType("integer");
+
+ b.Property("ViewersId")
+ .HasColumnType("bigint");
+
+ b.HasKey("DegreesId", "ViewersId");
+
+ b.HasIndex("ViewersId");
+
+ b.ToTable("DegreeEntryViewer");
+ });
+
+ modelBuilder.Entity("EmblemEntryViewer", b =>
+ {
+ b.Property("EmblemsId")
+ .HasColumnType("integer");
+
+ b.Property("ViewersId")
+ .HasColumnType("bigint");
+
+ b.HasKey("EmblemsId", "ViewersId");
+
+ b.HasIndex("ViewersId");
+
+ b.ToTable("EmblemEntryViewer");
+ });
+
+ modelBuilder.Entity("LeaderSkinEntryViewer", b =>
+ {
+ b.Property("LeaderSkinsId")
+ .HasColumnType("integer");
+
+ b.Property("ViewersId")
+ .HasColumnType("bigint");
+
+ b.HasKey("LeaderSkinsId", "ViewersId");
+
+ b.HasIndex("ViewersId");
+
+ b.ToTable("LeaderSkinEntryViewer");
+ });
+
+ modelBuilder.Entity("MyPageBackgroundEntryViewer", b =>
+ {
+ b.Property("MyPageBackgroundsId")
+ .HasColumnType("integer");
+
+ b.Property("ViewersId")
+ .HasColumnType("bigint");
+
+ b.HasKey("MyPageBackgroundsId", "ViewersId");
+
+ b.HasIndex("ViewersId");
+
+ b.ToTable("MyPageBackgroundEntryViewer");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Entities.Story.SpecialBattleSetting", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("BanishEffectOverride")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("ClassDestroyEffectOverride")
+ .HasColumnType("integer");
+
+ b.Property("EnemyAttachSkill")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("EnemyStartLife")
+ .HasColumnType("integer");
+
+ b.Property("EnemyStartPp")
+ .HasColumnType("integer");
+
+ b.Property("IdOverrideInBattleLog")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Note")
+ .HasColumnType("text");
+
+ b.Property("PlayerAttachSkill")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("PlayerFirstTurn")
+ .HasColumnType("integer");
+
+ b.Property("PlayerStartLife")
+ .HasColumnType("integer");
+
+ b.Property("PlayerStartPp")
+ .HasColumnType("integer");
+
+ b.Property("ResultSkip")
+ .HasColumnType("integer");
+
+ b.Property("SpecialTokenDrawEffectOverride")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("TokenDrawEffectOverride")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("VsEffectOverride")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.ToTable("SpecialBattleSettings");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Entities.Story.StoryChapter", b =>
+ {
+ b.Property("StoryId")
+ .HasColumnType("integer");
+
+ b.Property("Battle3dFieldId")
+ .HasColumnType("integer");
+
+ b.Property("BattleExists")
+ .HasColumnType("boolean");
+
+ b.Property("BgFileName")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("BgmId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("ChapterClearTextId")
+ .HasColumnType("text");
+
+ b.Property("ChapterEffectPath")
+ .HasColumnType("text");
+
+ b.Property("ChapterId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("CharaId")
+ .HasColumnType("integer");
+
+ b.Property("EnemyAiId")
+ .HasColumnType("integer");
+
+ b.Property("EnemyCharaId")
+ .HasColumnType("integer");
+
+ b.Property("EnemyClass")
+ .HasColumnType("integer");
+
+ b.Property("IsCameraMovable")
+ .HasColumnType("integer");
+
+ b.Property("IsMaintenanceChapter")
+ .HasColumnType("boolean");
+
+ b.Property("IsPlayAnotherEndAppearanceAnimation")
+ .HasColumnType("boolean");
+
+ b.Property("IsReleasedAnotherEnd")
+ .HasColumnType("boolean");
+
+ b.Property("IsSkipEnabled")
+ .HasColumnType("boolean");
+
+ b.Property("NextChapterId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("ReleasePoint")
+ .HasColumnType("integer");
+
+ b.Property("RequiredChapterId")
+ .HasColumnType("text");
+
+ b.Property("SectionId")
+ .HasColumnType("integer");
+
+ b.Property("SelectionDisplayPosition")
+ .HasColumnType("text");
+
+ b.Property("SelectionTextId")
+ .HasColumnType("text");
+
+ b.Property("ShowCoordinate")
+ .HasColumnType("integer");
+
+ b.Property("ShowSubtitles")
+ .HasColumnType("integer");
+
+ b.Property("SpecialBattleSettingId")
+ .HasColumnType("integer");
+
+ b.Property("UnlockText")
+ .HasColumnType("text");
+
+ b.Property("XCoordinate")
+ .HasColumnType("numeric");
+
+ b.Property("YCoordinate")
+ .HasColumnType("numeric");
+
+ b.HasKey("StoryId");
+
+ b.HasIndex("NextChapterId");
+
+ b.HasIndex("SpecialBattleSettingId");
+
+ b.HasIndex("SectionId", "CharaId", "ChapterId");
+
+ b.ToTable("StoryChapters");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Entities.Story.StorySection", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("AllStoryOrderId")
+ .HasColumnType("integer");
+
+ b.Property("BackGroundId")
+ .HasColumnType("integer");
+
+ b.Property("ChapterSelectType")
+ .HasColumnType("integer");
+
+ b.Property("ImageName")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("IsLeaderSelect")
+ .HasColumnType("boolean");
+
+ b.Property("IsPlayAnotherEndAppearanceAnimation")
+ .HasColumnType("boolean");
+
+ b.Property("IsSpoiler")
+ .HasColumnType("integer");
+
+ b.Property("IsUnderMaintenance")
+ .HasColumnType("boolean");
+
+ b.Property("NameTextKey")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("OrderId")
+ .HasColumnType("integer");
+
+ b.Property("SpoilerMessage")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("StoryApiType")
+ .HasColumnType("integer");
+
+ b.Property("StoryTypeOverwrite")
+ .HasColumnType("integer");
+
+ b.Property("WorldId")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("WorldId");
+
+ b.ToTable("StorySections");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Entities.Story.StoryWorld", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("PanelImageName")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("RibbonText")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("TitleTextKey")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("StoryWorlds");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Entities.Story.ViewerStoryBranchUnlock", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("StoryId")
+ .HasColumnType("integer");
+
+ b.Property("UnlockedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.HasKey("ViewerId", "StoryId");
+
+ b.ToTable("ViewerStoryBranchUnlocks");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Entities.Story.ViewerStoryProgress", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("StoryId")
+ .HasColumnType("integer");
+
+ b.Property("FinishedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("IsFinish")
+ .HasColumnType("boolean");
+
+ b.Property("IsSkipped")
+ .HasColumnType("boolean");
+
+ b.Property("SkippedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.HasKey("ViewerId", "StoryId");
+
+ b.ToTable("ViewerStoryProgress");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.AchievementCatalogEntry", b =>
+ {
+ b.Property("AchievementType")
+ .HasColumnType("integer");
+
+ b.Property("Level")
+ .HasColumnType("integer");
+
+ b.Property("EventArg")
+ .HasColumnType("integer");
+
+ b.Property("EventType")
+ .HasColumnType("text");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("OrderNum")
+ .HasColumnType("integer");
+
+ b.Property("RequireNumber")
+ .HasColumnType("integer");
+
+ b.Property("RewardDetailId")
+ .HasColumnType("bigint");
+
+ b.Property("RewardNumber")
+ .HasColumnType("integer");
+
+ b.Property("RewardType")
+ .HasColumnType("integer");
+
+ b.HasKey("AchievementType", "Level");
+
+ b.HasIndex("AchievementType");
+
+ b.HasIndex("EventType", "EventArg");
+
+ b.ToTable("AchievementCatalog");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.ArenaSeasonConfig", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("Cost")
+ .HasColumnType("numeric(20,0)");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Enable")
+ .HasColumnType("integer");
+
+ b.Property("FormatInfo")
+ .IsRequired()
+ .HasColumnType("jsonb");
+
+ b.Property("IsJoin")
+ .HasColumnType("boolean");
+
+ b.Property("Mode")
+ .HasColumnType("integer");
+
+ b.Property("RupyCost")
+ .HasColumnType("numeric(20,0)");
+
+ b.Property("TicketCost")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.ToTable("ArenaSeasons");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.ArenaTwoPickReward", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("RewardGroup")
+ .HasColumnType("integer");
+
+ b.Property("RewardId")
+ .HasColumnType("bigint");
+
+ b.Property("RewardNum")
+ .HasColumnType("integer");
+
+ b.Property("RewardType")
+ .HasColumnType("integer");
+
+ b.Property("Weight")
+ .HasColumnType("integer");
+
+ b.Property("WinCount")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("WinCount");
+
+ b.HasIndex("WinCount", "RewardGroup", "RewardType", "RewardId", "RewardNum")
+ .IsUnique();
+
+ b.ToTable("ArenaTwoPickRewards");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.AvatarAbilityEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("Ability")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("AbilityCost")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("AbilityDesc")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("BattleStartFirstPlayerTurnBp")
+ .HasColumnType("integer");
+
+ b.Property("BattleStartMaxLife")
+ .HasColumnType("integer");
+
+ b.Property("BattleStartSecondPlayerTurnBp")
+ .HasColumnType("integer");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("LeaderSkinId")
+ .HasColumnType("integer");
+
+ b.Property("PassiveAbility")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("PassiveAbilityDesc")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("AvatarAbilities");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.BannerEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("ChangeTime")
+ .HasColumnType("integer");
+
+ b.Property("Click")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("ImageName")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("ImagePaths")
+ .IsRequired()
+ .HasColumnType("jsonb");
+
+ b.Property("RemainingTime")
+ .HasColumnType("integer");
+
+ b.Property("Status")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Banners");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.BattlePassLevelEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Level")
+ .HasColumnType("integer");
+
+ b.Property("RequiredPoint")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.ToTable("BattlePassLevels");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.BattlePassMonthlyMissionEntry", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("BattlePassPoint")
+ .HasColumnType("integer");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("EventArg")
+ .HasColumnType("integer");
+
+ b.Property("EventType")
+ .HasColumnType("text");
+
+ b.Property("Month")
+ .HasColumnType("integer");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("OrderNum")
+ .HasColumnType("integer");
+
+ b.Property("RequireNumber")
+ .HasColumnType("integer");
+
+ b.Property("RewardDetailId")
+ .HasColumnType("bigint");
+
+ b.Property("RewardNumber")
+ .HasColumnType("integer");
+
+ b.Property("RewardType")
+ .HasColumnType("integer");
+
+ b.Property("Year")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Year", "Month");
+
+ b.HasIndex("Year", "Month", "OrderNum")
+ .IsUnique();
+
+ b.ToTable("BattlePassMonthlyMissions");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.BattlePassRewardEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("bigint");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("IsAppealExclusion")
+ .HasColumnType("boolean");
+
+ b.Property("Level")
+ .HasColumnType("integer");
+
+ b.Property("RewardDetailId")
+ .HasColumnType("bigint");
+
+ b.Property("RewardNumber")
+ .HasColumnType("integer");
+
+ b.Property("RewardType")
+ .HasColumnType("integer");
+
+ b.Property("SeasonId")
+ .HasColumnType("integer");
+
+ b.Property("Track")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("SeasonId", "Track", "Level")
+ .IsUnique();
+
+ b.ToTable("BattlePassRewards");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.BattlePassSeasonEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("CanPurchase")
+ .HasColumnType("boolean");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("EndDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("MaxLevel")
+ .HasColumnType("integer");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("PriceCrystal")
+ .HasColumnType("integer");
+
+ b.Property("StartDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.HasKey("Id");
+
+ b.HasIndex("StartDate", "EndDate");
+
+ b.ToTable("BattlePassSeasons");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.BattlefieldEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("IsOpen")
+ .HasColumnType("boolean");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Battlefields");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.BotRosterEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("AiId")
+ .HasColumnType("integer");
+
+ b.Property("BattlePoint")
+ .HasColumnType("integer");
+
+ b.Property("CharaId")
+ .HasColumnType("integer");
+
+ b.Property("ClassId")
+ .HasColumnType("integer");
+
+ b.Property("CountryCode")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DegreeId")
+ .HasColumnType("integer");
+
+ b.Property("EmblemId")
+ .HasColumnType("integer");
+
+ b.Property("FieldId")
+ .HasColumnType("integer");
+
+ b.Property("IsMasterRank")
+ .HasColumnType("integer");
+
+ b.Property("IsOfficial")
+ .HasColumnType("integer");
+
+ b.Property("MasterPoint")
+ .HasColumnType("integer");
+
+ b.Property("Rank")
+ .HasColumnType("integer");
+
+ b.Property("SleeveId")
+ .HasColumnType("integer");
+
+ b.Property("UserName")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("BotRoster");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.BuildDeckProductEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DeckCode")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("FeaturedCardId")
+ .HasColumnType("bigint");
+
+ b.Property("IntroPriceCrystal")
+ .HasColumnType("integer");
+
+ b.Property("IntroPriceRupy")
+ .HasColumnType("integer");
+
+ b.Property("IsEnabled")
+ .HasColumnType("boolean");
+
+ b.Property("LeaderId")
+ .HasColumnType("integer");
+
+ b.Property("ProductNameKey")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("PurchaseNumMax")
+ .HasColumnType("integer");
+
+ b.Property("RegularPriceCrystal")
+ .HasColumnType("integer");
+
+ b.Property("RegularPriceRupy")
+ .HasColumnType("integer");
+
+ b.Property("SeriesId")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("SeriesId");
+
+ b.ToTable("BuildDeckProducts");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.BuildDeckSeriesEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DrumrollPath")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("IntroKey")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("IsEnabled")
+ .HasColumnType("boolean");
+
+ b.Property("IsNew")
+ .HasColumnType("boolean");
+
+ b.Property("NameKey")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("OrderIndex")
+ .HasColumnType("integer");
+
+ b.Property("TitlePath")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("BuildDeckSeries");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.CardCosmeticReward", b =>
+ {
+ b.Property("CardId")
+ .HasColumnType("bigint");
+
+ b.Property("Type")
+ .HasColumnType("integer");
+
+ b.Property("CosmeticId")
+ .HasColumnType("bigint");
+
+ b.Property("Quantity")
+ .HasColumnType("integer");
+
+ b.HasKey("CardId", "Type", "CosmeticId");
+
+ b.HasIndex("CardId");
+
+ b.ToTable("CardCosmeticRewards");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.ClassEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Classes");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.ClassExpEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("NecessaryExp")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.ToTable("ClassExpCurve");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.ColosseumAvatarDeck", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("CardListJson")
+ .IsRequired()
+ .HasColumnType("jsonb");
+
+ b.Property("ClassId")
+ .HasColumnType("integer");
+
+ b.Property("DeckNo")
+ .HasColumnType("integer");
+
+ b.Property("DisplayOrder")
+ .HasColumnType("integer");
+
+ b.Property("LeaderSkinId")
+ .HasColumnType("bigint");
+
+ b.Property("SleeveId")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DeckNo")
+ .IsUnique();
+
+ b.ToTable("ColosseumAvatarDecks");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.ColosseumHofDeck", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("CardListJson")
+ .IsRequired()
+ .HasColumnType("jsonb");
+
+ b.Property("ClassId")
+ .HasColumnType("integer");
+
+ b.Property("DeckNo")
+ .HasColumnType("integer");
+
+ b.Property("DisplayOrder")
+ .HasColumnType("integer");
+
+ b.Property("LeaderSkinId")
+ .HasColumnType("bigint");
+
+ b.Property("SleeveId")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DeckNo")
+ .IsUnique();
+
+ b.ToTable("ColosseumHofDecks");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.ColosseumWindFallDeck", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("CardListJson")
+ .IsRequired()
+ .HasColumnType("jsonb");
+
+ b.Property("ClassId")
+ .HasColumnType("integer");
+
+ b.Property("DeckNo")
+ .HasColumnType("integer");
+
+ b.Property("DisplayOrder")
+ .HasColumnType("integer");
+
+ b.Property("LeaderSkinId")
+ .HasColumnType("bigint");
+
+ b.Property("SleeveId")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DeckNo")
+ .IsUnique();
+
+ b.ToTable("ColosseumWindFallDecks");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.DefaultDeckEntry", b =>
+ {
+ b.Property