namespace QuestionsApi.Models; public class QuestionResponse { public string Id { get; set; } = ""; public string ExternalId { get; set; } = ""; public string Stem { get; set; } = ""; public string LeadIn { get; set; } = ""; public List Choices { get; set; } = []; public string CorrectChoiceId { get; set; } = ""; public string Explanation { get; set; } = ""; public Dictionary ChoiceExplanations { get; set; } = []; public Dictionary WrongAnswerFollowups { get; set; } = []; public Dictionary ChoiceSelectionPercentages { get; set; } = []; public string Discipline { get; set; } = ""; public string System { get; set; } = ""; public string PerformanceCategory { get; set; } = ""; public int Difficulty { get; set; } public int QuestionElo { get; set; } = 1000; public List Labs { get; set; } = []; public List Media { get; set; } = []; public List Tags { get; set; } = []; public static QuestionResponse FromModel( Question question, Dictionary? liveChoiceSelectionPercentages = null, int questionElo = 1000) => new() { Id = question.Id ?? "", ExternalId = question.ExternalId, Stem = question.Stem, LeadIn = question.LeadIn, Choices = question.Choices, CorrectChoiceId = question.CorrectChoiceId, Explanation = question.Explanation, ChoiceExplanations = question.ChoiceExplanations, WrongAnswerFollowups = question.WrongAnswerFollowups, ChoiceSelectionPercentages = BuildChoiceSelectionPercentages(question, liveChoiceSelectionPercentages), Discipline = question.Discipline, System = question.System, PerformanceCategory = RatingCategory.Normalize(question.PerformanceCategory, question.System, question.Discipline), Difficulty = question.Difficulty, QuestionElo = questionElo, Labs = question.Labs, Media = question.Media, Tags = question.Tags }; public static Dictionary BuildChoiceSelectionPercentages(Question question, Dictionary? liveChoiceSelectionPercentages) { if (liveChoiceSelectionPercentages is not { Count: > 0 }) return question.ChoiceSelectionPercentages; return question.Choices.ToDictionary( choice => choice.Id, choice => liveChoiceSelectionPercentages.GetValueOrDefault(choice.Id, 0)); } } public class FirstQuestionAttemptResponse { public string QuestionExternalId { get; set; } = ""; public Dictionary ChoiceSelectionPercentages { get; set; } = []; public int QuestionElo { get; set; } = 1000; public RatingChangeResponse? Rating { get; set; } } public class SkipQuestionResponse { public string QuestionExternalId { get; set; } = ""; public string CorrectChoiceId { get; set; } = ""; public Dictionary ChoiceSelectionPercentages { get; set; } = []; public int QuestionElo { get; set; } = 1000; public RatingChangeResponse? Rating { get; set; } } public static class RatingCategory { public const string Uncategorized = "Uncategorized"; public static readonly string[] Categories = [ "Renal/Urinary & Male/Female Systems & Pregnancy", "Behavioral Health & Social Sciences: Communication, Ethics, Patient Safety", "Immune/Blood & Lymphoreticular/Endocrine/Multisystem", "Biostatistics & Epidemiology/Population Health", "Musculoskeletal/Skin & Subcutaneous Tissue", "Cardiovascular System", "Nervous System & Special Senses", "Respiratory System", "Gastrointestinal System", Uncategorized ]; public static string Normalize(string? explicitCategory, string? system, string? discipline) { foreach (var value in new[] { explicitCategory, system, discipline }) { if (string.IsNullOrWhiteSpace(value)) continue; var normalized = Categories.FirstOrDefault(c => string.Equals(c, value.Trim(), StringComparison.OrdinalIgnoreCase)); if (normalized is not null) return normalized; var lower = value.ToLowerInvariant(); if (lower.Contains("cardio")) return "Cardiovascular System"; if (lower.Contains("resp")) return "Respiratory System"; if (lower.Contains("gastro") || lower.Contains("hepato")) return "Gastrointestinal System"; if (lower.Contains("neuro") || lower.Contains("special sense")) return "Nervous System & Special Senses"; if (lower.Contains("renal") || lower.Contains("urinary") || lower.Contains("pregnan") || lower.Contains("reproductive")) return "Renal/Urinary & Male/Female Systems & Pregnancy"; if (lower.Contains("behavior") || lower.Contains("ethic") || lower.Contains("communication") || lower.Contains("safety")) return "Behavioral Health & Social Sciences: Communication, Ethics, Patient Safety"; if (lower.Contains("immune") || lower.Contains("blood") || lower.Contains("endocrine") || lower.Contains("multisystem")) return "Immune/Blood & Lymphoreticular/Endocrine/Multisystem"; if (lower.Contains("biostat") || lower.Contains("epidemi") || lower.Contains("population")) return "Biostatistics & Epidemiology/Population Health"; if (lower.Contains("musculo") || lower.Contains("skin") || lower.Contains("derm")) return "Musculoskeletal/Skin & Subcutaneous Tissue"; } return Uncategorized; } }