Files
tiku-backend.net/Tiku.Infrastructure/Persistence/Configurations/ContentV2AssessmentConfigurations.cs
xiong 3f5957d744
Some checks failed
ci / release-gate (push) Has been cancelled
feat(content): establish v2 learning delivery foundation
2026-08-06 09:52:18 +08:00

115 lines
5.8 KiB
C#

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Tiku.Domain.Content;
using Tiku.Domain.Learning;
namespace Tiku.Infrastructure.Persistence.Configurations;
internal sealed class AssessmentPolicyConfiguration : IEntityTypeConfiguration<AssessmentPolicy>
{
public void Configure(EntityTypeBuilder<AssessmentPolicy> builder)
{
builder.ConfigureTenantEntity("assessment_policies");
builder.ConfigureTimestamps();
builder.Property(entity => entity.Code).HasMaxLength(100);
builder.Property(entity => entity.Name).HasMaxLength(300);
builder.HasIndex(entity => new { entity.TenantId, entity.Code }).IsUnique();
builder.HasOne<BusinessLine>().WithMany().HasForeignKey(entity => entity.BusinessLineId)
.OnDelete(DeleteBehavior.Restrict);
builder.HasOne<AssessmentPolicyVersion>().WithMany()
.HasForeignKey(entity => new { entity.TenantId, AssessmentPolicyId = entity.Id, Id = entity.CurrentVersionId })
.HasPrincipalKey(entity => new { entity.TenantId, entity.AssessmentPolicyId, entity.Id })
.OnDelete(DeleteBehavior.Restrict);
}
}
internal sealed class AssessmentPolicyVersionConfiguration : IEntityTypeConfiguration<AssessmentPolicyVersion>
{
public void Configure(EntityTypeBuilder<AssessmentPolicyVersion> builder)
{
builder.ConfigureTenantOwned("assessment_policy_versions");
builder.HasAlternateKey(entity => new { entity.TenantId, entity.AssessmentPolicyId, entity.Id });
builder.Property(entity => entity.GradingMode).HasSnakeCaseEnum();
builder.Property(entity => entity.Status).HasSnakeCaseEnum();
builder.Property(entity => entity.CreatedAt).HasDefaultValueSql("now()");
builder.HasIndex(entity => new { entity.TenantId, entity.AssessmentPolicyId, entity.VersionNo }).IsUnique();
builder.HasOne<AssessmentPolicy>().WithMany()
.HasForeignKey(entity => new { entity.TenantId, Id = entity.AssessmentPolicyId })
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
.OnDelete(DeleteBehavior.Cascade);
builder.ToTable(table =>
{
table.HasCheckConstraint("ck_assessment_policy_default_score", "default_score > 0");
table.HasCheckConstraint("ck_assessment_policy_rounding", "rounding_scale between 0 and 6");
});
}
}
internal sealed class ObjectiveGradingRuleConfiguration : IEntityTypeConfiguration<ObjectiveGradingRule>
{
public void Configure(EntityTypeBuilder<ObjectiveGradingRule> builder)
{
builder.ConfigureTenantOwned("objective_grading_rules");
builder.Property(entity => entity.RuleType).HasMaxLength(100);
builder.Property(entity => entity.Configuration).IsJson("{}");
builder.HasIndex(entity => new { entity.TenantId, entity.AssessmentPolicyVersionId, entity.RuleType }).IsUnique();
builder.HasOne<AssessmentPolicyVersion>().WithMany()
.HasForeignKey(entity => new { entity.TenantId, Id = entity.AssessmentPolicyVersionId })
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
.OnDelete(DeleteBehavior.Cascade);
}
}
internal sealed class SubjectiveRubricConfiguration : IEntityTypeConfiguration<SubjectiveRubric>
{
public void Configure(EntityTypeBuilder<SubjectiveRubric> builder)
{
builder.ConfigureTenantOwned("subjective_rubrics");
builder.Property(entity => entity.Code).HasMaxLength(100);
builder.Property(entity => entity.Name).HasMaxLength(300);
builder.Property(entity => entity.Criteria).IsJson("[]");
builder.HasIndex(entity => new { entity.TenantId, entity.AssessmentPolicyVersionId, entity.Code }).IsUnique();
builder.HasOne<AssessmentPolicyVersion>().WithMany()
.HasForeignKey(entity => new { entity.TenantId, Id = entity.AssessmentPolicyVersionId })
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
.OnDelete(DeleteBehavior.Cascade);
builder.ToTable(table => table.HasCheckConstraint("ck_subjective_rubric_max_score", "max_score > 0"));
}
}
internal sealed class AssessmentScoreBandConfiguration : IEntityTypeConfiguration<AssessmentScoreBand>
{
public void Configure(EntityTypeBuilder<AssessmentScoreBand> builder)
{
builder.ConfigureTenantOwned("assessment_score_bands");
builder.Property(entity => entity.Label).HasMaxLength(100);
builder.HasIndex(entity => new
{
entity.TenantId,
entity.AssessmentPolicyVersionId,
entity.MinScore,
entity.MaxScore
}).IsUnique();
builder.HasOne<AssessmentPolicyVersion>().WithMany()
.HasForeignKey(entity => new { entity.TenantId, Id = entity.AssessmentPolicyVersionId })
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
.OnDelete(DeleteBehavior.Cascade);
builder.ToTable(table => table.HasCheckConstraint("ck_assessment_score_band", "max_score >= min_score"));
}
}
internal sealed class ScoreAdjustmentRuleConfiguration : IEntityTypeConfiguration<ScoreAdjustmentRule>
{
public void Configure(EntityTypeBuilder<ScoreAdjustmentRule> builder)
{
builder.ConfigureTenantOwned("score_adjustment_rules");
builder.Property(entity => entity.RuleType).HasMaxLength(100);
builder.Property(entity => entity.Configuration).IsJson("{}");
builder.HasIndex(entity => new { entity.TenantId, entity.AssessmentPolicyVersionId, entity.Priority }).IsUnique();
builder.HasOne<AssessmentPolicyVersion>().WithMany()
.HasForeignKey(entity => new { entity.TenantId, Id = entity.AssessmentPolicyVersionId })
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
.OnDelete(DeleteBehavior.Cascade);
}
}