using MemberCenter.Domain.Entities; using MemberCenter.Infrastructure.Identity; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; namespace MemberCenter.Infrastructure.Persistence; public class MemberCenterDbContext : IdentityDbContext { public MemberCenterDbContext(DbContextOptions options) : base(options) { } public DbSet Tenants => Set(); public DbSet NewsletterLists => Set(); public DbSet NewsletterSubscriptions => Set(); public DbSet EmailVerifications => Set(); public DbSet UnsubscribeTokens => Set(); public DbSet AuditLogs => Set(); public DbSet SystemFlags => Set(); protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); builder.UseOpenIddict(); builder.Entity(entity => { entity.ToTable("tenants"); entity.HasKey(x => x.Id); entity.Property(x => x.Name).IsRequired(); entity.Property(x => x.Status).IsRequired().HasDefaultValue("active"); entity.Property(x => x.Domains).HasColumnType("text[]"); entity.Property(x => x.CreatedAt).HasDefaultValueSql("now()"); }); builder.Entity(entity => { entity.ToTable("newsletter_lists"); entity.HasKey(x => x.Id); entity.Property(x => x.Name).IsRequired(); entity.Property(x => x.Status).IsRequired().HasDefaultValue("active"); entity.Property(x => x.CreatedAt).HasDefaultValueSql("now()"); entity.HasOne(x => x.Tenant) .WithMany(t => t.NewsletterLists) .HasForeignKey(x => x.TenantId) .OnDelete(DeleteBehavior.Cascade); }); builder.Entity(entity => { entity.ToTable("newsletter_subscriptions"); entity.HasKey(x => x.Id); entity.Property(x => x.Email).IsRequired(); entity.Property(x => x.Status).IsRequired().HasDefaultValue("pending"); entity.Property(x => x.CreatedAt).HasDefaultValueSql("now()"); entity.Property(x => x.Preferences) .HasColumnType("jsonb") .HasConversion( v => v.RootElement.GetRawText(), v => System.Text.Json.JsonDocument.Parse(v, new System.Text.Json.JsonDocumentOptions())); entity.HasIndex(x => x.Email).HasDatabaseName("idx_newsletter_subscriptions_email"); entity.HasIndex(x => x.ListId).HasDatabaseName("idx_newsletter_subscriptions_list_id"); entity.HasIndex(x => new { x.ListId, x.Email }).IsUnique(); entity.HasOne(x => x.List) .WithMany(l => l.Subscriptions) .HasForeignKey(x => x.ListId) .OnDelete(DeleteBehavior.Cascade); entity.HasOne() .WithMany() .HasForeignKey(x => x.UserId) .OnDelete(DeleteBehavior.SetNull); }); builder.Entity(entity => { entity.ToTable("email_verifications"); entity.HasKey(x => x.Id); entity.Property(x => x.Email).IsRequired(); entity.Property(x => x.TokenHash).IsRequired(); entity.Property(x => x.Purpose).IsRequired(); entity.HasIndex(x => x.Email).HasDatabaseName("idx_email_verifications_email"); entity.HasOne() .WithMany() .HasForeignKey(x => x.TenantId) .OnDelete(DeleteBehavior.Cascade); }); builder.Entity(entity => { entity.ToTable("unsubscribe_tokens"); entity.HasKey(x => x.Id); entity.Property(x => x.TokenHash).IsRequired(); entity.HasOne(x => x.Subscription) .WithMany() .HasForeignKey(x => x.SubscriptionId) .OnDelete(DeleteBehavior.Cascade); }); builder.Entity(entity => { entity.ToTable("audit_logs"); entity.HasKey(x => x.Id); entity.Property(x => x.ActorType).IsRequired(); entity.Property(x => x.Action).IsRequired(); entity.Property(x => x.Payload) .HasColumnType("jsonb") .HasConversion( v => v.RootElement.GetRawText(), v => System.Text.Json.JsonDocument.Parse(v, new System.Text.Json.JsonDocumentOptions())); entity.Property(x => x.CreatedAt).HasDefaultValueSql("now()"); }); builder.Entity(entity => { entity.ToTable("system_flags"); entity.HasKey(x => x.Id); entity.Property(x => x.Key).IsRequired(); entity.Property(x => x.Value).IsRequired(); entity.Property(x => x.UpdatedAt).HasDefaultValueSql("now()"); entity.HasIndex(x => x.Key).IsUnique(); }); builder.Entity(entity => { entity.ToTable("users"); entity.Property(x => x.CreatedAt).HasDefaultValueSql("now()"); }); builder.Entity(entity => { entity.ToTable("roles"); entity.Property(x => x.CreatedAt).HasDefaultValueSql("now()"); }); builder.Entity>(entity => { entity.ToTable("user_roles"); }); builder.Entity>(entity => { entity.ToTable("user_claims"); }); builder.Entity>(entity => { entity.ToTable("role_claims"); }); builder.Entity>(entity => { entity.ToTable("user_logins"); }); builder.Entity>(entity => { entity.ToTable("user_tokens"); }); builder.Entity>().HasKey(l => new { l.LoginProvider, l.ProviderKey }); builder.Entity>().HasKey(t => new { t.UserId, t.LoginProvider, t.Name }); } }