using GameList.Domain; using Microsoft.EntityFrameworkCore; namespace GameList.Data; public class AppDbContext(DbContextOptions options) : DbContext(options) { public DbSet Players => Set(); public DbSet Suggestions => Set(); public DbSet Votes => Set(); public DbSet AppState => Set(); protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity(builder => { builder.HasKey(p => p.Id); builder.Property(p => p.DisplayName).HasMaxLength(16); builder.Property(p => p.Username).IsRequired().HasMaxLength(24); builder.Property(p => p.NormalizedUsername).IsRequired().HasMaxLength(24); builder.HasIndex(p => p.NormalizedUsername).IsUnique(); builder.Property(p => p.PasswordHash).IsRequired(); builder.Property(p => p.PasswordSalt).IsRequired(); builder.Property(p => p.PasswordHashVersion).HasDefaultValue(1); builder.Property(p => p.IsAdmin).HasDefaultValue(false); builder.Property(p => p.IsOwner).HasDefaultValue(false); builder.HasIndex(p => p.IsOwner).HasFilter($"{nameof(Player.IsOwner)} = 1").IsUnique(); builder.Property(p => p.HasJoker).HasDefaultValue(false); builder.Property(p => p.CurrentPhase).HasDefaultValue(Phase.Suggest); builder.Property(p => p.VotesFinal).HasDefaultValue(false); builder.HasMany(p => p.Suggestions).WithOne(s => s.Player!).HasForeignKey(s => s.PlayerId).OnDelete(DeleteBehavior.Cascade); builder.HasMany(p => p.Votes).WithOne(v => v.Player!).HasForeignKey(v => v.PlayerId).OnDelete(DeleteBehavior.Cascade); }); modelBuilder.Entity(builder => { builder.HasKey(s => s.Id); builder.Property(s => s.Name).IsRequired().HasMaxLength(100); builder.Property(s => s.Genre).HasMaxLength(50); builder.Property(s => s.Description).HasMaxLength(500); builder.Property(s => s.ScreenshotUrl).HasMaxLength(2048); builder.Property(s => s.YoutubeUrl).HasMaxLength(2048); builder.Property(s => s.GameUrl).HasMaxLength(2048); builder.Property(s => s.MinPlayers); builder.Property(s => s.MaxPlayers); builder.HasOne(s => s.ParentSuggestion).WithMany(p => p.LinkedSuggestions).HasForeignKey(s => s.ParentSuggestionId).OnDelete(DeleteBehavior.SetNull); builder.HasIndex(s => s.ParentSuggestionId); }); modelBuilder.Entity(builder => { builder.HasKey(v => v.Id); builder.Property(v => v.Score).IsRequired(); builder.HasIndex(v => new { v.PlayerId, v.SuggestionId }).IsUnique(); }); modelBuilder.Entity(builder => { builder.HasKey(s => s.Id); builder.HasData(new AppState { Id = 1, ResultsOpen = false, UpdatedAt = DateTimeOffset.UnixEpoch }); }); } }