Implement requested workflow and UI updates

This commit is contained in:
biss committed 2026-08-18 10:16:02 +08:00
1 parent 5959585864
commit 390d0b123f
18 files changed
+7800 -35

No files matched your search

@@ -59,6 +59,11 @@ public sealed class CourseSubstitution : EntityBase
public Course? OriginalCourse { get; set; }
public Guid SubstituteCourseId { get; set; }
public Course? SubstituteCourse { get; set; }
// The published rule that authorized this exception. Keeping it on the
// application makes later curriculum and audit results explainable even
// when course metadata changes.
public Guid? CourseEquivalencyRuleId { get; set; }
public CourseEquivalencyRule? CourseEquivalencyRule { get; set; }
public required string Reason { get; set; }
public ApprovalStatus Status { get; set; } = ApprovalStatus.Submitted;
public string? ReviewComment { get; set; }
@@ -67,6 +72,21 @@ public sealed class CourseSubstitution : EntityBase
public Guid? ReviewedByUserId { get; set; }
}
// A formal, reusable replacement relationship. Applications may only use an
// enabled rule; approval remains a student-specific decision.
public sealed class CourseEquivalencyRule : EntityBase
{
public Guid OriginalCourseId { get; set; }
public Course? OriginalCourse { get; set; }
public Guid SubstituteCourseId { get; set; }
public Course? SubstituteCourse { get; set; }
public Guid? MajorId { get; set; }
public Major? Major { get; set; }
public int? EffectiveGrade { get; set; }
public bool IsEnabled { get; set; } = true;
public string? Notes { get; set; }
}
public enum ApprovalStatus
{
Submitted = 1,
@@ -49,6 +49,10 @@ public sealed class CourseEnrollment : EntityBase
public EnrollmentType EnrollmentType { get; set; } = EnrollmentType.Normal;
public DateTime EnrolledAt { get; set; } = DateTime.UtcNow;
public DateTime? WaitlistedAt { get; set; }
// Kept after the queue entry leaves the active list so students and staff
// can see why a particular candidate did or did not move forward.
public DateTime? WaitlistResolvedAt { get; set; }
public string? WaitlistResolutionReason { get; set; }
public DateTime? WithdrawnAt { get; set; }
}