using GerbilManagerWebAPI.Models; using Microsoft.EntityFrameworkCore; public class ApplicationContext : DbContext { public ApplicationContext(DbContextOptions options) : base(options) { } public DbSet Gerbils => Set(); public DbSet Litters => Set(); public DbSet Contacts => Set(); public DbSet Enclosures => Set(); public DbSet ColorVarieties => Set(); public DbSet GerbilPhotos => Set(); public DbSet HealthRecords => Set(); public DbSet WeightRecords => Set(); public DbSet SaleContracts => Set(); public DbSet BreederSettings => Set(); protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity(e => { // Enums persisted as their string names (readable, Gridify-friendly). e.Property(g => g.Gender).HasConversion(); e.Property(g => g.Status).HasConversion(); e.HasOne(g => g.Litter).WithMany() .HasForeignKey(g => g.LitterId).OnDelete(DeleteBehavior.SetNull); e.HasOne(g => g.OriginContact).WithMany() .HasForeignKey(g => g.OriginContactId).OnDelete(DeleteBehavior.Restrict); e.HasOne(g => g.ReceiverContact).WithMany() .HasForeignKey(g => g.ReceiverContactId).OnDelete(DeleteBehavior.Restrict); e.HasOne(g => g.Enclosure).WithMany(en => en.Gerbils) .HasForeignKey(g => g.EnclosureId).OnDelete(DeleteBehavior.SetNull); e.HasOne(g => g.ColorVariety).WithMany() .HasForeignKey(g => g.ColorVarietyId).OnDelete(DeleteBehavior.SetNull); }); modelBuilder.Entity(e => { e.HasOne(l => l.Father).WithMany() .HasForeignKey(l => l.FatherId).OnDelete(DeleteBehavior.Restrict); e.HasOne(l => l.Mother).WithMany() .HasForeignKey(l => l.MotherId).OnDelete(DeleteBehavior.Restrict); }); modelBuilder.Entity(e => { e.Property(h => h.Type).HasConversion(); e.HasOne().WithMany() .HasForeignKey(h => h.GerbilId).OnDelete(DeleteBehavior.Cascade); }); modelBuilder.Entity(e => e.HasOne().WithMany() .HasForeignKey(w => w.GerbilId).OnDelete(DeleteBehavior.Cascade)); modelBuilder.Entity(e => e.HasOne().WithMany() .HasForeignKey(p => p.GerbilId).OnDelete(DeleteBehavior.Cascade)); // FEAT-13: Abgabeverträge + Zuchtprofil. modelBuilder.Entity(e => { e.Property(c => c.Price).HasPrecision(10, 2); // Restrict: ein Kontakt mit Verträgen ist ein Dokumentenbestand, // kein versehentlich löschbarer Datensatz. e.HasOne(c => c.Contact).WithMany() .HasForeignKey(c => c.ContactId).OnDelete(DeleteBehavior.Restrict); }); modelBuilder.Entity(e => { e.HasKey(a => new { a.SaleContractId, a.GerbilId }); e.HasOne().WithMany(c => c.Animals) .HasForeignKey(a => a.SaleContractId).OnDelete(DeleteBehavior.Cascade); // Cascade: wird ein Tier gelöscht, verschwindet nur die Verknüpfung — // der Vertrag (und seine .docx als Beleg) bleibt bestehen. e.HasOne(a => a.Gerbil).WithMany() .HasForeignKey(a => a.GerbilId).OnDelete(DeleteBehavior.Cascade); }); // Zuchtprofil: genau eine (leere) Zeile mit fixer Id. modelBuilder.Entity() .HasData(new BreederSettings { Id = GerbilManagerWebAPI.Models.BreederSettings.SingletonId }); SeedColorVarieties(modelBuilder); } /// /// Seed the colour-variety catalog. Source of truth = Kevin's GEN-2 generated list /// (gerbil-manager-web/src/genetics/colorVarietySeed.generated.json): 73 varieties /// (the 18 frozen-contract names first, then the baseportal.de extension), in stable /// SortOrder. Names are UI filter keys — spelling changes route through god. /// private static void SeedColorVarieties(ModelBuilder modelBuilder) { (string Name, string Genotype)[] catalog = { ("Pink Eyed White (PEW)", "AA chch DD EE GG pp spsp rere"), ("Hermelin", "aa chch DD EE GG PP spsp rere"), ("Himalaya", "AA chch DD EE GG PP spsp rere"), ("Zobel", "aa cchmcchm DD EE gg PP spsp rere"), ("Schwarzschimmel", "AA CC DD efef GG PP spsp rere"), ("Rotaugenschimmel", "AA CC DD efef GG pp spsp rere"), ("Agouti", "AA CC DD EE GG PP spsp rere"), ("Schwarz", "aa CC DD EE GG PP spsp rere"), ("Silberagouti", "AA CC DD EE gg PP spsp rere"), ("Anthrazit", "aa CC DD EE gg PP spsp rere"), ("Algierfuchs", "AA CC DD ee GG PP spsp rere"), ("Blau", "aa CC dd EE GG PP spsp rere"), ("Gold", "AA CC DD EE GG pp spsp rere"), ("Platin", "aa CC DD EE GG pp spsp rere"), ("Goldfuchs", "AA CC DD ee GG pp spsp rere"), ("Rotfuchs", "aa CC DD ee GG pp spsp rere"), ("dd Gold", "AA CC dd EE GG pp spsp rere"), ("dd Platin", "aa CC dd EE GG pp spsp rere"), ("Altweiss (REW)", "aa CC DD EE gg pp spsp rere"), ("Apricot (Blassfuchs)", "AA CC DD ee gg pp spsp rere"), ("Blaufuchs", "aa CC DD ee gg PP spsp rere"), ("C-Separator", "aa CC DD ee gg pp spsp rere"), ("Elfenbein", "AA CC DD EE gg pp spsp rere"), ("Kohlfuchs", "aa CC DD ee GG PP spsp rere"), ("Marder", "aa cchmcchm DD EE GG PP spsp rere"), ("Siam (Marder-Hell)", "aa cchmcchm DD EE GG PP spsp rere"), ("Polarfuchs", "AA CC DD ee gg PP spsp rere"), ("Saphir", "aa CC DD EE GG pp spsp rere"), ("Schimmel (Orangeschimmel)", "AA CC DD efef GG PP spsp rere"), ("Topas", "AA CC DD EE GG pp spsp rere"), ("Platin-Hell", "aa CC DD EE GG pp spsp rere"), ("Agouti dd", "AA CC dd EE GG PP spsp rere"), ("Silberagouti dd", "AA CC dd EE gg PP spsp rere"), ("Kohlfuchs dd", "aa CC dd ee GG PP spsp rere"), ("Anthrazit dd", "aa CC dd EE gg PP spsp rere"), ("Agouti CP-Hell", "AA cchmcchm DD EE GG PP spsp rere"), ("Blaufuchs CP", "aa cchmcchm DD ee gg PP spsp rere"), ("Polarfuchsschimmel", "AA CC DD efef gg PP spsp rere"), ("Silberschimmel", "AA CC DD efef gg PP spsp rere"), ("Algierfuchsschimmel", "AA CC DD efef GG PP spsp rere"), ("Polarfuchs-Hell CP", "AA cchmcchm DD ee gg PP spsp rere"), ("Kohlfuchsschimmel", "aa CC DD efef GG PP spsp rere"), ("Blaufuchsschimmel", "aa CC DD efef gg PP spsp rere"), ("Kohlfuchs, hell", "aa CC DD ee GG PP spsp rere"), ("Goldfuchs, hell", "AA CC DD ee GG pp spsp rere"), ("Goldfuchsschimmel", "AA CC DD efef GG pp spsp rere"), ("Gold-Hell", "AA CC DD EE GG pp spsp rere"), ("Siam (Marder-Hell) dd", "aa cchmcchm dd EE GG PP spsp rere"), ("Marder dd", "aa cchmcchm dd EE GG PP spsp rere"), ("Zobel-Hell", "aa cchmcchm DD EE gg PP spsp rere"), ("Silberagouti dd CP", "AA cchmcchm dd EE gg PP spsp rere"), ("Silberagouti-Hell dd CP", "AA cchmcchm dd EE gg PP spsp rere"), ("Agouti dd CP", "AA cchmcchm dd EE GG PP spsp rere"), ("Agouti-Hell dd CP", "AA cchmcchm dd EE GG PP spsp rere"), ("Blaufuchs, hell", "aa CC DD ee gg PP spsp rere"), ("Rotfuchsschimmel", "aa CC DD efef GG pp spsp rere"), ("Polarfuchs, hell", "AA CC DD ee gg PP spsp rere"), ("Kohlfuchsschimmel, hell", "aa CC DD efef GG PP spsp rere"), ("Rotfuchs, hell", "aa CC DD ee GG pp spsp rere"), ("Zobel dd", "aa cchmcchm dd EE gg PP spsp rere"), ("Kohlfuchs-Hell", "aa CC DD ee GG PP spsp rere"), ("Kohlfuchs CP", "aa cchmcchm DD ee GG PP spsp rere"), ("Algierfuchs CP", "AA cchmcchm DD ee GG PP spsp rere"), ("Silberagouti CP", "AA cchmcchm DD EE gg PP spsp rere"), ("Agouti CP", "AA cchmcchm DD EE GG PP spsp rere"), ("Algierfuchs-Hell CP", "AA cchmcchm DD ee GG PP spsp rere"), ("Kohlfuchs,hell CP", "aa cchmcchm DD ee GG PP spsp rere"), ("Polarfuchs CP", "AA cchmcchm DD ee gg PP spsp rere"), ("Algierfuchs, hell", "AA CC DD ee GG PP spsp rere"), ("Topas dd", "AA CC dd EE GG pp spsp rere"), ("Zobel-Hell dd", "aa cchmcchm dd EE gg PP spsp rere"), ("Kohlfuchsschimmel CP", "aa cchmcchm DD efef GG PP spsp rere"), ("Blaufuchs dd", "aa CC dd ee gg PP spsp rere"), }; var rows = new ColorVariety[catalog.Length]; for (int i = 0; i < catalog.Length; i++) { rows[i] = new ColorVariety { // Stable, deterministic GUIDs so the HasData seed is migration-stable. Id = new Guid($"00000000-0000-0000-0000-{(i + 1):D12}"), Name = catalog[i].Name, CanonicalGenotype = catalog[i].Genotype, SortOrder = i, }; } modelBuilder.Entity().HasData(rows); } }