using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Tiku.Domain.Content; using Tiku.Domain.Learning; namespace Tiku.Infrastructure.Persistence.Configurations; internal sealed class TargetDimensionDefinitionConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { builder.ConfigureEntity("target_dimension_definitions"); builder.ConfigureTimestamps(); builder.Property(entity => entity.Code).HasMaxLength(100); builder.Property(entity => entity.Name).HasMaxLength(200); builder.HasIndex(entity => entity.Code).IsUnique(); } } internal sealed class TargetNodeConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { builder.ConfigureEntity("target_nodes"); builder.ConfigureTimestamps(); builder.Property(entity => entity.Code).HasMaxLength(100); builder.Property(entity => entity.Name).HasMaxLength(300); builder.Property(entity => entity.Path).HasColumnType("ltree"); builder.HasIndex(entity => new { entity.TargetDimensionDefinitionId, entity.Code }).IsUnique(); builder.HasIndex(entity => entity.Path).HasMethod("gist"); builder.HasOne().WithMany() .HasForeignKey(entity => entity.TargetDimensionDefinitionId) .OnDelete(DeleteBehavior.Restrict); builder.HasOne().WithMany().HasForeignKey(entity => entity.ParentId) .OnDelete(DeleteBehavior.Restrict); } } internal sealed class ExamTargetProfileConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { builder.ConfigureEntity("exam_target_profiles"); builder.ConfigureTimestamps(); builder.Property(entity => entity.Code).HasMaxLength(150); builder.Property(entity => entity.Name).HasMaxLength(500); builder.HasIndex(entity => new { entity.BusinessLineId, entity.Code }).IsUnique(); builder.HasOne().WithMany().HasForeignKey(entity => entity.BusinessLineId) .OnDelete(DeleteBehavior.Restrict); builder.HasOne().WithMany() .HasForeignKey(entity => new { ExamTargetProfileId = entity.Id, Id = entity.CurrentVersionId }) .HasPrincipalKey(entity => new { entity.ExamTargetProfileId, entity.Id }) .OnDelete(DeleteBehavior.Restrict); } } internal sealed class ExamTargetProfileVersionConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { builder.ConfigureEntity("exam_target_profile_versions"); builder.HasAlternateKey(entity => new { entity.ExamTargetProfileId, entity.Id }); builder.Property(entity => entity.DisplayName).HasMaxLength(500); builder.Property(entity => entity.Status).HasSnakeCaseEnum(); builder.Property(entity => entity.CreatedAt).HasDefaultValueSql("now()"); builder.HasIndex(entity => new { entity.ExamTargetProfileId, entity.VersionNo }).IsUnique(); builder.HasOne().WithMany().HasForeignKey(entity => entity.ExamTargetProfileId) .OnDelete(DeleteBehavior.Cascade); } } internal sealed class ExamTargetProfileValueConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { builder.ConfigureEntity("exam_target_profile_values"); builder.HasIndex(entity => new { entity.ExamTargetProfileVersionId, entity.TargetDimensionDefinitionId, entity.TargetNodeId }).IsUnique(); builder.HasOne().WithMany() .HasForeignKey(entity => entity.ExamTargetProfileVersionId).OnDelete(DeleteBehavior.Cascade); builder.HasOne().WithMany() .HasForeignKey(entity => entity.TargetDimensionDefinitionId).OnDelete(DeleteBehavior.Restrict); builder.HasOne().WithMany().HasForeignKey(entity => entity.TargetNodeId) .OnDelete(DeleteBehavior.Restrict); } } internal sealed class BusinessTargetPolicyConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { builder.ConfigureEntity("business_target_policies"); builder.ConfigureTimestamps(); builder.HasIndex(entity => entity.BusinessLineId).IsUnique(); builder.HasOne().WithMany().HasForeignKey(entity => entity.BusinessLineId) .OnDelete(DeleteBehavior.Restrict); builder.HasOne().WithMany() .HasForeignKey(entity => new { BusinessTargetPolicyId = entity.Id, Id = entity.CurrentVersionId }) .HasPrincipalKey(entity => new { entity.BusinessTargetPolicyId, entity.Id }) .OnDelete(DeleteBehavior.Restrict); } } internal sealed class BusinessTargetPolicyVersionConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { builder.ConfigureEntity("business_target_policy_versions"); builder.HasAlternateKey(entity => new { entity.BusinessTargetPolicyId, entity.Id }); builder.Property(entity => entity.SelectionMode).HasSnakeCaseEnum(64); builder.Property(entity => entity.Status).HasSnakeCaseEnum(); builder.Property(entity => entity.CreatedAt).HasDefaultValueSql("now()"); builder.HasIndex(entity => new { entity.BusinessTargetPolicyId, entity.VersionNo }).IsUnique(); builder.HasOne().WithMany().HasForeignKey(entity => entity.BusinessTargetPolicyId) .OnDelete(DeleteBehavior.Cascade); builder.ToTable(table => { table.HasCheckConstraint("ck_business_target_policy_active", "max_active_targets between 1 and 16"); table.HasCheckConstraint("ck_business_target_policy_primary", "max_primary_targets between 0 and max_active_targets"); table.HasCheckConstraint("ck_business_target_policy_alternate", "max_alternate_targets between 0 and max_active_targets"); table.HasCheckConstraint("ck_business_target_policy_cooldown", "target_change_cooldown_days between 0 and 365"); }); } } internal sealed class BusinessTargetDimensionRequirementConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { builder.ConfigureEntity("business_target_dimension_requirements"); builder.HasIndex(entity => new { entity.BusinessTargetPolicyVersionId, entity.TargetDimensionDefinitionId }).IsUnique(); builder.HasOne().WithMany() .HasForeignKey(entity => entity.BusinessTargetPolicyVersionId).OnDelete(DeleteBehavior.Cascade); builder.HasOne().WithMany() .HasForeignKey(entity => entity.TargetDimensionDefinitionId).OnDelete(DeleteBehavior.Restrict); builder.ToTable(table => table.HasCheckConstraint( "ck_business_target_dimension_cardinality", "min_values >= 0 and max_values >= min_values")); } }