using Jiaowu.Api.Domain.Common; namespace Jiaowu.Api.Domain.Academic; public sealed class GradeSheet : EntityBase { public Guid TeachingTaskId { get; set; } public TeachingTask? TeachingTask { get; set; } public decimal RegularWeight { get; set; } = 30; public decimal FinalWeight { get; set; } = 70; public GradeSheetStatus Status { get; set; } = GradeSheetStatus.Draft; public string? ReviewComment { get; set; } public DateTime? SubmittedAt { get; set; } public DateTime? ReviewedAt { get; set; } public DateTime? PublishedAt { get; set; } public ICollection Records { get; set; } = []; public ICollection Items { get; set; } = []; } public sealed class GradeItem : EntityBase { public Guid GradeSheetId { get; set; } public GradeSheet? GradeSheet { get; set; } public required string Name { get; set; } public decimal Weight { get; set; } public int SortOrder { get; set; } public GradeItemSourceType SourceType { get; set; } = GradeItemSourceType.Manual; public DateTime? SourceSnapshotAt { get; set; } public ICollection Scores { get; set; } = []; } public sealed class GradeRecord : EntityBase { public Guid GradeSheetId { get; set; } public GradeSheet? GradeSheet { get; set; } public Guid StudentId { get; set; } public Student? Student { get; set; } public decimal? RegularScore { get; set; } public decimal? FinalScore { get; set; } public decimal? TotalScore { get; set; } public decimal? GradePoint { get; set; } public GradeExamStatus ExamStatus { get; set; } = GradeExamStatus.Normal; public string? Notes { get; set; } public ICollection ItemScores { get; set; } = []; } public sealed class GradeItemScore { public Guid GradeRecordId { get; set; } public GradeRecord? GradeRecord { get; set; } public Guid GradeItemId { get; set; } public GradeItem? GradeItem { get; set; } public decimal? Score { get; set; } } /// /// Persisted course-result aggregate. One course/term is materialized at each /// organizational level so the result-analysis page never aggregates raw /// grade records on request. /// public sealed class CourseGradeStatistic : EntityBase { public Guid CourseId { get; set; } public Guid AcademicTermId { get; set; } public CourseGradeStatisticScope Scope { get; set; } public Guid? ScopeEntityId { get; set; } public int StudentCount { get; set; } public int PassedCount { get; set; } public int Below60Count { get; set; } public int From60To69Count { get; set; } public int From70To79Count { get; set; } public int From80To89Count { get; set; } public int From90To100Count { get; set; } public decimal HighestScore { get; set; } public decimal AverageScore { get; set; } public decimal LowestScore { get; set; } public decimal PassRate { get; set; } public DateTime CalculatedAt { get; set; } } /// /// Materialized analysis for one published teaching class. Course/term /// organizational benchmarks stay in ; /// this table is the grain used for peer-class and historical comparisons. /// public sealed class TeachingTaskGradeStatistic : EntityBase { public Guid GradeSheetId { get; set; } public GradeSheet? GradeSheet { get; set; } public Guid TeachingTaskId { get; set; } public TeachingTask? TeachingTask { get; set; } public Guid CourseId { get; set; } public Guid AcademicTermId { get; set; } public int StudentCount { get; set; } public int PassedCount { get; set; } public int ExcellentCount { get; set; } public decimal HighestScore { get; set; } public decimal AverageScore { get; set; } public decimal MedianScore { get; set; } public decimal LowestScore { get; set; } public decimal StandardDeviation { get; set; } public decimal PassRate { get; set; } public decimal ExcellentRate { get; set; } public DateTime CalculatedAt { get; set; } public ICollection ScoreBands { get; set; } = []; } /// /// Flexible score-band rows are kept separately so future band definitions do /// not require widening the teaching-class summary table. /// public sealed class TeachingTaskGradeScoreBand : EntityBase { public Guid TeachingTaskGradeStatisticId { get; set; } public TeachingTaskGradeStatistic? TeachingTaskGradeStatistic { get; set; } public required string Label { get; set; } public decimal LowerBound { get; set; } public decimal? UpperBound { get; set; } public int StudentCount { get; set; } public int SortOrder { get; set; } } public enum CourseGradeStatisticScope { AdministrativeClass = 1, Major = 2, College = 3, University = 4 } public sealed class CourseGradeStatisticsRefreshJob : EntityBase { public Guid GradeSheetId { get; set; } public CourseGradeStatisticsRefreshJobStatus Status { get; set; } = CourseGradeStatisticsRefreshJobStatus.Queued; public DateTime? StartedAt { get; set; } public DateTime? CompletedAt { get; set; } public string? ErrorMessage { get; set; } } public enum CourseGradeStatisticsRefreshJobStatus { Queued = 1, Running = 2, Succeeded = 3, Failed = 4 } public enum GradeSheetStatus { Draft = 1, Submitted = 2, Approved = 3, Published = 4, Returned = 5 } public enum GradeExamStatus { Normal = 1, Absent = 2, Deferred = 3, Exempt = 4, Makeup = 5 } public enum GradeItemSourceType { Manual = 1, ExperimentSummary = 2 }