using Core.Entities; namespace Core.Models; /// /// Result of parsing a student event ranking CSV. /// public class StudentEventRankingParseResult { /// /// Accepted ranking matches, including the raw CSV text and fuzzy scores. /// public List Matches { get; set; } = []; /// /// Unmatched students, unmatched or ambiguous events, and other row-level issues. /// public List Issues { get; set; } = []; /// /// Critical errors that prevented parsing (for example a missing header). /// public List Errors { get; set; } = []; /// /// Non-critical warnings about the file as a whole. /// public List Warnings { get; set; } = []; /// /// Accepted rankings without match metadata. /// public IReadOnlyList Rankings => [.. Matches.Select(m => m.Ranking)]; /// /// Number of accepted ranking rows. /// public int TotalParsed => Matches.Count; /// /// Distinct students who have at least one accepted rank. /// Uses Id when assigned, otherwise first and last name, so unsaved parsed students stay distinct. /// public IReadOnlyList StudentsWithAcceptedRanks => [.. Matches .Select(m => m.Ranking.Student) .GroupBy(s => s.Id != 0 ? $"id:{s.Id}" : $"name:{s.FirstName}|{s.LastName}") .Select(g => g.First())]; /// /// True when no critical parse errors were recorded. /// public bool IsSuccess => Errors.Count == 0; } /// /// A successfully matched ranking cell from the CSV. /// public class StudentEventRankingMatch { public required StudentEventRanking Ranking { get; set; } public string RawStudentName { get; set; } = string.Empty; public string RawEventName { get; set; } = string.Empty; public int StudentScore { get; set; } public int EventScore { get; set; } public int RowNumber { get; set; } } /// /// A row-level problem encountered while parsing rankings. /// public class StudentEventRankingIssue { public int RowNumber { get; set; } public int Rank { get; set; } public string RawStudentName { get; set; } = string.Empty; public string RawEventName { get; set; } = string.Empty; public StudentEventRankingIssueType IssueType { get; set; } public string Message { get; set; } = string.Empty; public string? SuggestedEventName { get; set; } public int? Score { get; set; } } /// /// Types of issues reported while parsing student event rankings. /// public enum StudentEventRankingIssueType { UnmatchedStudent, UnmatchedEvent, AmbiguousEvent, DuplicateEvent, DuplicateRank, InvalidFormat }