<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Mbenkar</id>
	<title>Expertiza_Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Mbenkar"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Mbenkar"/>
	<updated>2026-06-29T20:29:11Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163347</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163347"/>
		<updated>2025-04-06T21:27:44Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* teams_participant.rb Reimplementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was reimplemented as is.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was reimplemented as is.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
Renamed method from name to username.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
Renamed method from fullname to name.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was reimplemented as is.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Deletes the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was reimplemented as is.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroys all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was reimplemented as is.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
Did not reimplement this method - use team’s topic getter instead.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
Did not reimplement this method - moved to responsible team mailer class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
Did not reimplement this method - use can_review instead since able_to_review simply delegates to an existing database field provided by ActiveRecord.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
Did not reimplement this method - moved to responsible team mailer class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determines the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was reimplemented as is.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.sort_by_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sorts a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
Did not reimplement this method - use built-in Rails sorting instead.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.export&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Exports participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was reimplemented as is.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.export_fields&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was reimplemented as is.&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===teams_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the user's name, appending &amp;quot;(Mentor)&amp;quot; if the user is recognized as a mentor in the system.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
Replaced call to user.name with call to participant.name.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Removes the corresponding TeamUserNode and delete the team if this was the last user associated with it.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
Replaced call to team.teams_users.empty? With team.teams_participants.empty?.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;get_team_members&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
(No implementation present) – Placeholder for a method intended to retrieve members of a specific team.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
Did not reimplement this method - it was a stubbed method in TeamsUser.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.remove_team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Removes the TeamsUser entry that links the specified user and team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
Replaced the parameters ‘user_id’ and ‘team_id’ with ‘participant’, since participant objects contain team information.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.first_by_team_id&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the first TeamsUser record associated with the given team ID.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
Replaced calls to TeamsUser.where() with TeamsParticipant.where().&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.team_empty?&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns whether the specified team has no members by checking for the absence of associated TeamsUser records.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
Replaced calls to TeamsUser.where() with TeamsParticipant.where().&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.add_member_to_invited_team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Adds an invited user to the invitee’s team for a given assignment if the invitee belongs to a matching team.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
Replaced the parameters ‘invitee_user_id’, ‘invited_user_id’ and ‘assignment_id’ with ‘invitee_participant_id’ and ‘invited_participant_id’, since participant objects contain assignment information.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.team_id&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the team ID associated with the given user and assignment, if such a team exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
Replaced the parameters ‘assignment_id’ and ‘user_id’ with ‘participant’, since participant objects contain assignment information.&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163346</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163346"/>
		<updated>2025-04-06T21:04:51Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* participant.rb Reimplementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was reimplemented as is.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was reimplemented as is.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
Renamed method from name to username.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
Renamed method from fullname to name.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was reimplemented as is.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Deletes the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was reimplemented as is.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroys all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was reimplemented as is.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
Did not reimplement this method - use team’s topic getter instead.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
Did not reimplement this method - moved to responsible team mailer class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
Did not reimplement this method - use can_review instead since able_to_review simply delegates to an existing database field provided by ActiveRecord.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
Did not reimplement this method - moved to responsible team mailer class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determines the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was reimplemented as is.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.sort_by_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sorts a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
Did not reimplement this method - use built-in Rails sorting instead.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.export&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Exports participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was reimplemented as is.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.export_fields&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was reimplemented as is.&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===teams_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the user's name, appending &amp;quot;(Mentor)&amp;quot; if the user is recognized as a mentor in the system.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Removes the corresponding TeamUserNode and delete the team if this was the last user associated with it.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;get_team_members&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
(No implementation present) – Placeholder for a method intended to retrieve members of a specific team.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.remove_team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Removes the TeamsUser entry that links the specified user and team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.first_by_team_id&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the first TeamsUser record associated with the given team ID.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.team_empty?&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns whether the specified team has no members by checking for the absence of associated TeamsUser records.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.add_member_to_invited_team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Adds an invited user to the invitee’s team for a given assignment if the invitee belongs to a matching team.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.team_id&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the team ID associated with the given user and assignment, if such a team exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163327</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163327"/>
		<updated>2025-04-06T19:59:05Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* teams_participant.rb Reimplementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Deletes the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroys all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determines the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.sort_by_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sorts a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.export&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Exports participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.export_fields&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===teams_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the user's name, appending &amp;quot;(Mentor)&amp;quot; if the user is recognized as a mentor in the system.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Removes the corresponding TeamUserNode and delete the team if this was the last user associated with it.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;get_team_members&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
(No implementation present) – Placeholder for a method intended to retrieve members of a specific team.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.remove_team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Removes the TeamsUser entry that links the specified user and team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.first_by_team_id&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the first TeamsUser record associated with the given team ID.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.team_empty?&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns whether the specified team has no members by checking for the absence of associated TeamsUser records.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.add_member_to_invited_team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Adds an invited user to the invitee’s team for a given assignment if the invitee belongs to a matching team.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.team_id&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the team ID associated with the given user and assignment, if such a team exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163315</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163315"/>
		<updated>2025-04-06T19:53:11Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* sort_by_name Method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Deletes the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroys all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determines the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.sort_by_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sorts a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.export&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Exports participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.export_fields&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===teams_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the user's name, appending &amp;quot;(Mentor)&amp;quot; if the user is recognized as a mentor in the system.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Removes the corresponding TeamUserNode and delete the team if this was the last user associated with it.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;get_team_members&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
(No implementation present) – Placeholder for a method intended to retrieve members of a specific team.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.remove_team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Removes the TeamsUser entry that links the specified user and team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163314</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163314"/>
		<updated>2025-04-06T19:53:00Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* export Method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Deletes the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroys all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determines the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;sort_by_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sorts a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.export&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Exports participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.export_fields&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===teams_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the user's name, appending &amp;quot;(Mentor)&amp;quot; if the user is recognized as a mentor in the system.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Removes the corresponding TeamUserNode and delete the team if this was the last user associated with it.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;get_team_members&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
(No implementation present) – Placeholder for a method intended to retrieve members of a specific team.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.remove_team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Removes the TeamsUser entry that links the specified user and team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163313</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163313"/>
		<updated>2025-04-06T19:52:46Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* export_fields Method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Deletes the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroys all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determines the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;sort_by_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sorts a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Exports participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.export_fields&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===teams_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the user's name, appending &amp;quot;(Mentor)&amp;quot; if the user is recognized as a mentor in the system.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Removes the corresponding TeamUserNode and delete the team if this was the last user associated with it.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;get_team_members&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
(No implementation present) – Placeholder for a method intended to retrieve members of a specific team.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.remove_team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Removes the TeamsUser entry that links the specified user and team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163312</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163312"/>
		<updated>2025-04-06T19:51:27Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* teams_participant.rb Reimplementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Deletes the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroys all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determines the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;sort_by_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sorts a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Exports participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export_fields&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===teams_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the user's name, appending &amp;quot;(Mentor)&amp;quot; if the user is recognized as a mentor in the system.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Removes the corresponding TeamUserNode and delete the team if this was the last user associated with it.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;get_team_members&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
(No implementation present) – Placeholder for a method intended to retrieve members of a specific team.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;self.remove_team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Removes the TeamsUser entry that links the specified user and team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163306</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163306"/>
		<updated>2025-04-06T19:45:52Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* participant.rb Reimplementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Deletes the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroys all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determines the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;sort_by_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sorts a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Exports participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export_fields&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===teams_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163303</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163303"/>
		<updated>2025-04-06T19:44:34Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* name Method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Deletes the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroys all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determines the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;sort_by_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sorts a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Exports participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export_fields&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===teams_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163301</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163301"/>
		<updated>2025-04-06T19:43:50Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* fullname Method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Deletes the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroys all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determines the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;sort_by_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sorts a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Exports participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export_fields&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===teams_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163299</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163299"/>
		<updated>2025-04-06T19:43:38Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* handle Method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Deletes the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroys all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determines the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;sort_by_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sorts a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Exports participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export_fields&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===teams_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163297</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163297"/>
		<updated>2025-04-06T19:43:31Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* delete Method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Deletes the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroys all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determines the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;sort_by_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sorts a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Exports participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export_fields&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===teams_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163296</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163296"/>
		<updated>2025-04-06T19:43:26Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* force_delete Method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Delete the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroys all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determines the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;sort_by_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sorts a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Exports participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export_fields&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===teams_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163295</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163295"/>
		<updated>2025-04-06T19:43:18Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* mail_assigned_reviewers Method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Delete the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroy all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determines the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;sort_by_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sorts a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Exports participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export_fields&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===teams_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163294</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163294"/>
		<updated>2025-04-06T19:43:13Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* topic_name Method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Delete the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroy all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Send email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determines the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;sort_by_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sorts a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Exports participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export_fields&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===teams_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163292</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163292"/>
		<updated>2025-04-06T19:43:09Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* able_to_review Method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Delete the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroy all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Send email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determines the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;sort_by_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sorts a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Exports participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export_fields&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===teams_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163291</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163291"/>
		<updated>2025-04-06T19:43:04Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* email Method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Delete the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroy all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Send email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sends a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determines the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;sort_by_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sorts a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Exports participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export_fields&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===teams_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163290</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163290"/>
		<updated>2025-04-06T19:42:59Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* authorization Method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Delete the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroy all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Send email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Send a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determines the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;sort_by_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sorts a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Exports participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export_fields&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===teams_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163289</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163289"/>
		<updated>2025-04-06T19:42:55Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* sort_by_name Method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Delete the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroy all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Send email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Send a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determine the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;sort_by_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sorts a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Exports participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export_fields&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===teams_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163288</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163288"/>
		<updated>2025-04-06T19:42:49Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* export Method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Delete the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroy all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Send email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Send a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determine the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;sort_by_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sort a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Exports participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export_fields&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===teams_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163286</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163286"/>
		<updated>2025-04-06T19:42:44Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* export_fields Method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Delete the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroy all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Send email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Send a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determine the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;sort_by_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sort a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Export participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export_fields&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===teams_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163282</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163282"/>
		<updated>2025-04-06T19:41:01Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* team_participant.rb Reimplementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Delete the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroy all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Send email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Send a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determine the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;sort_by_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sort a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Export participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export_fields&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===teams_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163279</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163279"/>
		<updated>2025-04-06T19:37:29Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* participant.rb Reimplementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Delete the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroy all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Send email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Send a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determine the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;sort_by_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sort a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Export participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export_fields&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===team_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163274</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163274"/>
		<updated>2025-04-06T19:33:04Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* participant.rb Reimplementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Delete the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroy all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Send email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Send a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determine the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;sort_by_name&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sort a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Export participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;export_fields&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===team_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163272</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163272"/>
		<updated>2025-04-06T19:31:00Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* participant.rb Reimplementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===='''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''====&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Delete the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroy all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Send email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Send a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determine the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;sort_by_name&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sort a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Export participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;export_fields&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===team_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163271</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163271"/>
		<updated>2025-04-06T19:30:38Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* team Method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===team_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163270</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163270"/>
		<updated>2025-04-06T19:29:42Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* participant.rb Reimplementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
==='''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''===&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Delete the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroy all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Send email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Send a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determine the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;sort_by_name&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sort a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Export participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;export_fields&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===team_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163269</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163269"/>
		<updated>2025-04-06T19:28:31Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* participant.rb Reimplementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===team_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163267</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163267"/>
		<updated>2025-04-06T19:23:43Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* participant.rb Reimplementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;responses&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Returns a list of responses by mapping each response map associated with the participant to its corresponding response.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s name by delegating the call to the associated user’s `name` method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;fullname&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s full name by delegating the call to the associated user’s fullname method, optionally passing an IP address.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s handle unless anonymized view is enabled, in which case return a generic placeholder.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Delete the participant if no associated response maps or team exist, or if forced; otherwise, raise an exception.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;force_delete&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Destroy all associated response maps and remove the team if this is the last participant; then delete the participant itself.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;topic_name&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return the participant’s topic name if available, or a centered em dash placeholder if not.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;mail_assigned_reviewers&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Send email notifications to all reviewers assigned to the participant’s team for a given assignment.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;able_to_review&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return whether the participant is able to review, delegating to can_review.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Send a registration email to the participant with assignment details, name, and login credentials.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;authorization&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Determine the participant’s authorization level (e.g., mentor, reviewer, submitter) based on permission flags.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;sort_by_name&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Sort a list of participants by their associated user’s name in a case-insensitive manner.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;export&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Export participant data to a CSV file based on the selected options for personal details, role, parent, email settings, and handle.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;export_fields&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Return a list of CSV header fields to include in the export, based on the provided options.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===team_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163259</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163259"/>
		<updated>2025-04-06T19:05:57Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* participant.rb Reimplementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
Retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===team_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163258</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163258"/>
		<updated>2025-04-06T19:03:29Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* participant.rb Reimplementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Participant class and its role:&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
This method retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===team_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163257</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163257"/>
		<updated>2025-04-06T19:03:02Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* team_participant.rb Reimplementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
This method retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===team_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method in TeamsUser that was reimplemented in the new TeamsParticipant class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163256</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163256"/>
		<updated>2025-04-06T19:02:10Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* team_participant.rb Reimplementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
This method retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===team_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163255</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163255"/>
		<updated>2025-04-06T19:01:57Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* participant.rb Reimplementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
This method retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
'''Changes Made'''&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===team_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163254</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163254"/>
		<updated>2025-04-06T19:01:09Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* participant.rb Reimplementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;team&amp;lt;/code&amp;gt; Method'''&lt;br /&gt;
&lt;br /&gt;
'''Description'''&lt;br /&gt;
&lt;br /&gt;
This method retrieves the team associated with the current user by finding their `TeamsUser` record and returning the linked team, if it exists.&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===team_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163253</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163253"/>
		<updated>2025-04-06T18:47:36Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* team_participant.rb Reimplementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===team_participant.rb Reimplementation===&lt;br /&gt;
We also reimplemented TeamsUser as TeamsParticipant, in alignment with the updated domain terminology and to better reflect the association between users and teams within a given context. While the new TeamsParticipant model includes a user_id field for compatibility, it is no longer central to the functionality. This shift allows the new system to more clearly represent the team-participant relationship and lays the groundwork for better encapsulation and extensibility in future enhancements.&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163252</id>
		<title>CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2526_Reimplement_Teams_and_Participant_hierarchies&amp;diff=163252"/>
		<updated>2025-04-06T18:47:15Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: /* participant.rb Reimplementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This project reimplements the Team and Participant hierarchies within the new Expertiza system. It introduces cleaner, modular structures for Participant, AssignmentParticipant, CourseParticipant, and a new TeamsParticipant class (replacing TeamsUser). The redesign also addresses legacy code smells and shifts logic to follow SOLID principles, improving maintainability, testability, and extensibility.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
* '''Reimplement Participant-related Classes:''' Fully reimplement the Participant, AssignmentParticipant, and CourseParticipant classes using clean object-oriented design, ensuring each class has a well-defined responsibility and follows SOLID principles.&lt;br /&gt;
* '''Introduce TeamsParticipant:''' Replace the existing TeamsUser class with a new TeamsParticipant class that clearly defines the relationship between teams and participants while preserving necessary fields.&lt;br /&gt;
* '''Refactor the Team Hierarchy:''' Integrate the Team hierarchy refactoring from OSS Project 3, improving upon it by addressing feedback provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Address Code Smells and Design Flaws:''' Eliminate all SRP violations and code smells from the original Participant, AssignmentParticipant, and CourseParticipant implementations.&lt;br /&gt;
* '''Write Comprehensive Tests:''' Implement thorough RSpec tests for all model behaviors, including edge cases.&lt;br /&gt;
&lt;br /&gt;
==Existing Issues==&lt;br /&gt;
1. '''Participant Hierarchy Violations'''&lt;br /&gt;
&lt;br /&gt;
The current implementations of &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/participant.rb participant.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_participant.rb assignment_participant.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_participant.rb course_participant.rb] &amp;lt;/code&amp;gt; contain multiple issues that must be addressed:&lt;br /&gt;
* Refactor code to fully comply with the Single Responsibility Principle (SRP).&lt;br /&gt;
* Eliminate code smells such as misplaced methods.&lt;br /&gt;
* Write sufficient RSpec tests to verify correct behavior under various conditions.&lt;br /&gt;
* Enhance inline documentation and comments to clearly explain:&lt;br /&gt;
** The purpose of each method.&lt;br /&gt;
** Justification for retaining or removing existing logic.&lt;br /&gt;
** Any key design decisions made during the implementation.&lt;br /&gt;
&lt;br /&gt;
2. '''TeamsParticipant Replacement'''&lt;br /&gt;
&lt;br /&gt;
The current &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/teams_user.rb teams_user.rb] &amp;lt;/code&amp;gt; class lacks proper structure and clarity in its associations. It will be replaced with a new TeamsParticipant class that:&lt;br /&gt;
* Preserves the existing behavior and relationships.&lt;br /&gt;
* Cleans up design inconsistencies.&lt;br /&gt;
* Introduces better encapsulation and naming for maintainability.&lt;br /&gt;
&lt;br /&gt;
3. '''Team Hierarchy Refactor'''&lt;br /&gt;
&lt;br /&gt;
The existing &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/team.rb team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/assignment_team.rb assignment_team.rb] &amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/course_team.rb course_team.rb] &amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/blob/main/app/models/mentored_team.rb mentored_team.rb] &amp;lt;/code&amp;gt; classes require rework to align with the updated architecture:&lt;br /&gt;
* Reimplement these classes using the clean design introduced in OSS Project 3.&lt;br /&gt;
* Address key feedback from &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;, such as:&lt;br /&gt;
** Rename methods like user? to more expressive terms like has_as_member? to improve clarity.&lt;br /&gt;
** Remove or clearly justify any commented-out legacy code.&lt;br /&gt;
** Refactor create_new_team() to better reflect intent (e.g., assign_team_to_topic) and clean up legacy logic based on outdated user-team assumptions.&lt;br /&gt;
&lt;br /&gt;
==Design / Proposed Solution==&lt;br /&gt;
===team.rb Reimplementation===&lt;br /&gt;
In the new team.rb implementation, we renamed is_member? to has_as_member?. The original method name implied that the team was a member of the user, rather than the other way around. Additionally, we moved the add_participant() method from AssignmentTeam to Team to apply the Factory Method Pattern. This change allows both CourseTeam and AssignmentTeam to reuse the same logic for participant creation while deferring type-specific behavior (like selecting the correct Participant subclass) to the factory method. All of this was done based on the feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised Team class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;has_as_member?&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
This method checks whether a given user is a member of the team. &lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Renamed from is_member? to has_as_member? for clarity.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;add_participant&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a Participant to the team, given a user object. It first checks if a corresponding participant already exists, and if not, creates a new one using the appropriate subclass, either AssignmentParticipant or CourseParticipant.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Moved from AssignmentTeam to the parent Team class to promote reuse and apply the Factory Method Pattern.&lt;br /&gt;
&lt;br /&gt;
===assignment_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_team.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===mentored_team.rb Reimplementation===&lt;br /&gt;
In the new mentored_team.rb implementation, we decided to remove the MentorManagement class and integrate its functionality directly into MentoredTeam and change add_member() to take participant instead of user and assignment id. This decision was made not only to improve cohesion and eliminate unnecessary indirection, but also to address structural feedback from the instructor provided in &amp;lt;code&amp;gt; [https://github.com/expertiza/expertiza/pull/2941 Pull Request #2941] &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Below is a breakdown of each method that was changed/added in the revised MentoredTeam class and its role:&lt;br /&gt;
====&amp;lt;code&amp;gt;add_member&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Adds a participant to the team using the superclass implementation and then automatically assigns a mentor to the team if the conditions are met (such as minimum team size and absence of an existing mentor).&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed from add_member(user, assignment_id = nil) to add_member(participant), since the participant contains all this information.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;import_team_members&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
Takes a hash of team member names and iterates through them. For each valid name, it looks up the corresponding user, ensures they are not already on the team, finds their AssignmentParticipant, and adds them to the team via add_member. It also triggers mentor assignment as part of this process.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
Changed the call inside it for add_member(user, assignment_id = nil) to add_member(participant).&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;assign_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that encapsulates the full logic of mentor assignment. It checks several conditions (e.g., whether mentoring is enabled, team has a topic, mentor already exists, etc.). If all conditions are satisfied, it selects an available mentor using the select_mentor method and adds them to the team, followed by notification emails.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;select_mentor&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that implements the algorithm for choosing the most suitable mentor. It selects among participants marked as mentors for the given assignment and returns the one who is currently mentoring the fewest teams. Ties are automatically broken by Hash#sort_by. This ensures a balanced distribution of mentor assignments.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;zip_mentors_with_team_count&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that generates a mapping of mentor user_ids to the number of teams each is currently mentoring, used by the select_mentor method. It performs a grouped count on the TeamsUser table and returns a sorted list of mentors by workload.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;mentors_for_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that returns all Participant records for a given assignment where the participant has can_mentor: true. This filters potential mentor candidates from the larger participant pool and serves as the base query for mentor selection logic.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_team_of_mentor_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email notification to all members of a team informing them that a mentor has been assigned. The message includes the mentor’s name and email, the assignment name, and a list of team members.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;code&amp;gt;notify_mentor_of_assignment&amp;lt;/code&amp;gt; Method ====&lt;br /&gt;
''' Description '''&lt;br /&gt;
&lt;br /&gt;
A private method that sends an email to the newly assigned mentor notifying them of their assignment. The email includes the assignment name and a full list of current team members to help the mentor familiarize themselves with the team.&lt;br /&gt;
&lt;br /&gt;
''' Changes Made '''&lt;br /&gt;
&lt;br /&gt;
No functional changes were made; the method was simply moved from MentorManagement to MentoredTeam.&lt;br /&gt;
&lt;br /&gt;
===participant.rb Reimplementation===&lt;br /&gt;
In the new implementation of the Participant model, we refactored several methods to improve clarity, maintainability, and alignment with the Single Responsibility Principle (SRP). The topic_name method was removed, as topics are associated with teams rather than participants, making its presence in Participant a design inconsistency. We also relocated the mail_assigned_reviewers method to a dedicated mailer class, where notification logic more appropriately belongs. The authorization method was renamed for clarity, and sort_by_name was eliminated due to its overly narrow use case and lack of general applicability. These changes help decouple responsibilities and make the class easier to test and extend.&lt;br /&gt;
&lt;br /&gt;
===assignment_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===course_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
===team_participant.rb Reimplementation===&lt;br /&gt;
&lt;br /&gt;
==SOLID Principle(s)==&lt;br /&gt;
'''Single Responsibility Principle:''' &amp;quot;A class should only have one responsibility and should never have more than one reason to change.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are many violations of the Single Responsibility Principle (SRP) across all Participant classes. For example, AssignmentParticipant contains methods like reviews() and get_reviewer(), which should be the responsibility of the Team class. Similarly, Participant includes mail_assigned_reviewers() and email(), which should belong to the Mailer class.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
We will write tests to ensure that all model validations function correctly for each class, including Participant, AssignmentParticipant, CourseParticipant, TeamsParticipant, and all team-related models. We will verify that belongs_to, has_many, and other associations are correctly configured and that no orphaned or dangling records remain after creation or deletion. Special attention will be given to business logic, particularly methods reused or inherited across subclasses. Additionally, we will test edge conditions like minimum team size thresholds, permission flags (e.g., can_mentor), and mentor-selection criteria to ensure the intended behavior is preserved.&lt;br /&gt;
&lt;br /&gt;
= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Link to reimplementation-back-end Expertiza Repository: https://github.com/expertiza/reimplementation-back-end&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/reimplementation-back-end&lt;br /&gt;
* Link to Pull Request: &lt;br /&gt;
* Link to Video Walkthrough:&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2503._Refactor_the_Team_hierarchy&amp;diff=162876</id>
		<title>CSC/ECE 517 Spring 2025 - E2503. Refactor the Team hierarchy</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2503._Refactor_the_Team_hierarchy&amp;diff=162876"/>
		<updated>2025-03-26T18:16:44Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: added more details in MentoredTeam method list and problem/solution sections&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
'''Relevant Links:'''&lt;br /&gt;
* Link to Expertiza Repository: https://github.com/expertiza/expertiza&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/expertiza&lt;br /&gt;
* Link to Pull Request: https://github.com/expertiza/expertiza/pull/2941&lt;br /&gt;
&lt;br /&gt;
= Expertiza Background =&lt;br /&gt;
Expertiza is an open-source project built using the Ruby on Rails MVC framework, designed to facilitate peer review and collaborative learning. The project has undergone multiple iterations, with ongoing efforts focused on refactoring the existing codebase to improve maintainability, efficiency, and scalability. Additionally, there are initiatives aimed at reimplementing a new version of Expertiza to enhance its architecture and functionality.&lt;br /&gt;
&lt;br /&gt;
= About Team/CourseTeam/AssignmentTeam/MentoredTeam =&lt;br /&gt;
The Team hierarchy contains the classes that hold teams of students enrolled in Expertiza. Teams can reserve topics and submit work. There are currently four classes in the team hierarchy: Team, CourseTeam, AssignmentTeam, and MentoredTeam. Instances of the Team superclass should never be created since any actual team will be a member of one of the three other classes. CourseTeams stay together for the entire course duration and work on all assignments together. Although some instructors choose not to use CourseTeams, others employ Team-Based Learning and do benefit from using CourseTeams. It is possible to both copy CourseTeams into AssignmentTeams, and vice-versa. Any team formed to take part in an assignment will be an AssignmentTeam, unless the assignment is set up to automatically assign mentors to teams. In this case, the assignment teams will be created as MentoredTeams (a subclass of AssignmentTeam) which has a designated member known as the mentor. &lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
The Team hierarchy in Expertiza is responsible for managing student teams, allowing them to reserve topics, submit work, and, in some cases, review other teams' submissions. However, the current implementation is overly complex, with redundant methods and unnecessary dependencies. The Team class has 27 methods, many of which should be refactored or removed, while AssignmentTeam contains 36 methods, several of which duplicate functionality from the superclass. Additionally, the system currently models team members as Users, but the new design will transition to Participants, requiring updates to team membership logic.&lt;br /&gt;
&lt;br /&gt;
= Tasks =&lt;br /&gt;
'''Refactoring the Team Hierarchy'''&lt;br /&gt;
* Prevent direct instantiation of Team, ensuring all actual teams belong to CourseTeam, AssignmentTeam, or MentoredTeam. &lt;br /&gt;
* Move only the core shared functionalities to the Team and reduce the method count.&lt;br /&gt;
* Eliminate Redundant Methods in AssignmentTeam and CourseTeam.&lt;br /&gt;
* Identify duplicate methods across Team, AssignmentTeam, and CourseTeam.&lt;br /&gt;
* Ensure CourseTeam and AssignmentTeam override import/export functionality from Team instead of defining separate versions.&lt;br /&gt;
&lt;br /&gt;
'''Transition from Users to Participants '''&lt;br /&gt;
* Modify add_member and related methods to work with CourseParticipants and AssignmentParticipants instead of Users.&lt;br /&gt;
* Ensure teams enforce correct membership rules (e.g., CourseTeam only accepts CourseParticipants).&lt;br /&gt;
&lt;br /&gt;
'''Optimizing Team Copying'''&lt;br /&gt;
* Ensure clear and efficient handling of copying between AssignmentTeam and CourseTeam.&lt;br /&gt;
* Consolidate logic for copying members across different team types.&lt;br /&gt;
&lt;br /&gt;
'''Improving Method Clarity and Encapsulation'''&lt;br /&gt;
* Convert class methods like size into instance methods.&lt;br /&gt;
* Standardize method naming conventions for clarity (e.g., avoid inconsistencies like copy_members vs. copy_content).&lt;br /&gt;
&lt;br /&gt;
'''Removing Unused and Inefficient Code'''&lt;br /&gt;
* Identify and remove any unused methods in Team, AssignmentTeam, and CourseTeam. &lt;br /&gt;
* Remove commented-out or deprecated code that no longer serves a purpose. &lt;br /&gt;
* Simplify methods that are overly complex by leveraging helper functions where necessary. &lt;br /&gt;
&lt;br /&gt;
'''Testing and Code Validation'''&lt;br /&gt;
* Update tests to reflect the refactored team hierarchy and ensure correctness. &lt;br /&gt;
* Remove or rewrite tests that validate methods no longer in use.&lt;br /&gt;
&lt;br /&gt;
= Plan of Work =&lt;br /&gt;
We began by listing all of the methods belonging to each class in the Team hierarchy. Next, we met with our mentor (Dr. Gehringer) and reviewed every single method’s readability, maintainability, and adherence to best practices (SOLID principles, DRY, etc.). Once we organized the methods by class, we assigned groups of methods as tasks amongst team members and began refactoring existing methods while making sure existing test cases still passed and new tests were added as needed.&lt;br /&gt;
&lt;br /&gt;
= Implementation =&lt;br /&gt;
'''Refactor Team Model'''&lt;br /&gt;
* Methods involved:&lt;br /&gt;
** self.allowed_types&lt;br /&gt;
** self.team_operation&lt;br /&gt;
** self.responses&lt;br /&gt;
** author_names&lt;br /&gt;
** user?(user)&lt;br /&gt;
** add_member(user, _assignment_id = nil)&lt;br /&gt;
** self.size(team_id)&lt;br /&gt;
** copy_members(new_team)&lt;br /&gt;
** self.check_for_existing(parent, name, team_type)&lt;br /&gt;
** self.randomize_all_by_parent(parent, team_type, min_team_size)&lt;br /&gt;
** self.create_team_from_single_users(min_team_size, parent, team_type, users)&lt;br /&gt;
** self.assign_single_users_to_teams(min_team_size, parent, teams, users)&lt;br /&gt;
** self.generate_team_name(_team_name_prefix = “”)&lt;br /&gt;
** self.create_team_and_node(id)&lt;br /&gt;
** self.create_team_with_users(parent_id, user_ids)&lt;br /&gt;
** self.remove_user_from_previous_team(parent_id, user_id)&lt;br /&gt;
** self.find_team_users(assignment_id, user_id)&lt;br /&gt;
&lt;br /&gt;
* Problems/Solutions:&lt;br /&gt;
** The refactoring efforts addressed several key issues in Expertiza's codebase, including redundancy, unclear naming, and inefficient implementations. &lt;br /&gt;
** Unnecessary methods and parameters were removed or consolidated, improving code clarity and maintainability.&lt;br /&gt;
** Naming conventions were refined to better reflect functionality, and certain methods were moved to more appropriate classes, such as CourseTeam and AssignmentTeam.&lt;br /&gt;
** The use of ActiveRecord's dependent destroy was implemented to ensure proper cleanup of associated records.&lt;br /&gt;
** Additionally, alternative implementations were suggested to simplify logic, such as replacing redundant methods with built-in Rails queries and using uniqueness validation instead of manual checks.&lt;br /&gt;
** Improvements were proposed for import/export methods.&lt;br /&gt;
&lt;br /&gt;
* Changes:&lt;br /&gt;
** Moved parent_entity_type and self.find_parent_entity(id) from CourseTeam to Team.&lt;br /&gt;
[[File:2503-0.png]]&lt;br /&gt;
** Renamed author_names to member_names.&lt;br /&gt;
[[File:2503-1.png]]&lt;br /&gt;
** Removed unnecessary parameter from add_member; replaced size with instance method; CourseTeam’s add_participant method was removed, and CourseTeam inherits Team.add_member instead.&lt;br /&gt;
[[File:2503-2.png]]&lt;br /&gt;
** Renamed randomize_all_by_parent to create_random_teams.&lt;br /&gt;
[[File:2503-3.png]]&lt;br /&gt;
** Renamed create_team_from_single_users to team_from_users.&lt;br /&gt;
[[File:2503-4.png]]&lt;br /&gt;
** No changes to self.handle_duplicate.&lt;br /&gt;
[[File:2503-5.png]]&lt;br /&gt;
** Added optional user_ids parameter to facilitate removal of create_team_with_users method to avoid redundancy.&lt;br /&gt;
[[File:2503-6.png]]&lt;br /&gt;
&lt;br /&gt;
'''Refactor CourseTeam Model'''&lt;br /&gt;
* Methods involved:&lt;br /&gt;
** parent_model&lt;br /&gt;
** self.parent_model(id)&lt;br /&gt;
** assignment_id&lt;br /&gt;
** self.prototype&lt;br /&gt;
** copy(assignment_id)&lt;br /&gt;
** add_participant(course_id, user)&lt;br /&gt;
** self.import(row, course_id, options)&lt;br /&gt;
** self.export(csv, parent_id, options)&lt;br /&gt;
** self.export_fields(options)&lt;br /&gt;
** add_member(user, _id, = nil)&lt;br /&gt;
&lt;br /&gt;
* Problems/Solutions:&lt;br /&gt;
** parent_model: Replaced with parent_entity_type() and find_parent_entity(id) in the Team class for clarity, since it duplicated functionality.&lt;br /&gt;
** self.parent_model(id) - Logic was moved to Team.find_parent_entity(id) to consolidate redundant behavior.&lt;br /&gt;
** assignment_id - No changes made; it correctly returns nil to indicate it's not an AssignmentTeam.&lt;br /&gt;
** self.prototype - Removed because it's unnecessary—creating a new instance with CourseTeam.new is sufficient.&lt;br /&gt;
** copy(assignment_id) - Refactored and renamed to copy_to_assignment() for clarity.&lt;br /&gt;
** add_participant(course_id, user) - Removed, as this responsibility already exists in the Course class.&lt;br /&gt;
** self.import(row, course_id, options) - Left unchanged since it appropriately overrides Team.import().&lt;br /&gt;
** self.export(csv, parent_id, options) - Left unchanged as it overrides Team.export() correctly.&lt;br /&gt;
** self.export_fields(options) - Left unchanged because it’s used in export_file_controller.rb for file exports.&lt;br /&gt;
** add_member(user, _id = nil) - Removed due to duplication; the Team class already implements add_member().&lt;br /&gt;
&lt;br /&gt;
* Changes:&lt;br /&gt;
** Refactored the code and now the method called copy_to_assignment()&lt;br /&gt;
[[File:2503-7.png]]&lt;br /&gt;
&lt;br /&gt;
'''Refactor AssignmentTeam Model'''&lt;br /&gt;
* Changes:&lt;br /&gt;
** assign_reviewer left as is [no change]&lt;br /&gt;
** get_reviewer() was renamed to reviewer()&lt;br /&gt;
** reviewed_by left() as is [no change]&lt;br /&gt;
** topic() renamed to topic_id()&lt;br /&gt;
[[File:2503-8.png]]&lt;br /&gt;
** files() refactored to use an iterator-based approach&lt;br /&gt;
[[File:2503-9.png]]&lt;br /&gt;
** For set.export_fields(), enabled fields to be an explicit return value to improve readability&lt;br /&gt;
** self.remove_team_by_id left as is, very concise; “unless nil” check ensures safety&lt;br /&gt;
** path() was refactored to avoid string concatenation&lt;br /&gt;
** set_team_directory_num() was refactored method name to match behavior&lt;br /&gt;
[[File:2503-10.png]]&lt;br /&gt;
** Refactored method name to match behavior&lt;br /&gt;
[[File:2503-11.png]]&lt;br /&gt;
&lt;br /&gt;
'''Refactor MentoredTeam Model'''&lt;br /&gt;
* Methods involved:&lt;br /&gt;
** add_member(user, assignment_id = nil)&lt;br /&gt;
** import_team_members(row_hash)&lt;br /&gt;
&lt;br /&gt;
* Problems/Solutions:&lt;br /&gt;
** Refactored add_member since most the functionality is already in Team.add_member(), and it just needs to overwrite it to add the assigning a mentor functionality to MentoredTeam&lt;br /&gt;
** import_team_members isn't changed since it calls add_member(user, parent_id) which is not similar to what is in the Team.import_team_members()&lt;br /&gt;
&lt;br /&gt;
* Changes:&lt;br /&gt;
** Refactored add_member to override Team.add_member to handle assigning a mentor&lt;br /&gt;
[[File:2503-12.png]]&lt;br /&gt;
= Test Plan =&lt;br /&gt;
This project involves refactoring the Team hierarchy, ensuring that existing functionality remains unchanged while improving structure and maintainability. Since the refactor involves modifying class structures, consolidating redundant methods, and introducing better encapsulation, the following steps were taken to validate correctness:&lt;br /&gt;
* Refactored RSpec test files to reflect changes in class structure, method names, and logic updates.&lt;br /&gt;
* Ran the test suite after each major change to verify that functionality remained consistent across Team, CourseTeam, AssignmentTeam, and MentoredTeam.&lt;br /&gt;
* Ensured that core team operations (adding/removing members, copying teams, importing/exporting teams) worked as expected by validating test outputs against pre-refactor results.&lt;br /&gt;
* Ensured all refactored classes maintained high test coverage, targeting at least 90% coverage in Team, AssignmentTeam, and CourseTeam.&lt;br /&gt;
* Ensured that removed methods were either unnecessary or replaced with equivalent logic in the refactored structure.&lt;br /&gt;
* Validated UI functionality by testing that teams were correctly displayed, managed, and interacted with in the system.&lt;br /&gt;
[[File:I1.png]]&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2503._Refactor_the_Team_hierarchy&amp;diff=162875</id>
		<title>CSC/ECE 517 Spring 2025 - E2503. Refactor the Team hierarchy</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2503._Refactor_the_Team_hierarchy&amp;diff=162875"/>
		<updated>2025-03-26T18:12:28Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: added problem/solution list for CourseTeam&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
'''Relevant Links:'''&lt;br /&gt;
* Link to Expertiza Repository: https://github.com/expertiza/expertiza&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/expertiza&lt;br /&gt;
* Link to Pull Request: https://github.com/expertiza/expertiza/pull/2941&lt;br /&gt;
&lt;br /&gt;
= Expertiza Background =&lt;br /&gt;
Expertiza is an open-source project built using the Ruby on Rails MVC framework, designed to facilitate peer review and collaborative learning. The project has undergone multiple iterations, with ongoing efforts focused on refactoring the existing codebase to improve maintainability, efficiency, and scalability. Additionally, there are initiatives aimed at reimplementing a new version of Expertiza to enhance its architecture and functionality.&lt;br /&gt;
&lt;br /&gt;
= About Team/CourseTeam/AssignmentTeam/MentoredTeam =&lt;br /&gt;
The Team hierarchy contains the classes that hold teams of students enrolled in Expertiza. Teams can reserve topics and submit work. There are currently four classes in the team hierarchy: Team, CourseTeam, AssignmentTeam, and MentoredTeam. Instances of the Team superclass should never be created since any actual team will be a member of one of the three other classes. CourseTeams stay together for the entire course duration and work on all assignments together. Although some instructors choose not to use CourseTeams, others employ Team-Based Learning and do benefit from using CourseTeams. It is possible to both copy CourseTeams into AssignmentTeams, and vice-versa. Any team formed to take part in an assignment will be an AssignmentTeam, unless the assignment is set up to automatically assign mentors to teams. In this case, the assignment teams will be created as MentoredTeams (a subclass of AssignmentTeam) which has a designated member known as the mentor. &lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
The Team hierarchy in Expertiza is responsible for managing student teams, allowing them to reserve topics, submit work, and, in some cases, review other teams' submissions. However, the current implementation is overly complex, with redundant methods and unnecessary dependencies. The Team class has 27 methods, many of which should be refactored or removed, while AssignmentTeam contains 36 methods, several of which duplicate functionality from the superclass. Additionally, the system currently models team members as Users, but the new design will transition to Participants, requiring updates to team membership logic.&lt;br /&gt;
&lt;br /&gt;
= Tasks =&lt;br /&gt;
'''Refactoring the Team Hierarchy'''&lt;br /&gt;
* Prevent direct instantiation of Team, ensuring all actual teams belong to CourseTeam, AssignmentTeam, or MentoredTeam. &lt;br /&gt;
* Move only the core shared functionalities to the Team and reduce the method count.&lt;br /&gt;
* Eliminate Redundant Methods in AssignmentTeam and CourseTeam.&lt;br /&gt;
* Identify duplicate methods across Team, AssignmentTeam, and CourseTeam.&lt;br /&gt;
* Ensure CourseTeam and AssignmentTeam override import/export functionality from Team instead of defining separate versions.&lt;br /&gt;
&lt;br /&gt;
'''Transition from Users to Participants '''&lt;br /&gt;
* Modify add_member and related methods to work with CourseParticipants and AssignmentParticipants instead of Users.&lt;br /&gt;
* Ensure teams enforce correct membership rules (e.g., CourseTeam only accepts CourseParticipants).&lt;br /&gt;
&lt;br /&gt;
'''Optimizing Team Copying'''&lt;br /&gt;
* Ensure clear and efficient handling of copying between AssignmentTeam and CourseTeam.&lt;br /&gt;
* Consolidate logic for copying members across different team types.&lt;br /&gt;
&lt;br /&gt;
'''Improving Method Clarity and Encapsulation'''&lt;br /&gt;
* Convert class methods like size into instance methods.&lt;br /&gt;
* Standardize method naming conventions for clarity (e.g., avoid inconsistencies like copy_members vs. copy_content).&lt;br /&gt;
&lt;br /&gt;
'''Removing Unused and Inefficient Code'''&lt;br /&gt;
* Identify and remove any unused methods in Team, AssignmentTeam, and CourseTeam. &lt;br /&gt;
* Remove commented-out or deprecated code that no longer serves a purpose. &lt;br /&gt;
* Simplify methods that are overly complex by leveraging helper functions where necessary. &lt;br /&gt;
&lt;br /&gt;
'''Testing and Code Validation'''&lt;br /&gt;
* Update tests to reflect the refactored team hierarchy and ensure correctness. &lt;br /&gt;
* Remove or rewrite tests that validate methods no longer in use.&lt;br /&gt;
&lt;br /&gt;
= Plan of Work =&lt;br /&gt;
We began by listing all of the methods belonging to each class in the Team hierarchy. Next, we met with our mentor (Dr. Gehringer) and reviewed every single method’s readability, maintainability, and adherence to best practices (SOLID principles, DRY, etc.). Once we organized the methods by class, we assigned groups of methods as tasks amongst team members and began refactoring existing methods while making sure existing test cases still passed and new tests were added as needed.&lt;br /&gt;
&lt;br /&gt;
= Implementation =&lt;br /&gt;
'''Refactor Team Model'''&lt;br /&gt;
* Methods involved:&lt;br /&gt;
** self.allowed_types&lt;br /&gt;
** self.team_operation&lt;br /&gt;
** self.responses&lt;br /&gt;
** author_names&lt;br /&gt;
** user?(user)&lt;br /&gt;
** add_member(user, _assignment_id = nil)&lt;br /&gt;
** self.size(team_id)&lt;br /&gt;
** copy_members(new_team)&lt;br /&gt;
** self.check_for_existing(parent, name, team_type)&lt;br /&gt;
** self.randomize_all_by_parent(parent, team_type, min_team_size)&lt;br /&gt;
** self.create_team_from_single_users(min_team_size, parent, team_type, users)&lt;br /&gt;
** self.assign_single_users_to_teams(min_team_size, parent, teams, users)&lt;br /&gt;
** self.generate_team_name(_team_name_prefix = “”)&lt;br /&gt;
** self.create_team_and_node(id)&lt;br /&gt;
** self.create_team_with_users(parent_id, user_ids)&lt;br /&gt;
** self.remove_user_from_previous_team(parent_id, user_id)&lt;br /&gt;
** self.find_team_users(assignment_id, user_id)&lt;br /&gt;
&lt;br /&gt;
* Problems/Solutions:&lt;br /&gt;
** The refactoring efforts addressed several key issues in Expertiza's codebase, including redundancy, unclear naming, and inefficient implementations. &lt;br /&gt;
** Unnecessary methods and parameters were removed or consolidated, improving code clarity and maintainability.&lt;br /&gt;
** Naming conventions were refined to better reflect functionality, and certain methods were moved to more appropriate classes, such as CourseTeam and AssignmentTeam.&lt;br /&gt;
** The use of ActiveRecord's dependent destroy was implemented to ensure proper cleanup of associated records.&lt;br /&gt;
** Additionally, alternative implementations were suggested to simplify logic, such as replacing redundant methods with built-in Rails queries and using uniqueness validation instead of manual checks.&lt;br /&gt;
** Improvements were proposed for import/export methods.&lt;br /&gt;
&lt;br /&gt;
* Changes:&lt;br /&gt;
** Moved parent_entity_type and self.find_parent_entity(id) from CourseTeam to Team.&lt;br /&gt;
[[File:2503-0.png]]&lt;br /&gt;
** Renamed author_names to member_names.&lt;br /&gt;
[[File:2503-1.png]]&lt;br /&gt;
** Removed unnecessary parameter from add_member; replaced size with instance method; CourseTeam’s add_participant method was removed, and CourseTeam inherits Team.add_member instead.&lt;br /&gt;
[[File:2503-2.png]]&lt;br /&gt;
** Renamed randomize_all_by_parent to create_random_teams.&lt;br /&gt;
[[File:2503-3.png]]&lt;br /&gt;
** Renamed create_team_from_single_users to team_from_users.&lt;br /&gt;
[[File:2503-4.png]]&lt;br /&gt;
** No changes to self.handle_duplicate.&lt;br /&gt;
[[File:2503-5.png]]&lt;br /&gt;
** Added optional user_ids parameter to facilitate removal of create_team_with_users method to avoid redundancy.&lt;br /&gt;
[[File:2503-6.png]]&lt;br /&gt;
&lt;br /&gt;
'''Refactor CourseTeam Model'''&lt;br /&gt;
* Methods involved:&lt;br /&gt;
** parent_model&lt;br /&gt;
** self.parent_model(id)&lt;br /&gt;
** assignment_id&lt;br /&gt;
** self.prototype&lt;br /&gt;
** copy(assignment_id)&lt;br /&gt;
** add_participant(course_id, user)&lt;br /&gt;
** self.import(row, course_id, options)&lt;br /&gt;
** self.export(csv, parent_id, options)&lt;br /&gt;
** self.export_fields(options)&lt;br /&gt;
** add_member(user, _id, = nil)&lt;br /&gt;
&lt;br /&gt;
* Problems/Solutions:&lt;br /&gt;
** parent_model: Replaced with parent_entity_type() and find_parent_entity(id) in the Team class for clarity, since it duplicated functionality.&lt;br /&gt;
** self.parent_model(id) - Logic was moved to Team.find_parent_entity(id) to consolidate redundant behavior.&lt;br /&gt;
** assignment_id - No changes made; it correctly returns nil to indicate it's not an AssignmentTeam.&lt;br /&gt;
** self.prototype - Removed because it's unnecessary—creating a new instance with CourseTeam.new is sufficient.&lt;br /&gt;
** copy(assignment_id) - Refactored and renamed to copy_to_assignment() for clarity.&lt;br /&gt;
** add_participant(course_id, user) - Removed, as this responsibility already exists in the Course class.&lt;br /&gt;
** self.import(row, course_id, options) - Left unchanged since it appropriately overrides Team.import().&lt;br /&gt;
** self.export(csv, parent_id, options) - Left unchanged as it overrides Team.export() correctly.&lt;br /&gt;
** self.export_fields(options) - Left unchanged because it’s used in export_file_controller.rb for file exports.&lt;br /&gt;
** add_member(user, _id = nil) - Removed due to duplication; the Team class already implements add_member().&lt;br /&gt;
&lt;br /&gt;
* Changes:&lt;br /&gt;
** Refactored the code and now the method called copy_to_assignment()&lt;br /&gt;
[[File:2503-7.png]]&lt;br /&gt;
&lt;br /&gt;
'''Refactor AssignmentTeam Model'''&lt;br /&gt;
* Changes:&lt;br /&gt;
** assign_reviewer left as is [no change]&lt;br /&gt;
** get_reviewer() was renamed to reviewer()&lt;br /&gt;
** reviewed_by left() as is [no change]&lt;br /&gt;
** topic() renamed to topic_id()&lt;br /&gt;
[[File:2503-8.png]]&lt;br /&gt;
** files() refactored to use an iterator-based approach&lt;br /&gt;
[[File:2503-9.png]]&lt;br /&gt;
** For set.export_fields(), enabled fields to be an explicit return value to improve readability&lt;br /&gt;
** self.remove_team_by_id left as is, very concise; “unless nil” check ensures safety&lt;br /&gt;
** path() was refactored to avoid string concatenation&lt;br /&gt;
** set_team_directory_num() was refactored method name to match behavior&lt;br /&gt;
[[File:2503-10.png]]&lt;br /&gt;
** Refactored method name to match behavior&lt;br /&gt;
[[File:2503-11.png]]&lt;br /&gt;
&lt;br /&gt;
'''Refactor MentoredTeam Model'''&lt;br /&gt;
* Changes:&lt;br /&gt;
** Refactored add_member to override Team.add_member to handle assigning a mentor&lt;br /&gt;
[[File:2503-12.png]]&lt;br /&gt;
= Test Plan =&lt;br /&gt;
This project involves refactoring the Team hierarchy, ensuring that existing functionality remains unchanged while improving structure and maintainability. Since the refactor involves modifying class structures, consolidating redundant methods, and introducing better encapsulation, the following steps were taken to validate correctness:&lt;br /&gt;
* Refactored RSpec test files to reflect changes in class structure, method names, and logic updates.&lt;br /&gt;
* Ran the test suite after each major change to verify that functionality remained consistent across Team, CourseTeam, AssignmentTeam, and MentoredTeam.&lt;br /&gt;
* Ensured that core team operations (adding/removing members, copying teams, importing/exporting teams) worked as expected by validating test outputs against pre-refactor results.&lt;br /&gt;
* Ensured all refactored classes maintained high test coverage, targeting at least 90% coverage in Team, AssignmentTeam, and CourseTeam.&lt;br /&gt;
* Ensured that removed methods were either unnecessary or replaced with equivalent logic in the refactored structure.&lt;br /&gt;
* Validated UI functionality by testing that teams were correctly displayed, managed, and interacted with in the system.&lt;br /&gt;
[[File:I1.png]]&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2503._Refactor_the_Team_hierarchy&amp;diff=162874</id>
		<title>CSC/ECE 517 Spring 2025 - E2503. Refactor the Team hierarchy</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2503._Refactor_the_Team_hierarchy&amp;diff=162874"/>
		<updated>2025-03-26T18:00:43Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: added remaining screenshots&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
'''Relevant Links:'''&lt;br /&gt;
* Link to Expertiza Repository: https://github.com/expertiza/expertiza&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/expertiza&lt;br /&gt;
* Link to Pull Request: https://github.com/expertiza/expertiza/pull/2941&lt;br /&gt;
&lt;br /&gt;
= Expertiza Background =&lt;br /&gt;
Expertiza is an open-source project built using the Ruby on Rails MVC framework, designed to facilitate peer review and collaborative learning. The project has undergone multiple iterations, with ongoing efforts focused on refactoring the existing codebase to improve maintainability, efficiency, and scalability. Additionally, there are initiatives aimed at reimplementing a new version of Expertiza to enhance its architecture and functionality.&lt;br /&gt;
&lt;br /&gt;
= About Team/CourseTeam/AssignmentTeam/MentoredTeam =&lt;br /&gt;
The Team hierarchy contains the classes that hold teams of students enrolled in Expertiza. Teams can reserve topics and submit work. There are currently four classes in the team hierarchy: Team, CourseTeam, AssignmentTeam, and MentoredTeam. Instances of the Team superclass should never be created since any actual team will be a member of one of the three other classes. CourseTeams stay together for the entire course duration and work on all assignments together. Although some instructors choose not to use CourseTeams, others employ Team-Based Learning and do benefit from using CourseTeams. It is possible to both copy CourseTeams into AssignmentTeams, and vice-versa. Any team formed to take part in an assignment will be an AssignmentTeam, unless the assignment is set up to automatically assign mentors to teams. In this case, the assignment teams will be created as MentoredTeams (a subclass of AssignmentTeam) which has a designated member known as the mentor. &lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
The Team hierarchy in Expertiza is responsible for managing student teams, allowing them to reserve topics, submit work, and, in some cases, review other teams' submissions. However, the current implementation is overly complex, with redundant methods and unnecessary dependencies. The Team class has 27 methods, many of which should be refactored or removed, while AssignmentTeam contains 36 methods, several of which duplicate functionality from the superclass. Additionally, the system currently models team members as Users, but the new design will transition to Participants, requiring updates to team membership logic.&lt;br /&gt;
&lt;br /&gt;
= Tasks =&lt;br /&gt;
'''Refactoring the Team Hierarchy'''&lt;br /&gt;
* Prevent direct instantiation of Team, ensuring all actual teams belong to CourseTeam, AssignmentTeam, or MentoredTeam. &lt;br /&gt;
* Move only the core shared functionalities to the Team and reduce the method count.&lt;br /&gt;
* Eliminate Redundant Methods in AssignmentTeam and CourseTeam.&lt;br /&gt;
* Identify duplicate methods across Team, AssignmentTeam, and CourseTeam.&lt;br /&gt;
* Ensure CourseTeam and AssignmentTeam override import/export functionality from Team instead of defining separate versions.&lt;br /&gt;
&lt;br /&gt;
'''Transition from Users to Participants '''&lt;br /&gt;
* Modify add_member and related methods to work with CourseParticipants and AssignmentParticipants instead of Users.&lt;br /&gt;
* Ensure teams enforce correct membership rules (e.g., CourseTeam only accepts CourseParticipants).&lt;br /&gt;
&lt;br /&gt;
'''Optimizing Team Copying'''&lt;br /&gt;
* Ensure clear and efficient handling of copying between AssignmentTeam and CourseTeam.&lt;br /&gt;
* Consolidate logic for copying members across different team types.&lt;br /&gt;
&lt;br /&gt;
'''Improving Method Clarity and Encapsulation'''&lt;br /&gt;
* Convert class methods like size into instance methods.&lt;br /&gt;
* Standardize method naming conventions for clarity (e.g., avoid inconsistencies like copy_members vs. copy_content).&lt;br /&gt;
&lt;br /&gt;
'''Removing Unused and Inefficient Code'''&lt;br /&gt;
* Identify and remove any unused methods in Team, AssignmentTeam, and CourseTeam. &lt;br /&gt;
* Remove commented-out or deprecated code that no longer serves a purpose. &lt;br /&gt;
* Simplify methods that are overly complex by leveraging helper functions where necessary. &lt;br /&gt;
&lt;br /&gt;
'''Testing and Code Validation'''&lt;br /&gt;
* Update tests to reflect the refactored team hierarchy and ensure correctness. &lt;br /&gt;
* Remove or rewrite tests that validate methods no longer in use.&lt;br /&gt;
&lt;br /&gt;
= Plan of Work =&lt;br /&gt;
We began by listing all of the methods belonging to each class in the Team hierarchy. Next, we met with our mentor (Dr. Gehringer) and reviewed every single method’s readability, maintainability, and adherence to best practices (SOLID principles, DRY, etc.). Once we organized the methods by class, we assigned groups of methods as tasks amongst team members and began refactoring existing methods while making sure existing test cases still passed and new tests were added as needed.&lt;br /&gt;
&lt;br /&gt;
= Implementation =&lt;br /&gt;
'''Refactor Team Model'''&lt;br /&gt;
* Methods involved:&lt;br /&gt;
** self.allowed_types&lt;br /&gt;
** self.team_operation&lt;br /&gt;
** self.responses&lt;br /&gt;
** author_names&lt;br /&gt;
** user?(user)&lt;br /&gt;
** add_member(user, _assignment_id = nil)&lt;br /&gt;
** self.size(team_id)&lt;br /&gt;
** copy_members(new_team)&lt;br /&gt;
** self.check_for_existing(parent, name, team_type)&lt;br /&gt;
** self.randomize_all_by_parent(parent, team_type, min_team_size)&lt;br /&gt;
** self.create_team_from_single_users(min_team_size, parent, team_type, users)&lt;br /&gt;
** self.assign_single_users_to_teams(min_team_size, parent, teams, users)&lt;br /&gt;
** self.generate_team_name(_team_name_prefix = “”)&lt;br /&gt;
** self.create_team_and_node(id)&lt;br /&gt;
** self.create_team_with_users(parent_id, user_ids)&lt;br /&gt;
** self.remove_user_from_previous_team(parent_id, user_id)&lt;br /&gt;
** self.find_team_users(assignment_id, user_id)&lt;br /&gt;
&lt;br /&gt;
* Problems/Solutions:&lt;br /&gt;
** The refactoring efforts addressed several key issues in Expertiza's codebase, including redundancy, unclear naming, and inefficient implementations. &lt;br /&gt;
** Unnecessary methods and parameters were removed or consolidated, improving code clarity and maintainability.&lt;br /&gt;
** Naming conventions were refined to better reflect functionality, and certain methods were moved to more appropriate classes, such as CourseTeam and AssignmentTeam.&lt;br /&gt;
** The use of ActiveRecord's dependent destroy was implemented to ensure proper cleanup of associated records.&lt;br /&gt;
** Additionally, alternative implementations were suggested to simplify logic, such as replacing redundant methods with built-in Rails queries and using uniqueness validation instead of manual checks.&lt;br /&gt;
** Improvements were proposed for import/export methods.&lt;br /&gt;
&lt;br /&gt;
* Changes:&lt;br /&gt;
** Moved parent_entity_type and self.find_parent_entity(id) from CourseTeam to Team.&lt;br /&gt;
[[File:2503-0.png]]&lt;br /&gt;
** Renamed author_names to member_names.&lt;br /&gt;
[[File:2503-1.png]]&lt;br /&gt;
** Removed unnecessary parameter from add_member; replaced size with instance method; CourseTeam’s add_participant method was removed, and CourseTeam inherits Team.add_member instead.&lt;br /&gt;
[[File:2503-2.png]]&lt;br /&gt;
** Renamed randomize_all_by_parent to create_random_teams.&lt;br /&gt;
[[File:2503-3.png]]&lt;br /&gt;
** Renamed create_team_from_single_users to team_from_users.&lt;br /&gt;
[[File:2503-4.png]]&lt;br /&gt;
** No changes to self.handle_duplicate.&lt;br /&gt;
[[File:2503-5.png]]&lt;br /&gt;
** Added optional user_ids parameter to facilitate removal of create_team_with_users method to avoid redundancy.&lt;br /&gt;
[[File:2503-6.png]]&lt;br /&gt;
&lt;br /&gt;
'''Refactor CourseTeam Model'''&lt;br /&gt;
* Changes:&lt;br /&gt;
** Refactored the code and now the method called copy_to_assignment()&lt;br /&gt;
[[File:2503-7.png]]&lt;br /&gt;
&lt;br /&gt;
'''Refactor AssignmentTeam Model'''&lt;br /&gt;
* Changes:&lt;br /&gt;
** assign_reviewer left as is [no change]&lt;br /&gt;
** get_reviewer() was renamed to reviewer()&lt;br /&gt;
** reviewed_by left() as is [no change]&lt;br /&gt;
** topic() renamed to topic_id()&lt;br /&gt;
[[File:2503-8.png]]&lt;br /&gt;
** files() refactored to use an iterator-based approach&lt;br /&gt;
[[File:2503-9.png]]&lt;br /&gt;
** For set.export_fields(), enabled fields to be an explicit return value to improve readability&lt;br /&gt;
** self.remove_team_by_id left as is, very concise; “unless nil” check ensures safety&lt;br /&gt;
** path() was refactored to avoid string concatenation&lt;br /&gt;
** set_team_directory_num() was refactored method name to match behavior&lt;br /&gt;
[[File:2503-10.png]]&lt;br /&gt;
** Refactored method name to match behavior&lt;br /&gt;
[[File:2503-11.png]]&lt;br /&gt;
&lt;br /&gt;
'''Refactor MentoredTeam Model'''&lt;br /&gt;
* Changes:&lt;br /&gt;
** Refactored add_member to override Team.add_member to handle assigning a mentor&lt;br /&gt;
[[File:2503-12.png]]&lt;br /&gt;
= Test Plan =&lt;br /&gt;
This project involves refactoring the Team hierarchy, ensuring that existing functionality remains unchanged while improving structure and maintainability. Since the refactor involves modifying class structures, consolidating redundant methods, and introducing better encapsulation, the following steps were taken to validate correctness:&lt;br /&gt;
* Refactored RSpec test files to reflect changes in class structure, method names, and logic updates.&lt;br /&gt;
* Ran the test suite after each major change to verify that functionality remained consistent across Team, CourseTeam, AssignmentTeam, and MentoredTeam.&lt;br /&gt;
* Ensured that core team operations (adding/removing members, copying teams, importing/exporting teams) worked as expected by validating test outputs against pre-refactor results.&lt;br /&gt;
* Ensured all refactored classes maintained high test coverage, targeting at least 90% coverage in Team, AssignmentTeam, and CourseTeam.&lt;br /&gt;
* Ensured that removed methods were either unnecessary or replaced with equivalent logic in the refactored structure.&lt;br /&gt;
* Validated UI functionality by testing that teams were correctly displayed, managed, and interacted with in the system.&lt;br /&gt;
[[File:I1.png]]&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:2503-12.png&amp;diff=162873</id>
		<title>File:2503-12.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:2503-12.png&amp;diff=162873"/>
		<updated>2025-03-26T17:55:32Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:2503-11.png&amp;diff=162872</id>
		<title>File:2503-11.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:2503-11.png&amp;diff=162872"/>
		<updated>2025-03-26T17:55:24Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:2503-10.png&amp;diff=162871</id>
		<title>File:2503-10.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:2503-10.png&amp;diff=162871"/>
		<updated>2025-03-26T17:55:16Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:2503-9.png&amp;diff=162870</id>
		<title>File:2503-9.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:2503-9.png&amp;diff=162870"/>
		<updated>2025-03-26T17:55:07Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:2503-8.png&amp;diff=162869</id>
		<title>File:2503-8.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:2503-8.png&amp;diff=162869"/>
		<updated>2025-03-26T17:55:00Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:2503-7.png&amp;diff=162868</id>
		<title>File:2503-7.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:2503-7.png&amp;diff=162868"/>
		<updated>2025-03-26T17:54:49Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:2503-6.png&amp;diff=162867</id>
		<title>File:2503-6.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:2503-6.png&amp;diff=162867"/>
		<updated>2025-03-26T17:54:38Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2503._Refactor_the_Team_hierarchy&amp;diff=162866</id>
		<title>CSC/ECE 517 Spring 2025 - E2503. Refactor the Team hierarchy</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2503._Refactor_the_Team_hierarchy&amp;diff=162866"/>
		<updated>2025-03-26T17:53:42Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: added screenshots 2503-1 -&amp;gt; 2503-5&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Team Information =&lt;br /&gt;
'''Mentor:'''&lt;br /&gt;
* Ed Gehringer&lt;br /&gt;
&lt;br /&gt;
'''Team Members:'''&lt;br /&gt;
* Ahmed Hassan (aohassan)&lt;br /&gt;
&lt;br /&gt;
* Rameez Malik (remalik)&lt;br /&gt;
&lt;br /&gt;
* Moaad Benkaraache (mbenkar)&lt;br /&gt;
&lt;br /&gt;
'''Relevant Links:'''&lt;br /&gt;
* Link to Expertiza Repository: https://github.com/expertiza/expertiza&lt;br /&gt;
* Link to Forked Repository: https://github.com/AhmedOHassan/expertiza&lt;br /&gt;
* Link to Pull Request: https://github.com/expertiza/expertiza/pull/2941&lt;br /&gt;
&lt;br /&gt;
= Expertiza Background =&lt;br /&gt;
Expertiza is an open-source project built using the Ruby on Rails MVC framework, designed to facilitate peer review and collaborative learning. The project has undergone multiple iterations, with ongoing efforts focused on refactoring the existing codebase to improve maintainability, efficiency, and scalability. Additionally, there are initiatives aimed at reimplementing a new version of Expertiza to enhance its architecture and functionality.&lt;br /&gt;
&lt;br /&gt;
= About Team/CourseTeam/AssignmentTeam/MentoredTeam =&lt;br /&gt;
The Team hierarchy contains the classes that hold teams of students enrolled in Expertiza. Teams can reserve topics and submit work. There are currently four classes in the team hierarchy: Team, CourseTeam, AssignmentTeam, and MentoredTeam. Instances of the Team superclass should never be created since any actual team will be a member of one of the three other classes. CourseTeams stay together for the entire course duration and work on all assignments together. Although some instructors choose not to use CourseTeams, others employ Team-Based Learning and do benefit from using CourseTeams. It is possible to both copy CourseTeams into AssignmentTeams, and vice-versa. Any team formed to take part in an assignment will be an AssignmentTeam, unless the assignment is set up to automatically assign mentors to teams. In this case, the assignment teams will be created as MentoredTeams (a subclass of AssignmentTeam) which has a designated member known as the mentor. &lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
The Team hierarchy in Expertiza is responsible for managing student teams, allowing them to reserve topics, submit work, and, in some cases, review other teams' submissions. However, the current implementation is overly complex, with redundant methods and unnecessary dependencies. The Team class has 27 methods, many of which should be refactored or removed, while AssignmentTeam contains 36 methods, several of which duplicate functionality from the superclass. Additionally, the system currently models team members as Users, but the new design will transition to Participants, requiring updates to team membership logic.&lt;br /&gt;
&lt;br /&gt;
= Tasks =&lt;br /&gt;
'''Refactoring the Team Hierarchy'''&lt;br /&gt;
* Prevent direct instantiation of Team, ensuring all actual teams belong to CourseTeam, AssignmentTeam, or MentoredTeam. &lt;br /&gt;
* Move only the core shared functionalities to the Team and reduce the method count.&lt;br /&gt;
* Eliminate Redundant Methods in AssignmentTeam and CourseTeam.&lt;br /&gt;
* Identify duplicate methods across Team, AssignmentTeam, and CourseTeam.&lt;br /&gt;
* Ensure CourseTeam and AssignmentTeam override import/export functionality from Team instead of defining separate versions.&lt;br /&gt;
&lt;br /&gt;
'''Transition from Users to Participants '''&lt;br /&gt;
* Modify add_member and related methods to work with CourseParticipants and AssignmentParticipants instead of Users.&lt;br /&gt;
* Ensure teams enforce correct membership rules (e.g., CourseTeam only accepts CourseParticipants).&lt;br /&gt;
&lt;br /&gt;
'''Optimizing Team Copying'''&lt;br /&gt;
* Ensure clear and efficient handling of copying between AssignmentTeam and CourseTeam.&lt;br /&gt;
* Consolidate logic for copying members across different team types.&lt;br /&gt;
&lt;br /&gt;
'''Improving Method Clarity and Encapsulation'''&lt;br /&gt;
* Convert class methods like size into instance methods.&lt;br /&gt;
* Standardize method naming conventions for clarity (e.g., avoid inconsistencies like copy_members vs. copy_content).&lt;br /&gt;
&lt;br /&gt;
'''Removing Unused and Inefficient Code'''&lt;br /&gt;
* Identify and remove any unused methods in Team, AssignmentTeam, and CourseTeam. &lt;br /&gt;
* Remove commented-out or deprecated code that no longer serves a purpose. &lt;br /&gt;
* Simplify methods that are overly complex by leveraging helper functions where necessary. &lt;br /&gt;
&lt;br /&gt;
'''Testing and Code Validation'''&lt;br /&gt;
* Update tests to reflect the refactored team hierarchy and ensure correctness. &lt;br /&gt;
* Remove or rewrite tests that validate methods no longer in use.&lt;br /&gt;
&lt;br /&gt;
= Plan of Work =&lt;br /&gt;
We began by listing all of the methods belonging to each class in the Team hierarchy. Next, we met with our mentor (Dr. Gehringer) and reviewed every single method’s readability, maintainability, and adherence to best practices (SOLID principles, DRY, etc.). Once we organized the methods by class, we assigned groups of methods as tasks amongst team members and began refactoring existing methods while making sure existing test cases still passed and new tests were added as needed.&lt;br /&gt;
&lt;br /&gt;
= Implementation =&lt;br /&gt;
'''Refactor Team Model'''&lt;br /&gt;
* Methods involved:&lt;br /&gt;
** self.allowed_types&lt;br /&gt;
** self.team_operation&lt;br /&gt;
** self.responses&lt;br /&gt;
** author_names&lt;br /&gt;
** user?(user)&lt;br /&gt;
** add_member(user, _assignment_id = nil)&lt;br /&gt;
** self.size(team_id)&lt;br /&gt;
** copy_members(new_team)&lt;br /&gt;
** self.check_for_existing(parent, name, team_type)&lt;br /&gt;
** self.randomize_all_by_parent(parent, team_type, min_team_size)&lt;br /&gt;
** self.create_team_from_single_users(min_team_size, parent, team_type, users)&lt;br /&gt;
** self.assign_single_users_to_teams(min_team_size, parent, teams, users)&lt;br /&gt;
** self.generate_team_name(_team_name_prefix = “”)&lt;br /&gt;
** self.create_team_and_node(id)&lt;br /&gt;
** self.create_team_with_users(parent_id, user_ids)&lt;br /&gt;
** self.remove_user_from_previous_team(parent_id, user_id)&lt;br /&gt;
** self.find_team_users(assignment_id, user_id)&lt;br /&gt;
&lt;br /&gt;
* Problems/Solutions:&lt;br /&gt;
** The refactoring efforts addressed several key issues in Expertiza's codebase, including redundancy, unclear naming, and inefficient implementations. &lt;br /&gt;
** Unnecessary methods and parameters were removed or consolidated, improving code clarity and maintainability.&lt;br /&gt;
** Naming conventions were refined to better reflect functionality, and certain methods were moved to more appropriate classes, such as CourseTeam and AssignmentTeam.&lt;br /&gt;
** The use of ActiveRecord's dependent destroy was implemented to ensure proper cleanup of associated records.&lt;br /&gt;
** Additionally, alternative implementations were suggested to simplify logic, such as replacing redundant methods with built-in Rails queries and using uniqueness validation instead of manual checks.&lt;br /&gt;
** Improvements were proposed for import/export methods.&lt;br /&gt;
&lt;br /&gt;
* Changes:&lt;br /&gt;
** Moved parent_entity_type and self.find_parent_entity(id) from CourseTeam to Team.&lt;br /&gt;
[[File:2503-0.png]]&lt;br /&gt;
** Renamed author_names to member_names.&lt;br /&gt;
[[File:2503-1.png]]&lt;br /&gt;
** Removed unnecessary parameter from add_member; replaced size with instance method; CourseTeam’s add_participant method was removed, and CourseTeam inherits Team.add_member instead.&lt;br /&gt;
[[File:2503-2.png]]&lt;br /&gt;
** Renamed randomize_all_by_parent to create_random_teams.&lt;br /&gt;
[[File:2503-3.png]]&lt;br /&gt;
** Renamed create_team_from_single_users to team_from_users.&lt;br /&gt;
[[File:2503-4.png]]&lt;br /&gt;
** No changes to self.handle_duplicate.&lt;br /&gt;
[[File:2503-5.png]]&lt;br /&gt;
** Added optional user_ids parameter to facilitate removal of create_team_with_users method to avoid redundancy.&lt;br /&gt;
&lt;br /&gt;
'''Refactor CourseTeam Model'''&lt;br /&gt;
* Changes:&lt;br /&gt;
** Refactored the code and now the method called copy_to_assignment()&lt;br /&gt;
&lt;br /&gt;
'''Refactor AssignmentTeam Model'''&lt;br /&gt;
* Changes:&lt;br /&gt;
** assign_reviewer left as is [no change]&lt;br /&gt;
** get_reviewer() was renamed to reviewer()&lt;br /&gt;
** reviewed_by left() as is [no change]&lt;br /&gt;
** topic() renamed to topic_id()&lt;br /&gt;
** files() refactored to use an iterator-based approach&lt;br /&gt;
** For set.export_fields(), enabled fields to be an explicit return value to improve readability&lt;br /&gt;
** self.remove_team_by_id left as is, very concise; “unless nil” check ensures safety&lt;br /&gt;
** path() was refactored to avoid string concatenation&lt;br /&gt;
** set_team_directory_num() was refactored method name to match behavior&lt;br /&gt;
** Refactored method name to match behavior&lt;br /&gt;
&lt;br /&gt;
'''Refactor MentoredTeam Model'''&lt;br /&gt;
* Changes:&lt;br /&gt;
** Refactored add_member to override Team.add_member to handle assigning a mentor&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
This project involves refactoring the Team hierarchy, ensuring that existing functionality remains unchanged while improving structure and maintainability. Since the refactor involves modifying class structures, consolidating redundant methods, and introducing better encapsulation, the following steps were taken to validate correctness:&lt;br /&gt;
* Refactored RSpec test files to reflect changes in class structure, method names, and logic updates.&lt;br /&gt;
* Ran the test suite after each major change to verify that functionality remained consistent across Team, CourseTeam, AssignmentTeam, and MentoredTeam.&lt;br /&gt;
* Ensured that core team operations (adding/removing members, copying teams, importing/exporting teams) worked as expected by validating test outputs against pre-refactor results.&lt;br /&gt;
* Ensured all refactored classes maintained high test coverage, targeting at least 90% coverage in Team, AssignmentTeam, and CourseTeam.&lt;br /&gt;
* Ensured that removed methods were either unnecessary or replaced with equivalent logic in the refactored structure.&lt;br /&gt;
* Validated UI functionality by testing that teams were correctly displayed, managed, and interacted with in the system.&lt;br /&gt;
[[File:I1.png]]&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:2503-5.png&amp;diff=162865</id>
		<title>File:2503-5.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:2503-5.png&amp;diff=162865"/>
		<updated>2025-03-26T17:51:50Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:2503-4.png&amp;diff=162864</id>
		<title>File:2503-4.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:2503-4.png&amp;diff=162864"/>
		<updated>2025-03-26T17:51:42Z</updated>

		<summary type="html">&lt;p&gt;Mbenkar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mbenkar</name></author>
	</entry>
</feed>