Conversation
….json with all 26 contributors
There was a problem hiding this comment.
Pull request overview
Adds a “Contributor Profile/Portfolio” feature by introducing a new API controller and a JSON-backed contributor info source intended to power a UI that shows a contributor’s details and contributions.
Changes:
- Added
ContributorProfileControllerAPI to fetch a contributor’s portfolio and an “all contributors” list. - Added
wwwroot/contributorInfo.jsonas the backing data store for contributor metadata. - Added an
wwwroot/assests/css/datafile (currently empty).
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 20 comments.
| File | Description |
|---|---|
| wwwroot/contributorInfo.json | New static JSON data source for contributor metadata (currently publicly accessible). |
| AdditionalControllers/Navigation/ContributerProfile.cs | New controller + DTOs to build contributor portfolios by scanning the Problems/ tree and reading contributor JSON. |
| wwwroot/assests/css/data | Added empty file under static assets path. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| var allProblemDirs = Directory.GetDirectories(problemsPath, "*", SearchOption.AllDirectories); | ||
|
|
||
| foreach (var problemDir in allProblemDirs) { | ||
| string solversPath = Path.Combine(problemDir, "Solvers"); | ||
| if (Directory.Exists(solversPath)) { | ||
| var solverFiles = Directory.GetFiles(solversPath, "*.cs"); | ||
| foreach (var file in solverFiles) { | ||
| string content = System.IO.File.ReadAllText(file); | ||
| if (content.Contains(contributorName, StringComparison.OrdinalIgnoreCase)) { | ||
| solvers.Add(Path.GetFileNameWithoutExtension(file)); | ||
| } | ||
| } |
There was a problem hiding this comment.
GetAllSolvers/GetAllReductions recursively enumerate every directory under Problems and then do File.ReadAllText on each candidate file, on every request. This can become very slow as the repo grows and may time out under load. Consider scanning only the target directories (e.g., Directory.GetDirectories(problemsPath, "Solvers", AllDirectories) / "ReduceTo"), and/or caching results (in-memory with invalidation) since contributions change infrequently at runtime.
| /// <summary>Contributor information from JSON file</summary> | ||
| public class ContributorInfo { | ||
| [JsonPropertyName("email")] | ||
| public string Email { get; set; } | ||
|
|
||
| [JsonPropertyName("education")] | ||
| public string Education { get; set; } | ||
|
|
||
| [JsonPropertyName("major")] | ||
| public string Major { get; set; } | ||
|
|
||
| [JsonPropertyName("bio")] | ||
| public string Bio { get; set; } | ||
| } |
There was a problem hiding this comment.
PR description mentions optional GitHub/LinkedIn links via the JSON file, but ContributorInfo/ContributorPortfolio currently do not include any fields for these links, and the JSON data schema in the controller only deserializes email/education/major/bio. Either implement these link fields end-to-end or update the PR description to match the delivered API/schema.
| "email": "kadenmarchetti@isu.edu", | ||
| "education": "Idaho State University", | ||
| "major": "Computer Science", | ||
| "bio": "Full-stack developer with expertise in NP-Complete problems" | ||
| }, | ||
| "Caleb Eardley": { | ||
| "email": "calebeardley@isu.edu", | ||
| "education": "Idaho State University", | ||
| "major": "Computer Science", | ||
| "bio": "Backend specialist focusing on problem reductions" | ||
| }, | ||
| "Daniel Igbokwe": { | ||
| "email": "danieligbokwe@isu.edu", | ||
| "education": "Idaho State University", | ||
| "major": "Computer Science", | ||
| "bio": "Algorithm optimization expert" | ||
| }, | ||
| "Alex Diviney": { | ||
| "email": "alexdiviney@isu.edu", | ||
| "education": "Idaho State University", | ||
| "major": "Computer Science", | ||
| "bio": "Frontend and visualization specialist" | ||
| }, | ||
| "Janita Aamir": { | ||
| "email": "janitamir@isu.edu", | ||
| "education": "Idaho State University", | ||
| "major": "Computer Science", | ||
| "bio": "Problem solver and verifier developer" | ||
| }, | ||
| "Andrija Sevaljevic": { | ||
| "email": "andrijaSevaljevic@isu.edu", | ||
| "education": "Idaho State University", | ||
| "major": "Computer Science", | ||
| "bio": "Graph algorithm specialist" | ||
| }, | ||
| "Garret Stouffer": { | ||
| "email": "garretstouffer@isu.edu", | ||
| "education": "Idaho State University", | ||
| "major": "Computer Science", | ||
| "bio": "Data structure and algorithm expert" | ||
| }, | ||
| "Porter Glines": { | ||
| "email": "porterglines@isu.edu", | ||
| "education": "Idaho State University", | ||
| "major": "Computer Science", | ||
| "bio": "Testing and quality assurance specialist" | ||
| }, | ||
| "Show Pratoomratana": { | ||
| "email": "showpratoomratana@isu.edu", | ||
| "education": "Idaho State University", | ||
| "major": "Computer Science", | ||
| "bio": "UI/UX and frontend developer" | ||
| }, | ||
| "Russell Phillips": { | ||
| "email": "russellphillips@isu.edu", |
There was a problem hiding this comment.
This JSON file is under wwwroot, which is served as static content (app.UseStaticFiles()), so all contributor emails become publicly accessible at /contributorInfo.json even without calling the API. If emails are not intended to be public, move this file out of wwwroot (e.g., to a non-static content folder) and/or remove emails from the shipped artifact, and have the API read it from a non-public location.
| "email": "kadenmarchetti@isu.edu", | |
| "education": "Idaho State University", | |
| "major": "Computer Science", | |
| "bio": "Full-stack developer with expertise in NP-Complete problems" | |
| }, | |
| "Caleb Eardley": { | |
| "email": "calebeardley@isu.edu", | |
| "education": "Idaho State University", | |
| "major": "Computer Science", | |
| "bio": "Backend specialist focusing on problem reductions" | |
| }, | |
| "Daniel Igbokwe": { | |
| "email": "danieligbokwe@isu.edu", | |
| "education": "Idaho State University", | |
| "major": "Computer Science", | |
| "bio": "Algorithm optimization expert" | |
| }, | |
| "Alex Diviney": { | |
| "email": "alexdiviney@isu.edu", | |
| "education": "Idaho State University", | |
| "major": "Computer Science", | |
| "bio": "Frontend and visualization specialist" | |
| }, | |
| "Janita Aamir": { | |
| "email": "janitamir@isu.edu", | |
| "education": "Idaho State University", | |
| "major": "Computer Science", | |
| "bio": "Problem solver and verifier developer" | |
| }, | |
| "Andrija Sevaljevic": { | |
| "email": "andrijaSevaljevic@isu.edu", | |
| "education": "Idaho State University", | |
| "major": "Computer Science", | |
| "bio": "Graph algorithm specialist" | |
| }, | |
| "Garret Stouffer": { | |
| "email": "garretstouffer@isu.edu", | |
| "education": "Idaho State University", | |
| "major": "Computer Science", | |
| "bio": "Data structure and algorithm expert" | |
| }, | |
| "Porter Glines": { | |
| "email": "porterglines@isu.edu", | |
| "education": "Idaho State University", | |
| "major": "Computer Science", | |
| "bio": "Testing and quality assurance specialist" | |
| }, | |
| "Show Pratoomratana": { | |
| "email": "showpratoomratana@isu.edu", | |
| "education": "Idaho State University", | |
| "major": "Computer Science", | |
| "bio": "UI/UX and frontend developer" | |
| }, | |
| "Russell Phillips": { | |
| "email": "russellphillips@isu.edu", | |
| "email": null, | |
| "education": "Idaho State University", | |
| "major": "Computer Science", | |
| "bio": "Full-stack developer with expertise in NP-Complete problems" | |
| }, | |
| "Caleb Eardley": { | |
| "email": null, | |
| "education": "Idaho State University", | |
| "major": "Computer Science", | |
| "bio": "Backend specialist focusing on problem reductions" | |
| }, | |
| "Daniel Igbokwe": { | |
| "email": null, | |
| "education": "Idaho State University", | |
| "major": "Computer Science", | |
| "bio": "Algorithm optimization expert" | |
| }, | |
| "Alex Diviney": { | |
| "email": null, | |
| "education": "Idaho State University", | |
| "major": "Computer Science", | |
| "bio": "Frontend and visualization specialist" | |
| }, | |
| "Janita Aamir": { | |
| "email": null, | |
| "education": "Idaho State University", | |
| "major": "Computer Science", | |
| "bio": "Problem solver and verifier developer" | |
| }, | |
| "Andrija Sevaljevic": { | |
| "email": null, | |
| "education": "Idaho State University", | |
| "major": "Computer Science", | |
| "bio": "Graph algorithm specialist" | |
| }, | |
| "Garret Stouffer": { | |
| "email": null, | |
| "education": "Idaho State University", | |
| "major": "Computer Science", | |
| "bio": "Data structure and algorithm expert" | |
| }, | |
| "Porter Glines": { | |
| "email": null, | |
| "education": "Idaho State University", | |
| "major": "Computer Science", | |
| "bio": "Testing and quality assurance specialist" | |
| }, | |
| "Show Pratoomratana": { | |
| "email": null, | |
| "education": "Idaho State University", | |
| "major": "Computer Science", | |
| "bio": "UI/UX and frontend developer" | |
| }, | |
| "Russell Phillips": { | |
| "email": null, |
| var options = new JsonSerializerOptions { WriteIndented = true }; | ||
| string jsonString = JsonSerializer.Serialize(problemFolders, options); | ||
|
|
||
| return Ok(jsonString); |
There was a problem hiding this comment.
GetAllContributors claims to return contributor names, but it currently lists directories under Problems (e.g., NPComplete) and then returns a serialized JSON string via Ok(jsonString), which produces a quoted string rather than a JSON array. This should return actual contributor names (likely the keys from contributorInfo.json) and return them as a proper JSON array/object (e.g., return Ok(names);) without double-serializing.
| var options = new JsonSerializerOptions { WriteIndented = true }; | |
| string jsonString = JsonSerializer.Serialize(problemFolders, options); | |
| return Ok(jsonString); | |
| return Ok(problemFolders); |
| string npcPath = Path.Combine(problemsPath, "NPComplete"); | ||
| if (Directory.Exists(npcPath)) { | ||
| var npcProblemDirs = Directory.GetDirectories(npcPath); | ||
| foreach (var problemDir in npcProblemDirs) { | ||
| string problemName = "NPC_" + Path.GetFileName(problemDir); | ||
| // Check if contributor worked on this problem by looking at files | ||
| if (ContributorWorkedOnProblem(problemDir, contributorName)) { | ||
| problems.Add(problemName); | ||
| } |
There was a problem hiding this comment.
GetAllProblems prefixes directory names with "NPC_", but the directories in Problems/NPComplete already appear to be named like NPC_SAT3, NPC_CLIQUE, etc. This will produce values like NPC_NPC_SAT3. Use the folder name as-is (or normalize consistently) instead of adding an extra prefix.
| } | ||
| } | ||
| } | ||
| catch { } |
There was a problem hiding this comment.
Poor error handling: empty catch block.
| } | ||
| } | ||
| } | ||
| catch { } |
There was a problem hiding this comment.
Poor error handling: empty catch block.
| } | ||
| } | ||
| } | ||
| catch { } |
There was a problem hiding this comment.
Poor error handling: empty catch block.
| return allContributors[contributorName]; | ||
| } | ||
| } | ||
| catch { } |
There was a problem hiding this comment.
Poor error handling: empty catch block.
| if (allContributors != null && allContributors.ContainsKey(contributorName)) { | ||
| return allContributors[contributorName]; |
There was a problem hiding this comment.
Inefficient use of 'ContainsKey' and indexer.
| if (allContributors != null && allContributors.ContainsKey(contributorName)) { | |
| return allContributors[contributorName]; | |
| if (allContributors != null && allContributors.TryGetValue(contributorName, out var contributorInfo)) { | |
| return contributorInfo; |
Added a contributor portfolio where clicking a name shows their info and individual contributions. It uses a new API, a JSON data file, and an interactive modal. Contributors can also optionally add GitHub or LinkedIn links via the JSON file.