using Microsoft.EntityFrameworkCore; using SVSim.Bootstrap.Models.Seed; using SVSim.Database; using SVSim.Database.Models; namespace SVSim.Bootstrap.Importers; /// /// Idempotent upsert of mission catalog rows from seeds/mission-catalog.json. /// Rows missing from the seed are LEFT INTACT (so hand-added catalog rows survive). /// public class MissionCatalogImporter { public async Task ImportAsync(SVSimDbContext context, string seedDir) { var seed = SeedLoader.LoadList(Path.Combine(seedDir, "mission-catalog.json")); if (seed.Count == 0) { Console.WriteLine("[MissionCatalogImporter] No seed rows; skipping."); return 0; } var existing = await context.MissionCatalog.ToDictionaryAsync(e => e.Id); int created = 0, updated = 0; var unmapped = new List(); foreach (var s in seed) { if (s.Id == 0) continue; var entry = existing.TryGetValue(s.Id, out var ex) ? ex : new MissionCatalogEntry { Id = s.Id }; entry.Name = s.Name; entry.LotType = s.LotType; entry.RequireNumber = s.RequireNumber; entry.RewardType = s.RewardType; entry.RewardDetailId = s.RewardDetailId; entry.RewardNumber = s.RewardNumber; entry.BattlePassPoint = s.BattlePassPoint; entry.DefaultFlag = s.DefaultFlag; entry.EventType = s.EventType; entry.EventArg = s.EventArg; entry.StartTime = s.StartTime; entry.EndTime = s.EndTime; if (ex is null) { context.MissionCatalog.Add(entry); existing[s.Id] = entry; created++; } else updated++; if (s.EventType is null) unmapped.Add(s.Id); } await context.SaveChangesAsync(); Console.WriteLine($"[MissionCatalogImporter] +{created}/~{updated}"); if (unmapped.Count > 0) { Console.WriteLine($"[MissionCatalogImporter] WARN: {unmapped.Count} mission_ids with " + $"no event_type: [{string.Join(", ", unmapped)}] — add to MISSION_EVENT_MAP " + "in data_dumps/scripts/extract-missions.py and re-run the extractor"); } return created + updated; } }