using Microsoft.EntityFrameworkCore; using W542.GandalfReborn.Data.Entities.App; using W542.GandalfReborn.Data.Entities.Base; using W542.GandalfReborn.Data.Entities.Security; using W542.GandalfReborn.Data.Entities.Subject; using W542.GandalfReborn.Data.Entities.Subject.SignIn; using W542.GandalfReborn.Data.Entities.Tenant; namespace W542.GandalfReborn.Data.Database; public abstract class CoreContext(DbContextOptions options) : DbContext(options) where T : DbContext { public DbSet Tenants { get; set; } public DbSet Subjects { get; set; } public DbSet Apps { get; set; } public DbSet TenantSubjectRelations { get; set; } public DbSet AppSubjectRelations { get; set; } public DbSet AuthorityEntities { get; set; } public DbSet TokenMetadata { get; set; } public DbSet AuthCodes { get; set; } public DbSet AppsVersions { get; set; } public DbSet TenantVersions { get; set; } public DbSet AppSubjectRelationVersions { get; set; } public DbSet TenantSubjectRelationVersions { get; set; } public DbSet AppSubjectRelationInternalAuthorityRelationVersions { get; set; } public DbSet TenantSubjectRelationInternalAuthorityRelationVersions { get; set; } protected override void OnModelCreating(ModelBuilder builder) { #region Tenant var tenantBuilder = builder.Entity(); tenantBuilder .HasMany(x => x.Subjects) .WithMany(x => x.Tenants) .UsingEntity( r => r .HasOne(x => x.Subject) .WithMany() .HasForeignKey(x => x.SubjectId), l => l .HasOne(x => x.Tenant) .WithMany() .HasForeignKey(x => x.TenantId), j => j .HasKey(x => new { x.SubjectId, x.TenantId }) ); tenantBuilder .HasOne(x => x.Owner) .WithMany() .HasForeignKey(x => x.OwnerId) .IsRequired(); #endregion #region TenantSubjectRelation var tenantSubjectRelationBuilder = builder.Entity(); tenantSubjectRelationBuilder .HasMany(x => x.InternalAuthorities) .WithMany(x => x.TenantSubjectRelations) .UsingEntity( r => r .HasOne(x => x.InternalAuthority) .WithMany() .HasForeignKey(x => x.InternalAuthorityId), l => l .HasOne(x => x.TenantSubjectRelation) .WithMany() .HasForeignKey(x => new { x.SubjectId, x.TenantId }), j => j .HasKey(x => new { x.SubjectId, x.TenantId, x.InternalAuthorityId }) ) .HasKey(x => new { x.SubjectId, x.TenantId }); #endregion #region Subject var subjectBuilder = builder.Entity(); subjectBuilder .HasMany(x => x.SignInMethods) .WithOne(x => x.Subject) .HasForeignKey(x => x.SubjectId) .IsRequired(); subjectBuilder .HasIndex(x => x.Name) .IsUnique(); subjectBuilder .HasData(new SubjectEntity { Id = 1, Visibility = EntityVisibility.Active, Name = "chris" }); #endregion #region SighnIns var signInBuilder = builder.Entity(); signInBuilder .HasIndex(x => x.Email) .IsUnique(); #endregion #region App var appBuilder = builder.Entity(); appBuilder .HasMany(x => x.Subjects) .WithMany(x => x.Apps) .UsingEntity( r => r .HasOne(x => x.Subject) .WithMany() .HasForeignKey(x => x.SubjectId), l => l .HasOne(x => x.App) .WithMany() .HasForeignKey(x => x.AppId), j => j .HasKey(x => new { x.SubjectId, x.AppId }) ); appBuilder .HasOne(x => x.Tenant) .WithMany(x => x.Apps) .HasForeignKey(x => x.TenantId); #endregion #region AppSubjectRelation var appSubjectRelationBuilder = builder.Entity(); appSubjectRelationBuilder .HasMany(x => x.InternalAuthorities) .WithMany(x => x.AppSubjectRelations) .UsingEntity( r => r .HasOne(x => x.InternalAuthority) .WithMany() .HasForeignKey(x => x.InternalAuthorityId), l => l .HasOne(x => x.AppSubjectRelation) .WithMany() .HasForeignKey(x => new { x.SubjectId, x.AppId }), j => j .HasKey(x => new { x.SubjectId, x.AppId, x.InternalAuthorityId }) ) .HasKey(x => new { x.SubjectId, x.AppId }); #endregion #region Authority var authorityBuilder = builder.Entity(); authorityBuilder .HasData( new AuthorityEntity { Id = 1, Type = AuthorityType.Tenant, Name = "Tenant_Read", Description = "Allows users to read tenants" }, new AuthorityEntity { Id = 2, Type = AuthorityType.App, Name = "App_Read", Description = "Allows users to read apps" } ); authorityBuilder .HasKey(x => x.Id); authorityBuilder .HasIndex(x => x.Name) .IsUnique(); #endregion #region Tokens builder.Entity(); #endregion #region AuthCodes builder.Entity(); #endregion } }