forked from xiongyuxing/tiku-backend.net
159 lines
9.3 KiB
C#
159 lines
9.3 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|
using Tiku.Domain.Catalog;
|
|
using Tiku.Domain.Content;
|
|
using Tiku.Domain.Identity;
|
|
using Tiku.Domain.QuestionBanks;
|
|
using Tiku.Domain.Tenancy;
|
|
|
|
namespace Tiku.Infrastructure.Persistence.Configurations;
|
|
|
|
internal sealed class ContentAssetAccessEventConfiguration : IEntityTypeConfiguration<ContentAssetAccessEvent>
|
|
{
|
|
public void Configure(EntityTypeBuilder<ContentAssetAccessEvent> builder)
|
|
{
|
|
builder.ConfigureEntity("content_asset_access_events");
|
|
builder.HasAlternateKey(entity => new { entity.TenantId, entity.Id });
|
|
builder.Property(entity => entity.ActorRole).HasSnakeCaseEnum();
|
|
builder.Property(entity => entity.AccessType).HasSnakeCaseEnum();
|
|
builder.Property(entity => entity.Visibility).HasMaxLength(50);
|
|
builder.Property(entity => entity.AssetType).HasMaxLength(50);
|
|
builder.Property(entity => entity.StorageProvider).HasMaxLength(50);
|
|
builder.Property(entity => entity.Disposition).HasNullableSnakeCaseEnum();
|
|
builder.Property(entity => entity.SignatureMode).HasMaxLength(100);
|
|
builder.Property(entity => entity.Result).HasSnakeCaseEnum();
|
|
builder.Property(entity => entity.DenyCode).HasMaxLength(100);
|
|
builder.Property(entity => entity.IpAddress).HasMaxLength(100);
|
|
builder.Property(entity => entity.UserAgent).HasMaxLength(1024);
|
|
builder.Property(entity => entity.Metadata).IsJson("{}");
|
|
builder.Property(entity => entity.CreatedAt).HasDefaultValueSql("now()");
|
|
builder.HasIndex(entity => new { entity.TenantId, entity.AssetId, entity.CreatedAt });
|
|
builder.HasIndex(entity => new { entity.TenantId, entity.UserId, entity.CreatedAt })
|
|
.HasFilter("user_id is not null");
|
|
builder.HasIndex(entity => new { entity.TenantId, entity.AccessType, entity.Result, entity.CreatedAt });
|
|
builder.ToTable(table => table.HasCheckConstraint("ck_content_asset_access_events_expiry", "expires_in_seconds is null or expires_in_seconds > 0"));
|
|
builder.HasOne<Tenant>().WithMany().HasForeignKey(entity => entity.TenantId).OnDelete(DeleteBehavior.Cascade);
|
|
builder.HasOne<ContentAsset>().WithMany()
|
|
.HasForeignKey(entity => new { entity.TenantId, entity.AssetId })
|
|
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
|
.OnDelete(DeleteBehavior.Restrict);
|
|
builder.HasOne<User>().WithMany().HasForeignKey(entity => entity.UserId).OnDelete(DeleteBehavior.SetNull);
|
|
}
|
|
}
|
|
|
|
internal sealed class ContentAssetSecurityScanEventConfiguration : IEntityTypeConfiguration<ContentAssetSecurityScanEvent>
|
|
{
|
|
public void Configure(EntityTypeBuilder<ContentAssetSecurityScanEvent> builder)
|
|
{
|
|
builder.ConfigureEntity("content_asset_security_scan_events");
|
|
builder.HasAlternateKey(entity => new { entity.TenantId, entity.Id });
|
|
builder.Property(entity => entity.Provider).HasMaxLength(100);
|
|
builder.Property(entity => entity.ScanStatus).HasSnakeCaseEnum();
|
|
builder.Property(entity => entity.RiskLevel).HasSnakeCaseEnum();
|
|
builder.Property(entity => entity.IssueCodes)
|
|
.HasColumnType("text[]")
|
|
.HasDefaultValueSql("'{}'::text[]");
|
|
builder.Property(entity => entity.Details).IsJson("{}");
|
|
builder.Property(entity => entity.CreatedAt).HasDefaultValueSql("now()");
|
|
builder.HasIndex(entity => new { entity.TenantId, entity.AssetId, entity.CreatedAt });
|
|
builder.HasIndex(entity => new { entity.TenantId, entity.ScanStatus, entity.RiskLevel, entity.CreatedAt });
|
|
builder.HasOne<Tenant>().WithMany().HasForeignKey(entity => entity.TenantId).OnDelete(DeleteBehavior.Cascade);
|
|
builder.HasOne<ContentAsset>().WithMany()
|
|
.HasForeignKey(entity => new { entity.TenantId, entity.AssetId })
|
|
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
|
.OnDelete(DeleteBehavior.Restrict);
|
|
}
|
|
}
|
|
|
|
internal sealed class QuestionBankGrantConfiguration : IEntityTypeConfiguration<QuestionBankGrant>
|
|
{
|
|
public void Configure(EntityTypeBuilder<QuestionBankGrant> builder)
|
|
{
|
|
builder.ConfigureEntity("question_bank_grants");
|
|
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.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.HasOne<QuestionBank>().WithMany()
|
|
.HasForeignKey(entity => entity.SourceQuestionBankId)
|
|
.OnDelete(DeleteBehavior.Cascade);
|
|
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>
|
|
{
|
|
public void Configure(EntityTypeBuilder<TenantQuestionBankAdoption> builder)
|
|
{
|
|
builder.ConfigureTenantEntity("tenant_question_bank_adoptions");
|
|
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 })
|
|
.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 AiRecommendationReportConfiguration : IEntityTypeConfiguration<AiRecommendationReport>
|
|
{
|
|
public void Configure(EntityTypeBuilder<AiRecommendationReport> builder)
|
|
{
|
|
builder.ConfigureTenantEntity("ai_recommendation_reports");
|
|
builder.ConfigureTimestamps();
|
|
builder.Property(entity => entity.Status).HasSnakeCaseEnum();
|
|
builder.Property(entity => entity.Provider).HasMaxLength(100);
|
|
builder.Property(entity => entity.Model).HasMaxLength(100);
|
|
builder.Property(entity => entity.PromptVersion).HasMaxLength(100);
|
|
builder.Property(entity => entity.InputPayload).IsJson("{}");
|
|
builder.Property(entity => entity.ContextPayload).IsJson("{}");
|
|
builder.Property(entity => entity.ResultPayload).IsJson("{}");
|
|
builder.HasIndex(entity => new { entity.TenantId, entity.UserId, entity.CreatedAt });
|
|
builder.HasIndex(entity => new { entity.TenantId, entity.RegionId, entity.CreatedAt });
|
|
builder.HasOne<User>().WithMany().HasForeignKey(entity => entity.UserId).OnDelete(DeleteBehavior.Cascade);
|
|
builder.HasOne<Region>().WithMany()
|
|
.HasForeignKey(entity => new { entity.TenantId, entity.RegionId })
|
|
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
|
.OnDelete(DeleteBehavior.Restrict);
|
|
}
|
|
}
|