forked from gongxuegit/tiku-backend.net
feat: enforce tenant isolation and shared question bank
This commit is contained in:
@@ -65,72 +65,48 @@ internal sealed class ContentAssetSecurityScanEventConfiguration : IEntityTypeCo
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class QuestionBankGrantConfiguration : IEntityTypeConfiguration<QuestionBankGrant>
|
||||
internal sealed class TenantQuestionBankPreferenceConfiguration : IEntityTypeConfiguration<TenantQuestionBankPreference>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<QuestionBankGrant> builder)
|
||||
public void Configure(EntityTypeBuilder<TenantQuestionBankPreference> builder)
|
||||
{
|
||||
builder.ConfigureEntity("question_bank_grants");
|
||||
builder.ConfigureTenantEntity("tenant_question_bank_preferences");
|
||||
builder.ConfigureTimestamps();
|
||||
builder.Property(entity => entity.GrantScope).HasSnakeCaseEnum();
|
||||
builder.Property(entity => entity.AllowedPlanCodes)
|
||||
.HasColumnType("text[]")
|
||||
.HasDefaultValueSql("'{}'::text[]");
|
||||
builder.Property(entity => entity.AllowedTenantIds)
|
||||
.HasColumnType("uuid[]")
|
||||
.HasDefaultValueSql("'{}'::uuid[]");
|
||||
builder.Property(entity => entity.AllowedRegionIds)
|
||||
.HasColumnType("uuid[]")
|
||||
.HasDefaultValueSql("'{}'::uuid[]");
|
||||
builder.Property(entity => entity.AllowedSubjectIds)
|
||||
.HasColumnType("uuid[]")
|
||||
.HasDefaultValueSql("'{}'::uuid[]");
|
||||
builder.Property(entity => entity.Status).HasSnakeCaseEnum();
|
||||
builder.Property(entity => entity.Alias).HasMaxLength(300);
|
||||
builder.Property(entity => entity.NavigationLocation).HasMaxLength(100);
|
||||
builder.Property(entity => entity.Metadata).IsJson("{}");
|
||||
builder.HasIndex(entity => new { entity.SourceQuestionBankId, entity.Status, entity.StartsAt, entity.ExpiresAt });
|
||||
builder.HasIndex(entity => entity.AllowedTenantIds).HasMethod("gin");
|
||||
builder.HasIndex(entity => entity.AllowedPlanCodes).HasMethod("gin");
|
||||
builder.HasIndex(entity => new
|
||||
{
|
||||
entity.TenantId,
|
||||
entity.QuestionBankOwnerTenantId,
|
||||
entity.QuestionBankId
|
||||
}).IsUnique();
|
||||
builder.HasOne<QuestionBank>().WithMany()
|
||||
.HasForeignKey(entity => entity.SourceQuestionBankId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
.HasForeignKey(entity => new { entity.QuestionBankOwnerTenantId, entity.QuestionBankId })
|
||||
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
builder.HasOne<User>().WithMany().HasForeignKey(entity => entity.CreatedBy).OnDelete(DeleteBehavior.SetNull);
|
||||
builder.HasOne<User>().WithMany().HasForeignKey(entity => entity.UpdatedBy).OnDelete(DeleteBehavior.SetNull);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class TenantQuestionBankAdoptionConfiguration : IEntityTypeConfiguration<TenantQuestionBankAdoption>
|
||||
internal sealed class TenantQuestionReferenceConfiguration : IEntityTypeConfiguration<TenantQuestionReference>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<TenantQuestionBankAdoption> builder)
|
||||
public void Configure(EntityTypeBuilder<TenantQuestionReference> builder)
|
||||
{
|
||||
builder.ConfigureTenantEntity("tenant_question_bank_adoptions");
|
||||
builder.ConfigureTenantEntity("tenant_question_references");
|
||||
builder.ConfigureTimestamps();
|
||||
builder.Property(entity => entity.AdoptionMode).HasSnakeCaseEnum();
|
||||
builder.Property(entity => entity.Status).HasSnakeCaseEnum();
|
||||
builder.Property(entity => entity.SyncStatus).HasSnakeCaseEnum();
|
||||
builder.Property(entity => entity.SourceSnapshot).IsJson("{}");
|
||||
builder.Property(entity => entity.Metadata).IsJson("{}");
|
||||
builder.HasIndex(entity => new { entity.TenantId, entity.SourceQuestionBankId }).IsUnique();
|
||||
builder.HasIndex(entity => new { entity.TenantId, entity.Status, entity.UpdatedAt });
|
||||
builder.ToTable(table => table.HasCheckConstraint("ck_tenant_question_bank_adoptions_copied_count", "copied_question_count >= 0"));
|
||||
builder.HasOne<QuestionBank>().WithMany()
|
||||
.HasForeignKey(entity => entity.SourceQuestionBankId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
builder.HasOne<QuestionBankGrant>().WithMany()
|
||||
.HasForeignKey(entity => entity.GrantId)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
builder.HasOne<QuestionBank>().WithMany()
|
||||
.HasForeignKey(entity => new { entity.TenantId, entity.TargetQuestionBankId })
|
||||
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
builder.HasOne<ContentEntry>().WithMany()
|
||||
.HasForeignKey(entity => new { entity.TenantId, entity.TargetEntryId })
|
||||
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
builder.HasOne<QuestionCollection>().WithMany()
|
||||
.HasForeignKey(entity => new { entity.TenantId, entity.TargetCollectionId })
|
||||
builder.Property(entity => entity.Source).HasSnakeCaseEnum();
|
||||
builder.HasAlternateKey(entity => new
|
||||
{
|
||||
entity.TenantId,
|
||||
entity.QuestionOwnerTenantId,
|
||||
entity.QuestionId
|
||||
});
|
||||
builder.HasOne<Question>().WithMany()
|
||||
.HasForeignKey(entity => new { entity.QuestionOwnerTenantId, entity.QuestionId })
|
||||
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
builder.HasOne<User>().WithMany().HasForeignKey(entity => entity.CreatedBy).OnDelete(DeleteBehavior.SetNull);
|
||||
builder.HasOne<User>().WithMany().HasForeignKey(entity => entity.UpdatedBy).OnDelete(DeleteBehavior.SetNull);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user