134 lines
6.6 KiB
C#
134 lines
6.6 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 KnowledgeConceptConfiguration : IEntityTypeConfiguration<KnowledgeConcept>
|
|
{
|
|
public void Configure(EntityTypeBuilder<KnowledgeConcept> builder)
|
|
{
|
|
builder.ConfigureTenantEntity("knowledge_concepts");
|
|
builder.ConfigureTimestamps();
|
|
builder.Property(entity => entity.Code).HasMaxLength(100);
|
|
builder.Property(entity => entity.Name).HasMaxLength(300);
|
|
builder.Property(entity => entity.Description).HasMaxLength(2000);
|
|
builder.HasIndex(entity => new { entity.TenantId, entity.Code }).IsUnique();
|
|
}
|
|
}
|
|
|
|
internal sealed class CurriculumConfiguration : IEntityTypeConfiguration<Curriculum>
|
|
{
|
|
public void Configure(EntityTypeBuilder<Curriculum> builder)
|
|
{
|
|
builder.ConfigureTenantEntity("curricula");
|
|
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<CurriculumVersion>().WithMany()
|
|
.HasForeignKey(entity => new { entity.TenantId, CurriculumId = entity.Id, Id = entity.CurrentVersionId })
|
|
.HasPrincipalKey(entity => new { entity.TenantId, entity.CurriculumId, entity.Id })
|
|
.OnDelete(DeleteBehavior.Restrict);
|
|
}
|
|
}
|
|
|
|
internal sealed class CurriculumVersionConfiguration : IEntityTypeConfiguration<CurriculumVersion>
|
|
{
|
|
public void Configure(EntityTypeBuilder<CurriculumVersion> builder)
|
|
{
|
|
builder.ConfigureTenantOwned("curriculum_versions");
|
|
builder.HasAlternateKey(entity => new { entity.TenantId, entity.CurriculumId, entity.Id });
|
|
builder.Property(entity => entity.Name).HasMaxLength(300);
|
|
builder.Property(entity => entity.Status).HasSnakeCaseEnum();
|
|
builder.Property(entity => entity.CreatedAt).HasDefaultValueSql("now()");
|
|
builder.HasIndex(entity => new { entity.TenantId, entity.CurriculumId, entity.VersionNo }).IsUnique();
|
|
builder.HasOne<Curriculum>().WithMany()
|
|
.HasForeignKey(entity => new { entity.TenantId, Id = entity.CurriculumId })
|
|
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
|
.OnDelete(DeleteBehavior.Cascade);
|
|
}
|
|
}
|
|
|
|
internal sealed class CurriculumNodeConfiguration : IEntityTypeConfiguration<CurriculumNode>
|
|
{
|
|
public void Configure(EntityTypeBuilder<CurriculumNode> builder)
|
|
{
|
|
builder.ConfigureTenantEntity("curriculum_nodes");
|
|
builder.ConfigureTimestamps();
|
|
builder.Property(entity => entity.Code).HasMaxLength(100);
|
|
builder.Property(entity => entity.Name).HasMaxLength(300);
|
|
builder.Property(entity => entity.Kind).HasSnakeCaseEnum();
|
|
builder.HasIndex(entity => new { entity.TenantId, entity.CurriculumVersionId, entity.Code }).IsUnique();
|
|
builder.HasIndex(entity => new { entity.TenantId, entity.CurriculumVersionId, entity.ParentId, entity.SortOrder });
|
|
builder.HasOne<CurriculumVersion>().WithMany()
|
|
.HasForeignKey(entity => new { entity.TenantId, Id = entity.CurriculumVersionId })
|
|
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
|
.OnDelete(DeleteBehavior.Cascade);
|
|
builder.HasOne<CurriculumNode>().WithMany()
|
|
.HasForeignKey(entity => new { entity.TenantId, Id = entity.ParentId })
|
|
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
|
.OnDelete(DeleteBehavior.Restrict);
|
|
builder.HasOne<KnowledgeConcept>().WithMany()
|
|
.HasForeignKey(entity => new { entity.TenantId, Id = entity.KnowledgeConceptId })
|
|
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
|
.OnDelete(DeleteBehavior.Restrict);
|
|
}
|
|
}
|
|
|
|
internal sealed class CurriculumNodeClosureConfiguration : IEntityTypeConfiguration<CurriculumNodeClosure>
|
|
{
|
|
public void Configure(EntityTypeBuilder<CurriculumNodeClosure> builder)
|
|
{
|
|
builder.ConfigureTenantOwned("curriculum_node_closure");
|
|
builder.HasIndex(entity => new
|
|
{
|
|
entity.TenantId,
|
|
entity.CurriculumVersionId,
|
|
entity.AncestorNodeId,
|
|
entity.DescendantNodeId
|
|
}).IsUnique();
|
|
builder.HasIndex(entity => new { entity.TenantId, entity.CurriculumVersionId, entity.DescendantNodeId, entity.Depth });
|
|
builder.ToTable(table => table.HasCheckConstraint("ck_curriculum_node_closure_depth", "depth >= 0"));
|
|
}
|
|
}
|
|
|
|
internal sealed class ExamPaperSpecificationConfiguration : IEntityTypeConfiguration<ExamPaperSpecification>
|
|
{
|
|
public void Configure(EntityTypeBuilder<ExamPaperSpecification> builder)
|
|
{
|
|
builder.ConfigureTenantEntity("exam_paper_specifications");
|
|
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);
|
|
}
|
|
}
|
|
|
|
internal sealed class ExamPaperSpecificationVersionConfiguration :
|
|
IEntityTypeConfiguration<ExamPaperSpecificationVersion>
|
|
{
|
|
public void Configure(EntityTypeBuilder<ExamPaperSpecificationVersion> builder)
|
|
{
|
|
builder.ConfigureTenantOwned("exam_paper_specification_versions");
|
|
builder.Property(entity => entity.Sections).IsJson("[]");
|
|
builder.Property(entity => entity.Status).HasSnakeCaseEnum();
|
|
builder.Property(entity => entity.CreatedAt).HasDefaultValueSql("now()");
|
|
builder.HasIndex(entity => new { entity.TenantId, entity.SpecificationId, entity.VersionNo }).IsUnique();
|
|
builder.HasOne<ExamPaperSpecification>().WithMany()
|
|
.HasForeignKey(entity => new { entity.TenantId, Id = entity.SpecificationId })
|
|
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
|
.OnDelete(DeleteBehavior.Cascade);
|
|
builder.ToTable(table =>
|
|
{
|
|
table.HasCheckConstraint("ck_exam_paper_spec_duration", "duration_minutes > 0");
|
|
table.HasCheckConstraint("ck_exam_paper_spec_total_score", "total_score > 0");
|
|
});
|
|
}
|
|
}
|