using JobTrackerApi.Controllers; using JobTrackerApi.Models; namespace JobTrackerApi.Services; // Phase 3: the /career overview scorecard — "Profile completeness: 70%, missing: skills, projects". // Weighted so the sections that most affect a CV (identity, experience) count for more. public static class CareerCompleteness { private sealed record Section(string Key, string Label, int Weight, Func Count); private static readonly Section[] Sections = { new("personal", "Personal details", 20, p => (!string.IsNullOrWhiteSpace(p.Contact.FullName) ? 1 : 0) + (!string.IsNullOrWhiteSpace(p.Contact.Email) ? 1 : 0)), new("summary", "Professional summary", 10, p => p.Summary.Count(s => !string.IsNullOrWhiteSpace(s))), new("experience", "Experience", 25, p => p.Jobs.Count), new("education", "Education", 15, p => p.Education.Count), new("skills", "Skills", 15, p => p.Skills.Count(s => !string.IsNullOrWhiteSpace(s))), new("projects", "Projects", 10, p => p.Projects.Count), new("languages", "Languages", 5, p => p.Languages.Count), }; public static CareerCompletenessDto Evaluate(StructuredCvProfile profile) { var statuses = new List(); var missing = new List(); var earned = 0; var total = 0; foreach (var s in Sections) { total += s.Weight; var count = s.Count(profile); // "personal" needs both name + email (count 2); the rest need at least one item. var complete = s.Key == "personal" ? count >= 2 : count >= 1; if (complete) earned += s.Weight; else missing.Add(s.Label); statuses.Add(new CareerSectionStatusDto(s.Key, s.Label, complete, count)); } var percent = total == 0 ? 0 : (int)Math.Round(100.0 * earned / total); return new CareerCompletenessDto(percent, missing, statuses); } }