using DigitalData.EmailProfilerDispatcher.Abstraction.Entities; using DigitalData.UserManager.Domain.Entities; using DigitalData.UserManager.Infrastructure; using DigitalData.UserManager.Infrastructure.Contracts; using EnvelopeGenerator.Domain.Entities; using Microsoft.EntityFrameworkCore; using Group = DigitalData.UserManager.Domain.Entities.Group; using Module = DigitalData.UserManager.Domain.Entities.Module; using DigitalData.EmailProfilerDispatcher; using Microsoft.Extensions.Options; using EnvelopeGenerator.Application.Configurations; using DigitalData.Core.Client; using Microsoft.Extensions.Logging; namespace EnvelopeGenerator.Infrastructure; //TODO: Adding EmailOut instead of EmailOut.Abst is not correct for the arch. Re-design EmailPut consedering this. IMailDbContext shoud move to Abstraction layer (hint: in this case using DBSet in abst. will be problem because entity framework will have to be added. public class EGDbContext : DbContext, IUserManagerDbContext, IMailDbContext { public DbSet Configs { get; set; } public DbSet EnvelopeReceivers { get; set; } public DbSet Envelopes { get; set; } public DbSet DocumentReceiverElements { get; set; } public DbSet DocumentStatus { get; set; } public DbSet EmailTemplate { get; set; } public DbSet EnvelopeDocument { get; set; } public DbSet EnvelopeHistories { get; set; } public DbSet EnvelopeTypes { get; set; } public DbSet Receivers { get; set; } public DbSet GroupOfUsers { get; set; } public DbSet Groups { get; set; } public DbSet ModuleOfUsers { get; set; } public DbSet Modules { get; set; } public DbSet Users { get; set; } public DbSet UserReps { get; set; } public DbSet EMailOuts { get; set; } public DbSet EnvelopeReceiverReadOnlys { get; set; } public DbSet ClientUsers { get; set; } private readonly DbTriggerParams _triggers; private readonly ILogger? _logger; public bool IsMigration { get; set; } = false; public EGDbContext(DbContextOptions options, IOptions triggerParamOptions, ILogger? logger = null) : base(options) { _triggers = triggerParamOptions.Value; _logger = logger; Configs = Set(); EnvelopeReceivers = Set(); Envelopes = Set(); DocumentReceiverElements = Set(); DocumentStatus = Set(); EnvelopeDocument = Set(); EnvelopeHistories = Set(); EnvelopeTypes = Set(); Receivers = Set(); GroupOfUsers = Set(); Groups = Set(); ModuleOfUsers = Set(); Modules = Set(); Users = Set(); UserReps = Set(); EMailOuts = Set(); EnvelopeReceiverReadOnlys = Set(); } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity().HasNoKey(); modelBuilder.Entity() .HasKey(er => new { er.EnvelopeId, er.ReceiverId }); modelBuilder.Entity(); modelBuilder.Entity(); modelBuilder.Entity(); modelBuilder.Entity(); modelBuilder.Entity() .HasIndex(e => e.Uuid) .IsUnique(); modelBuilder.Entity(); modelBuilder.Entity(); modelBuilder.Entity() .HasIndex(e => e.Signature) .IsUnique(); modelBuilder.Entity() .HasIndex(e => e.EmailAddress) .IsUnique(); modelBuilder.Entity(); // Configure the one-to-many relationship of Envelope modelBuilder.Entity() .HasMany(e => e.Documents) .WithOne() .HasForeignKey(ed => ed.EnvelopeId); modelBuilder.Entity() .HasMany(e => e.History) .WithOne() .HasForeignKey(eh => eh.EnvelopeId); modelBuilder.Entity() .HasMany(ed => ed.Elements) .WithOne(e => e.Document) .HasForeignKey(e => e.DocumentId); modelBuilder.Entity() .HasOne(dre => dre.Document) .WithMany(ed => ed.Elements) .HasForeignKey(dre => dre.DocumentId); if (!IsMigration) { modelBuilder.Entity() .HasOne(eh => eh.Receiver) .WithMany() .HasForeignKey(eh => eh.UserReference) .HasPrincipalKey(e => e.EmailAddress); modelBuilder.Entity() .HasOne(eh => eh.Sender) .WithMany() .HasForeignKey(eh => eh.UserReference) .HasPrincipalKey(e => e.Email); } modelBuilder.Entity() .HasOne(erro => erro.Receiver) .WithMany() .HasForeignKey(erro => erro.AddedWho) .HasPrincipalKey(r => r.EmailAddress); modelBuilder.Entity() .HasOne(ds => ds.Envelope) .WithMany() .HasForeignKey(ds => ds.EnvelopeId); modelBuilder.Entity() .HasOne(ds => ds.Receiver) .WithMany() .HasForeignKey(ds => ds.ReceiverId); modelBuilder.Entity() .HasOne(ds => ds.Receiver) .WithMany() .HasForeignKey(ds => ds.ReceiverId); // Configure entities to handle database triggers void AddTrigger() where T : class => _triggers .Where(t => t.Key == typeof(T).Name) .SelectMany(t => t.Value) .ForEach(tName => { modelBuilder.Entity().ToTable(tb => tb.HasTrigger(tName)); _logger?.LogInformation("Trigger '{triggerName}' has been added to the '{entityName}' entity.", tName, typeof(T).Name); }); // TODO: call add trigger methods with attributes and reflection AddTrigger(); AddTrigger(); AddTrigger(); AddTrigger(); AddTrigger(); AddTrigger(); AddTrigger(); AddTrigger(); AddTrigger(); AddTrigger(); AddTrigger(); AddTrigger(); //configure model builder for user manager tables modelBuilder.ConfigureUserManager(); base.OnModelCreating(modelBuilder); } }