<?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=Asingh78</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=Asingh78"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Asingh78"/>
	<updated>2026-08-10T23:15:35Z</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_-_E2516._Reimplement_teams_users_controller.rb&amp;diff=163497</id>
		<title>CSC/ECE 517 Spring 2025 - E2516. Reimplement teams users controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2516._Reimplement_teams_users_controller.rb&amp;diff=163497"/>
		<updated>2025-04-08T00:30:28Z</updated>

		<summary type="html">&lt;p&gt;Asingh78: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2516: Reimplement teams_users_controller.rb==&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
Expertiza is an open-source platform designed to support education by streamlining assignment management. It offers a wide range of features: instructors can create and manage assignments, while students can submit their work in various file formats. One unique aspect is the peer review system, where students can review each other’s submissions. It also supports team-based work, allowing students to collaborate on assignments or projects. Overall, the platform helps both professors and students stay organized and work more efficiently.&lt;br /&gt;
&lt;br /&gt;
===Overview===&lt;br /&gt;
Our goal for this project is to reimplement the TeamUsersController and change it to TeamsParticipantsController thereby strictly following DRY and SOLID principles. Presently, the TeamsUsersController is responsible for managing the interactions between teams and participants. Teams are associated with assignments and courses while participants are associated with these.&lt;br /&gt;
&lt;br /&gt;
As of now, the controller achieves below mentioned functionalities:&lt;br /&gt;
&lt;br /&gt;
1. Listing team members&lt;br /&gt;
&lt;br /&gt;
2. Adding participants to teams&lt;br /&gt;
&lt;br /&gt;
3. Removing participants from teams&lt;br /&gt;
&lt;br /&gt;
4. Updating participants' duties within teams&lt;br /&gt;
&lt;br /&gt;
5. Providing autocomplete suggestions for participant names when adding new members&lt;br /&gt;
&lt;br /&gt;
6. Bulk deletion of team members&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the next project deliverable, we plan to achieve below mentioned functionalities:&lt;br /&gt;
&lt;br /&gt;
1. Modifying the TeamsUsersController to TeamsParticipantsController and respectively modifying the associations and related methods and classes&lt;br /&gt;
&lt;br /&gt;
2. We plan to achieve separation of concerns between models and classes and aim to minimize coupling&lt;br /&gt;
&lt;br /&gt;
3. More test cases and test suites will be implement to test the robustness and effectiveness of the changes modified&lt;br /&gt;
&lt;br /&gt;
4. Achieving code readability and maintainability by providing descriptive comments wherever necessary and maintaining consistent naming conventions for variables&lt;br /&gt;
&lt;br /&gt;
===Problem Description===&lt;br /&gt;
Currently our controller presents with below mentioned major issues:&lt;br /&gt;
&lt;br /&gt;
1. Incorrect Association Representation: The TeamsUser model links a User with a Team , not taking into consideration whether the User is assigned with a course or an assignment and generating ambiguity.&lt;br /&gt;
&lt;br /&gt;
2. Violation of SOLID/DRY Principles: The methods in the controllers are very long and contain unnecessary logic and redundant code&lt;br /&gt;
&lt;br /&gt;
3. Tight Coupling: Currently, there is a business logic code that resides in the model whereas it should have been placed in the controller. This results in a higher coupling and introduces difficulties in the future while modifying code.&lt;br /&gt;
&lt;br /&gt;
4. Inconsistent code quality: Many places in the code have inconsistent naming conventions for the variables. &lt;br /&gt;
&lt;br /&gt;
5. Insufficient Testing: Currently, testing has not been performed to a great extent and so the effectiveness of the existing codebase cannot be determined.&lt;br /&gt;
&lt;br /&gt;
===Scope of Work===&lt;br /&gt;
The current work will involve the below implementation effort:&lt;br /&gt;
&lt;br /&gt;
1. Model Refactoring&lt;br /&gt;
* Replace TeamsUsers controller with TeamsParticipants&lt;br /&gt;
* Update the database association structure to link TeamsParticipant with Partipant and Team&lt;br /&gt;
2. Controller Redesign&lt;br /&gt;
* Reimplementing a new TeamsParticipantsController which handles associations between teams and participants and achieves all functionalities listed in above section&lt;br /&gt;
* Ensure controller actions focus on request/response handling and delegating business logic to models&lt;br /&gt;
3. Create Method Refactor&lt;br /&gt;
* Breaking down create method in the controller into smaller, reusable, testable private methods&lt;br /&gt;
* Eliminate code duplication and unnecessary nesting&lt;br /&gt;
4. Model Enhancements&lt;br /&gt;
* Using the concept of polymorphism to clearly handle team membership and association rules&lt;br /&gt;
* Introducing checks related to whether a user is part of multiple teams and ensuring this is satisfied only in case of a mentor who can be assigned multiple teams&lt;br /&gt;
5. Code Quality Improvements&lt;br /&gt;
* Ensuring consistent naming conventions for variables&lt;br /&gt;
* Descriptive comments to make code more reliable and understandable&lt;br /&gt;
* Applying code best practises throughout codebase to ensure consistency&lt;br /&gt;
6. Testing&lt;br /&gt;
* Including RSpec tests for each controller method (e.g. index, create, delete etc.)&lt;br /&gt;
* Implement tests in models wherever additional business logic has been added&lt;br /&gt;
* Perform manual testing to ensure feature completeness and correctness&lt;br /&gt;
7. Documentation&lt;br /&gt;
* A detailed documentation providing the behavior of the controller and what it tries to achieve &lt;br /&gt;
* It should also include the associations between different entities and model and controller interactions&lt;br /&gt;
===Changes Proposed===&lt;br /&gt;
= Summary of Refactor =&lt;br /&gt;
&lt;br /&gt;
* '''Replaced''' all references to &amp;lt;code&amp;gt;TeamsUser&amp;lt;/code&amp;gt; with &amp;lt;code&amp;gt;TeamsParticipant&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* '''Refactored''' long methods (especially &amp;lt;code&amp;gt;create&amp;lt;/code&amp;gt;) into smaller private methods.&lt;br /&gt;
&lt;br /&gt;
* '''Moved''' business logic to &amp;lt;code&amp;gt;AssignmentTeam&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;MentoredTeam&amp;lt;/code&amp;gt; where appropriate (e.g., mentor-specific rules).&lt;br /&gt;
&lt;br /&gt;
* '''Removed''' unnecessary nesting in methods like &amp;lt;code&amp;gt;create&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* '''Improved''' naming conventions for all variables.&lt;br /&gt;
&lt;br /&gt;
* '''Enhanced''' comments to explain functionality clearly.&lt;br /&gt;
&lt;br /&gt;
* '''Ensured''' SOLID Principles are followed across all code.&lt;br /&gt;
&lt;br /&gt;
* '''Wrote''' new unit and integration tests for controller methods.&lt;br /&gt;
&lt;br /&gt;
= Proposed Flow for Major Methods =&lt;br /&gt;
&lt;br /&gt;
== index ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' &amp;lt;code&amp;gt;team_id&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Action:'''&lt;br /&gt;
Find team → Retrieve associated participants → Render list (JSON or HTML view).&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
Simplicity focus: Only data retrieval, no complex logic.&lt;br /&gt;
&lt;br /&gt;
== create ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' Participant information, &amp;lt;code&amp;gt;team_id&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Steps:'''&lt;br /&gt;
&lt;br /&gt;
Validate participant (exists, belongs to assignment/course).&lt;br /&gt;
Check team eligibility:&lt;br /&gt;
If participant is already on another team → Validate mentor exception rules (handled in model).&lt;br /&gt;
Create &amp;lt;code&amp;gt;TeamsParticipant&amp;lt;/code&amp;gt; record linking the participant and team.&lt;br /&gt;
Handle success/failure gracefully with appropriate responses.&lt;br /&gt;
'''Important:''' Keep business rules outside the controller wherever possible (delegate to model methods).&lt;br /&gt;
&lt;br /&gt;
== destroy ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' &amp;lt;code&amp;gt;teams_participant_id&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Action:'''&lt;br /&gt;
Remove participant from the team cleanly, handling foreign key constraints.&lt;br /&gt;
&lt;br /&gt;
== autocomplete_participants ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' &amp;lt;code&amp;gt;assignment_id&amp;lt;/code&amp;gt;, search string&lt;br /&gt;
&lt;br /&gt;
'''Action:'''&lt;br /&gt;
Return a list of matching participants for the given assignment.&lt;br /&gt;
&lt;br /&gt;
== bulk_delete ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' List of participant IDs&lt;br /&gt;
&lt;br /&gt;
'''Action:'''&lt;br /&gt;
Mass remove participants from their teams, validate permissions.&lt;br /&gt;
&lt;br /&gt;
= Helper Methods (Private) =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;find_team&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;find_participant&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;validate_participant_eligibility&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add_participant_to_team&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;remove_participant_from_team&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mentor_eligibility_check&amp;lt;/code&amp;gt; (Delegated to &amp;lt;code&amp;gt;AssignmentTeam&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;MentoredTeam&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Each method will have a clear single responsibility and promote reuse across the controller.&lt;br /&gt;
&lt;br /&gt;
= Notes on Migration =&lt;br /&gt;
&lt;br /&gt;
All foreign keys linking teams to users will point through &amp;lt;code&amp;gt;TeamsParticipants&amp;lt;/code&amp;gt;, not &amp;lt;code&amp;gt;TeamsUsers&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Update any related services or background jobs that previously depended on &amp;lt;code&amp;gt;TeamsUser&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Backward compatibility should be evaluated carefully to avoid breaking existing assignments or teams during the migration phase.&lt;br /&gt;
&lt;br /&gt;
= Files Changed =&lt;br /&gt;
&lt;br /&gt;
== TeamsParticipantsController ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Method&lt;br /&gt;
! Change&lt;br /&gt;
! Reason&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
| No Change&lt;br /&gt;
| Determines if the current user has the necessary privileges to perform the requested action.&lt;br /&gt;
|-&lt;br /&gt;
| auto_complete_for_user_name&lt;br /&gt;
| No Change&lt;br /&gt;
| Provides a list of possible team members based on a partial name search for autocomplete functionality.&lt;br /&gt;
|-&lt;br /&gt;
| update_duties&lt;br /&gt;
| No Change&lt;br /&gt;
| Updates the duty assigned to a participant within a team and redirects to the student's team view.&lt;br /&gt;
|-&lt;br /&gt;
| list&lt;br /&gt;
| No Change&lt;br /&gt;
| Displays all participants of a specific team with pagination support.&lt;br /&gt;
|-&lt;br /&gt;
| new&lt;br /&gt;
| No Change&lt;br /&gt;
| Prepares the form for adding a new participant.&lt;br /&gt;
|-&lt;br /&gt;
| create&lt;br /&gt;
| Refactored&lt;br /&gt;
| Validates eligibility before adding a participant; delegates business logic.&lt;br /&gt;
|-&lt;br /&gt;
| delete&lt;br /&gt;
| Refactored&lt;br /&gt;
| Removes participant cleanly with undo option.&lt;br /&gt;
|-&lt;br /&gt;
| delete_selected&lt;br /&gt;
| New&lt;br /&gt;
| Bulk deletes multiple participants from a team.&lt;br /&gt;
|-&lt;br /&gt;
| user_not_found_message (private)&lt;br /&gt;
| New&lt;br /&gt;
| Returns a specific message if a user is not found.&lt;br /&gt;
|-&lt;br /&gt;
| valid_participant? (private)&lt;br /&gt;
| New&lt;br /&gt;
| Checks eligibility of participant for assignment/course.&lt;br /&gt;
|-&lt;br /&gt;
| participant_not_found_message (private)&lt;br /&gt;
| New&lt;br /&gt;
| Provides feedback if participant not linked to assignment/course.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== AssignmentTeam.rb ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Method&lt;br /&gt;
! Change&lt;br /&gt;
! Reason&lt;br /&gt;
|-&lt;br /&gt;
| user_id(current_user = nil)&lt;br /&gt;
| Modified&lt;br /&gt;
| Added optional current_user param for better flexibility.&lt;br /&gt;
|-&lt;br /&gt;
| set_current_user&lt;br /&gt;
| Removed&lt;br /&gt;
| Logic merged into user_id.&lt;br /&gt;
|-&lt;br /&gt;
| includes?(participant)&lt;br /&gt;
| Retained (Minor rewording)&lt;br /&gt;
| Direct comparison with updated participant fetching logic.&lt;br /&gt;
|-&lt;br /&gt;
| parent_model&lt;br /&gt;
| Retained&lt;br /&gt;
| Returns 'Assignment' as parent model.&lt;br /&gt;
|-&lt;br /&gt;
| self.parent_model(id)&lt;br /&gt;
| Removed&lt;br /&gt;
| Responsibility moved elsewhere for separation of concerns.&lt;br /&gt;
|-&lt;br /&gt;
| fullname&lt;br /&gt;
| Removed&lt;br /&gt;
| Deemed unnecessary alias.&lt;br /&gt;
|-&lt;br /&gt;
| review_map_type&lt;br /&gt;
| Removed&lt;br /&gt;
| Hardcoding removed to reduce tight coupling.&lt;br /&gt;
|-&lt;br /&gt;
| prototype&lt;br /&gt;
| Removed&lt;br /&gt;
| Not needed under Rails ActiveRecord conventions.&lt;br /&gt;
|-&lt;br /&gt;
| assign_reviewer&lt;br /&gt;
| Modified&lt;br /&gt;
| Extracted review map creation into create_review_map.&lt;br /&gt;
|-&lt;br /&gt;
| create_review_map&lt;br /&gt;
| New&lt;br /&gt;
| Dedicated method for creating review maps.&lt;br /&gt;
|-&lt;br /&gt;
| get_reviewer&lt;br /&gt;
| Removed&lt;br /&gt;
| Reviewer assignment simplified.&lt;br /&gt;
|-&lt;br /&gt;
| reviewed_by?&lt;br /&gt;
| Modified&lt;br /&gt;
| Now uses ReviewResponseMap.exists? for better DB efficiency.&lt;br /&gt;
|-&lt;br /&gt;
| topic&lt;br /&gt;
| Removed&lt;br /&gt;
| Responsibility split for cleaner structure.&lt;br /&gt;
|-&lt;br /&gt;
| has_submissions?&lt;br /&gt;
| Retained&lt;br /&gt;
| Basic file/submission existence checks.&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| Modified&lt;br /&gt;
| Refactored using TeamsParticipant.team_members(id).&lt;br /&gt;
|-&lt;br /&gt;
| add_participant&lt;br /&gt;
| Modified&lt;br /&gt;
| Creates a TeamsParticipant directly.&lt;br /&gt;
|-&lt;br /&gt;
| delete &amp;amp; destroy&lt;br /&gt;
| Removed&lt;br /&gt;
| Simplified elsewhere.&lt;br /&gt;
|-&lt;br /&gt;
| first_member&lt;br /&gt;
| Removed&lt;br /&gt;
| SRP enforcement.&lt;br /&gt;
|-&lt;br /&gt;
| submitted_files(path)&lt;br /&gt;
| Removed&lt;br /&gt;
| File access logic shifted to service.&lt;br /&gt;
|-&lt;br /&gt;
| import/export methods&lt;br /&gt;
| Removed&lt;br /&gt;
| Responsibility moved to helpers/services.&lt;br /&gt;
|-&lt;br /&gt;
| copy(course_id)&lt;br /&gt;
| Removed&lt;br /&gt;
| Refactored externally.&lt;br /&gt;
|-&lt;br /&gt;
| hyperlinks&lt;br /&gt;
| Removed&lt;br /&gt;
| Delegated to service.&lt;br /&gt;
|-&lt;br /&gt;
| submit_hyperlink(hyperlink)&lt;br /&gt;
| Modified (Delegated)&lt;br /&gt;
| Handled by TeamFileService.&lt;br /&gt;
|-&lt;br /&gt;
| remove_hyperlink(hyperlink)&lt;br /&gt;
| Modified (Delegated)&lt;br /&gt;
| Handled by TeamFileService.&lt;br /&gt;
|-&lt;br /&gt;
| files(directory)&lt;br /&gt;
| Removed&lt;br /&gt;
| File traversal extracted.&lt;br /&gt;
|-&lt;br /&gt;
| team(participant)&lt;br /&gt;
| Removed&lt;br /&gt;
| Moved to higher-level service.&lt;br /&gt;
|-&lt;br /&gt;
| export_fields(options)&lt;br /&gt;
| Removed&lt;br /&gt;
| Offloaded for SRP.&lt;br /&gt;
|-&lt;br /&gt;
| remove_team_by_id(id)&lt;br /&gt;
| Removed&lt;br /&gt;
| Refactored.&lt;br /&gt;
|-&lt;br /&gt;
| path&lt;br /&gt;
| Removed&lt;br /&gt;
| File path responsibility shifted.&lt;br /&gt;
|-&lt;br /&gt;
| set_student_directory_num&lt;br /&gt;
| Removed&lt;br /&gt;
| Directory numbering moved.&lt;br /&gt;
|-&lt;br /&gt;
| received_any_peer_review?&lt;br /&gt;
| Removed&lt;br /&gt;
| Simplified elsewhere.&lt;br /&gt;
|-&lt;br /&gt;
| most_recent_submission&lt;br /&gt;
| Retained (Optimized)&lt;br /&gt;
| Improved query efficiency.&lt;br /&gt;
|-&lt;br /&gt;
| get_logged_in_reviewer_id(current_user_id)&lt;br /&gt;
| Removed&lt;br /&gt;
| Participant-reviewer handling refactored.&lt;br /&gt;
|-&lt;br /&gt;
| current_user_is_reviewer?(current_user_id)&lt;br /&gt;
| Removed&lt;br /&gt;
| Responsibility simplified.&lt;br /&gt;
|-&lt;br /&gt;
| create_new_team(user_id, signuptopic)&lt;br /&gt;
| Modified (Simplified)&lt;br /&gt;
| Refactored for better exception handling.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MentoredTeam.rb ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Method&lt;br /&gt;
! Change&lt;br /&gt;
! Reason&lt;br /&gt;
|-&lt;br /&gt;
| add_member(user, _assignment_id = nil)&lt;br /&gt;
| Refactored&lt;br /&gt;
| Broken into modular private methods for adding users and assigning mentors.&lt;br /&gt;
|-&lt;br /&gt;
| import_team_members(row_hash)&lt;br /&gt;
| Refactored&lt;br /&gt;
| Improved to skip blanks, safe user lookup, and error handling.&lt;br /&gt;
|-&lt;br /&gt;
| can_add_member?(user)&lt;br /&gt;
| New&lt;br /&gt;
| Private method for team capacity and mentor assignment validation.&lt;br /&gt;
|-&lt;br /&gt;
| add_team_user(user)&lt;br /&gt;
| New&lt;br /&gt;
| Cleanly adds a TeamsUser.&lt;br /&gt;
|-&lt;br /&gt;
| add_participant_to_team(user)&lt;br /&gt;
| New&lt;br /&gt;
| Adds participant based on assignment.&lt;br /&gt;
|-&lt;br /&gt;
| assign_mentor_if_needed(_assignment_id)&lt;br /&gt;
| New&lt;br /&gt;
| Ensures no duplicate mentors are assigned.&lt;br /&gt;
|-&lt;br /&gt;
| mentor_assignment_valid?(user)&lt;br /&gt;
| New&lt;br /&gt;
| Validates mentor assignment rules.&lt;br /&gt;
|-&lt;br /&gt;
| user_not_in_team?(user)&lt;br /&gt;
| New&lt;br /&gt;
| Checks if user is already part of the team.&lt;br /&gt;
|-&lt;br /&gt;
| find_or_raise_user(teammate)&lt;br /&gt;
| New&lt;br /&gt;
| Finds user or raises informative ImportError.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== TeamsParticipants Model ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Aspect&lt;br /&gt;
! Change&lt;br /&gt;
! Reason&lt;br /&gt;
|-&lt;br /&gt;
| Association&lt;br /&gt;
| New&lt;br /&gt;
| Establishes direct link between Participant and Team to maintain integrity.&lt;br /&gt;
|-&lt;br /&gt;
| team_members&lt;br /&gt;
| New&lt;br /&gt;
| Retrieves all users associated through participants.&lt;br /&gt;
|-&lt;br /&gt;
| remove_participant_from_team&lt;br /&gt;
| New&lt;br /&gt;
| Safely removes participant from team.&lt;br /&gt;
|-&lt;br /&gt;
| username delegation&lt;br /&gt;
| New&lt;br /&gt;
| Delegates access to participant's username.&lt;br /&gt;
|-&lt;br /&gt;
| Integrity&lt;br /&gt;
| New&lt;br /&gt;
| Ensures only valid assignment participants can join teams.&lt;br /&gt;
|-&lt;br /&gt;
| Maintainability&lt;br /&gt;
| New&lt;br /&gt;
| Designed to align with SOLID principles and Rails best practices.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Testing Plan =&lt;br /&gt;
We plan to cover the reimplementation and refactoring of the following:&lt;br /&gt;
* AssignmentTeam&lt;br /&gt;
* MentoredTeam&lt;br /&gt;
* TeamsParticipantsController&lt;br /&gt;
* TeamsParticipant model&lt;br /&gt;
&lt;br /&gt;
We use RSpec for model, controller, and request specs. API tests are also included where applicable.  &lt;br /&gt;
Both positive and negative test cases are included to ensure robust functionality, along with validation checks and authorization verifications.&lt;br /&gt;
&lt;br /&gt;
== AssignmentTeam Model Tests ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! # !! Method !! Test Description&lt;br /&gt;
|-&lt;br /&gt;
| 1 || user_id || Verify that the correct user ID is returned; prioritize current user if available.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || includes? || Check if a given participant is part of the team.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || parent_model || Ensure the parent model returns &amp;quot;Assignment&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || assign_reviewer || Test reviewer assignment creation and error handling when assignment is not found.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || create_review_map || Confirm a new ReviewResponseMap record is created successfully.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || reviewed_by? || Verify if a reviewer has reviewed the team; test both true and false scenarios.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || participants || Ensure the correct participants are retrieved via TeamsParticipant.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || add_participant || Confirm that a participant is added, and prevent duplicate addition.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || create_new_team || Ensure that a new team-user linkage, sign-up, and nodes are created properly.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || submit_hyperlink || Verify delegation to TeamFileService for hyperlink submission.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || remove_hyperlink || Verify delegation to TeamFileService for hyperlink removal.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || has_submissions? || Check behavior when team has submissions and when it doesn't.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || most_recent_submission || Ensure the most recent submission is retrieved based on updated_at.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MentoredTeam Model Tests ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! # !! Method !! Test Description&lt;br /&gt;
|-&lt;br /&gt;
| 1 || import_team_members || Ensure team members are imported from a list correctly.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || find_or_raise_user || Test for successful user lookup and error raising if user not found.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || user_not_in_team? || Confirm whether a user is already in the team or not.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || mentor_assignment_valid? || Verify that a mentor can be assigned properly and prevent duplicate mentors.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || add_member || Ensure user is added successfully and prevent re-adding existing team members.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || can_add_member? || Verify team capacity check before adding a member.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || add_team_user || Ensure that a TeamsUser is created and linked correctly.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || add_participant_to_team || Confirm that a participant is correctly linked to the team.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || assign_mentor_if_needed || Validate that mentor is assigned only when needed (no double assignment).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== TeamsParticipantsController Tests ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! # !! Method !! Test Description&lt;br /&gt;
|-&lt;br /&gt;
| 1 || valid_participant? || Confirm existence check for a participant; return true/false accordingly.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || update_duties || Test participant duty update flow and ensure a redirect occurs.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || user_not_found_message || Validate that a proper flash message is returned when a user isn't found.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || participant_not_found_message || Validate correct error message if participant isn't linked.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || create || Confirm that creating a TeamsParticipant increases record count.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || list || Test that the participant list view renders correctly.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || action_allowed? || Ensure access control is enforced based on user roles (admin/TA/student).&lt;br /&gt;
|-&lt;br /&gt;
| 8 || delete || Confirm deletion of a TeamsParticipant entry works correctly.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || auto_complete_for_user_name || Verify that JSON autocomplete results are returned based on user input.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || new || Test that the new participant view loads successfully.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || delete_selected || Ensure multiple TeamsParticipant records can be deleted at once.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== TeamsParticipant Model Tests ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! # !! Method !! Test Description&lt;br /&gt;
|-&lt;br /&gt;
| 1 || Associations || Ensure that a TeamsParticipant correctly belongs to a team and participant.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Validations || Confirm presence validations on team and participant relationships.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || team_members || Validate fetching all team members given a team ID.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || participant? || Verify participant existence check for a given user; test positive and negative cases.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== TeamsParticipants API (Request Specs) ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! # !! Endpoint !! Test Description&lt;br /&gt;
|-&lt;br /&gt;
| 1 || POST /teams_participants || Ensure a participant is added via API and redirects successfully.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || DELETE /teams_participants/:id || Ensure a participant is deleted via API and redirects successfully.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Vihar Manojkumar Shah([mailto:vshah23@ncsu.edu vshah23@ncsu.edu])&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Manav Kamdar               ([mailto:mkamdar@ncsu.edu mkamdar@ncsu.edu])&lt;br /&gt;
* Aditya Singh                 ([mailto:asingh78@ncsu.edu asingh78@ncsu.edu])&lt;br /&gt;
* Shivang Patel          ([mailto:spatel74@ncsu.edu spatel74@ncsu.edu])&lt;/div&gt;</summary>
		<author><name>Asingh78</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2516._Reimplement_teams_users_controller.rb&amp;diff=163496</id>
		<title>CSC/ECE 517 Spring 2025 - E2516. Reimplement teams users controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2516._Reimplement_teams_users_controller.rb&amp;diff=163496"/>
		<updated>2025-04-08T00:29:15Z</updated>

		<summary type="html">&lt;p&gt;Asingh78: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2516: Reimplement teams_users_controller.rb==&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
Expertiza is an open-source platform designed to support education by streamlining assignment management. It offers a wide range of features: instructors can create and manage assignments, while students can submit their work in various file formats. One unique aspect is the peer review system, where students can review each other’s submissions. It also supports team-based work, allowing students to collaborate on assignments or projects. Overall, the platform helps both professors and students stay organized and work more efficiently.&lt;br /&gt;
&lt;br /&gt;
===Overview===&lt;br /&gt;
Our goal for this project is to reimplement the TeamUsersController and change it to TeamsParticipantsController thereby strictly following DRY and SOLID principles. Presently, the TeamsUsersController is responsible for managing the interactions between teams and participants. Teams are associated with assignments and courses while participants are associated with these.&lt;br /&gt;
&lt;br /&gt;
As of now, the controller achieves below mentioned functionalities:&lt;br /&gt;
&lt;br /&gt;
1. Listing team members&lt;br /&gt;
&lt;br /&gt;
2. Adding participants to teams&lt;br /&gt;
&lt;br /&gt;
3. Removing participants from teams&lt;br /&gt;
&lt;br /&gt;
4. Updating participants' duties within teams&lt;br /&gt;
&lt;br /&gt;
5. Providing autocomplete suggestions for participant names when adding new members&lt;br /&gt;
&lt;br /&gt;
6. Bulk deletion of team members&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the next project deliverable, we plan to achieve below mentioned functionalities:&lt;br /&gt;
&lt;br /&gt;
1. Modifying the TeamsUsersController to TeamsParticipantsController and respectively modifying the associations and related methods and classes&lt;br /&gt;
&lt;br /&gt;
2. We plan to achieve separation of concerns between models and classes and aim to minimize coupling&lt;br /&gt;
&lt;br /&gt;
3. More test cases and test suites will be implement to test the robustness and effectiveness of the changes modified&lt;br /&gt;
&lt;br /&gt;
4. Achieving code readability and maintainability by providing descriptive comments wherever necessary and maintaining consistent naming conventions for variables&lt;br /&gt;
&lt;br /&gt;
===Problem Description===&lt;br /&gt;
Currently our controller presents with below mentioned major issues:&lt;br /&gt;
&lt;br /&gt;
1. Incorrect Association Representation: The TeamsUser model links a User with a Team , not taking into consideration whether the User is assigned with a course or an assignment and generating ambiguity.&lt;br /&gt;
&lt;br /&gt;
2. Violation of SOLID/DRY Principles: The methods in the controllers are very long and contain unnecessary logic and redundant code&lt;br /&gt;
&lt;br /&gt;
3. Tight Coupling: Currently, there is a business logic code that resides in the model whereas it should have been placed in the controller. This results in a higher coupling and introduces difficulties in the future while modifying code.&lt;br /&gt;
&lt;br /&gt;
4. Inconsistent code quality: Many places in the code have inconsistent naming conventions for the variables. &lt;br /&gt;
&lt;br /&gt;
5. Insufficient Testing: Currently, testing has not been performed to a great extent and so the effectiveness of the existing codebase cannot be determined.&lt;br /&gt;
&lt;br /&gt;
===Scope of Work===&lt;br /&gt;
The current work will involve the below implementation effort:&lt;br /&gt;
&lt;br /&gt;
1. Model Refactoring&lt;br /&gt;
* Replace TeamsUsers controller with TeamsParticipants&lt;br /&gt;
* Update the database association structure to link TeamsParticipant with Partipant and Team&lt;br /&gt;
2. Controller Redesign&lt;br /&gt;
* Reimplementing a new TeamsParticipantsController which handles associations between teams and participants and achieves all functionalities listed in above section&lt;br /&gt;
* Ensure controller actions focus on request/response handling and delegating business logic to models&lt;br /&gt;
3. Create Method Refactor&lt;br /&gt;
* Breaking down create method in the controller into smaller, reusable, testable private methods&lt;br /&gt;
* Eliminate code duplication and unnecessary nesting&lt;br /&gt;
4. Model Enhancements&lt;br /&gt;
* Using the concept of polymorphism to clearly handle team membership and association rules&lt;br /&gt;
* Introducing checks related to whether a user is part of multiple teams and ensuring this is satisfied only in case of a mentor who can be assigned multiple teams&lt;br /&gt;
5. Code Quality Improvements&lt;br /&gt;
* Ensuring consistent naming conventions for variables&lt;br /&gt;
* Descriptive comments to make code more reliable and understandable&lt;br /&gt;
* Applying code best practises throughout codebase to ensure consistency&lt;br /&gt;
6. Testing&lt;br /&gt;
* Including RSpec tests for each controller method (e.g. index, create, delete etc.)&lt;br /&gt;
* Implement tests in models wherever additional business logic has been added&lt;br /&gt;
* Perform manual testing to ensure feature completeness and correctness&lt;br /&gt;
7. Documentation&lt;br /&gt;
* A detailed documentation providing the behavior of the controller and what it tries to achieve &lt;br /&gt;
* It should also include the associations between different entities and model and controller interactions&lt;br /&gt;
===Changes Proposed===&lt;br /&gt;
= Summary of Refactor =&lt;br /&gt;
&lt;br /&gt;
'''Replaced''' all references to &amp;lt;code&amp;gt;TeamsUser&amp;lt;/code&amp;gt; with &amp;lt;code&amp;gt;TeamsParticipant&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Refactored''' long methods (especially &amp;lt;code&amp;gt;create&amp;lt;/code&amp;gt;) into smaller private methods.&lt;br /&gt;
&lt;br /&gt;
'''Moved''' business logic to &amp;lt;code&amp;gt;AssignmentTeam&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;MentoredTeam&amp;lt;/code&amp;gt; where appropriate (e.g., mentor-specific rules).&lt;br /&gt;
&lt;br /&gt;
'''Removed''' unnecessary nesting in methods like &amp;lt;code&amp;gt;create&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Improved''' naming conventions for all variables.&lt;br /&gt;
&lt;br /&gt;
'''Enhanced''' comments to explain functionality clearly.&lt;br /&gt;
&lt;br /&gt;
'''Ensured''' SOLID Principles are followed across all code.&lt;br /&gt;
&lt;br /&gt;
'''Wrote''' new unit and integration tests for controller methods.&lt;br /&gt;
&lt;br /&gt;
= Proposed Flow for Major Methods =&lt;br /&gt;
&lt;br /&gt;
== index ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' &amp;lt;code&amp;gt;team_id&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Action:'''&lt;br /&gt;
Find team → Retrieve associated participants → Render list (JSON or HTML view).&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
Simplicity focus: Only data retrieval, no complex logic.&lt;br /&gt;
&lt;br /&gt;
== create ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' Participant information, &amp;lt;code&amp;gt;team_id&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Steps:'''&lt;br /&gt;
&lt;br /&gt;
Validate participant (exists, belongs to assignment/course).&lt;br /&gt;
Check team eligibility:&lt;br /&gt;
If participant is already on another team → Validate mentor exception rules (handled in model).&lt;br /&gt;
Create &amp;lt;code&amp;gt;TeamsParticipant&amp;lt;/code&amp;gt; record linking the participant and team.&lt;br /&gt;
Handle success/failure gracefully with appropriate responses.&lt;br /&gt;
'''Important:''' Keep business rules outside the controller wherever possible (delegate to model methods).&lt;br /&gt;
&lt;br /&gt;
== destroy ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' &amp;lt;code&amp;gt;teams_participant_id&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Action:'''&lt;br /&gt;
Remove participant from the team cleanly, handling foreign key constraints.&lt;br /&gt;
&lt;br /&gt;
== autocomplete_participants ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' &amp;lt;code&amp;gt;assignment_id&amp;lt;/code&amp;gt;, search string&lt;br /&gt;
&lt;br /&gt;
'''Action:'''&lt;br /&gt;
Return a list of matching participants for the given assignment.&lt;br /&gt;
&lt;br /&gt;
== bulk_delete ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' List of participant IDs&lt;br /&gt;
&lt;br /&gt;
'''Action:'''&lt;br /&gt;
Mass remove participants from their teams, validate permissions.&lt;br /&gt;
&lt;br /&gt;
= Helper Methods (Private) =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;find_team&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;find_participant&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;validate_participant_eligibility&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add_participant_to_team&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;remove_participant_from_team&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mentor_eligibility_check&amp;lt;/code&amp;gt; (Delegated to &amp;lt;code&amp;gt;AssignmentTeam&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;MentoredTeam&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Each method will have a clear single responsibility and promote reuse across the controller.&lt;br /&gt;
&lt;br /&gt;
= Notes on Migration =&lt;br /&gt;
&lt;br /&gt;
All foreign keys linking teams to users will point through &amp;lt;code&amp;gt;TeamsParticipants&amp;lt;/code&amp;gt;, not &amp;lt;code&amp;gt;TeamsUsers&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Update any related services or background jobs that previously depended on &amp;lt;code&amp;gt;TeamsUser&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Backward compatibility should be evaluated carefully to avoid breaking existing assignments or teams during the migration phase.&lt;br /&gt;
&lt;br /&gt;
= Files Changed =&lt;br /&gt;
&lt;br /&gt;
== TeamsParticipantsController ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Method&lt;br /&gt;
! Change&lt;br /&gt;
! Reason&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
| No Change&lt;br /&gt;
| Determines if the current user has the necessary privileges to perform the requested action.&lt;br /&gt;
|-&lt;br /&gt;
| auto_complete_for_user_name&lt;br /&gt;
| No Change&lt;br /&gt;
| Provides a list of possible team members based on a partial name search for autocomplete functionality.&lt;br /&gt;
|-&lt;br /&gt;
| update_duties&lt;br /&gt;
| No Change&lt;br /&gt;
| Updates the duty assigned to a participant within a team and redirects to the student's team view.&lt;br /&gt;
|-&lt;br /&gt;
| list&lt;br /&gt;
| No Change&lt;br /&gt;
| Displays all participants of a specific team with pagination support.&lt;br /&gt;
|-&lt;br /&gt;
| new&lt;br /&gt;
| No Change&lt;br /&gt;
| Prepares the form for adding a new participant.&lt;br /&gt;
|-&lt;br /&gt;
| create&lt;br /&gt;
| Refactored&lt;br /&gt;
| Validates eligibility before adding a participant; delegates business logic.&lt;br /&gt;
|-&lt;br /&gt;
| delete&lt;br /&gt;
| Refactored&lt;br /&gt;
| Removes participant cleanly with undo option.&lt;br /&gt;
|-&lt;br /&gt;
| delete_selected&lt;br /&gt;
| New&lt;br /&gt;
| Bulk deletes multiple participants from a team.&lt;br /&gt;
|-&lt;br /&gt;
| user_not_found_message (private)&lt;br /&gt;
| New&lt;br /&gt;
| Returns a specific message if a user is not found.&lt;br /&gt;
|-&lt;br /&gt;
| valid_participant? (private)&lt;br /&gt;
| New&lt;br /&gt;
| Checks eligibility of participant for assignment/course.&lt;br /&gt;
|-&lt;br /&gt;
| participant_not_found_message (private)&lt;br /&gt;
| New&lt;br /&gt;
| Provides feedback if participant not linked to assignment/course.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== AssignmentTeam.rb ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Method&lt;br /&gt;
! Change&lt;br /&gt;
! Reason&lt;br /&gt;
|-&lt;br /&gt;
| user_id(current_user = nil)&lt;br /&gt;
| Modified&lt;br /&gt;
| Added optional current_user param for better flexibility.&lt;br /&gt;
|-&lt;br /&gt;
| set_current_user&lt;br /&gt;
| Removed&lt;br /&gt;
| Logic merged into user_id.&lt;br /&gt;
|-&lt;br /&gt;
| includes?(participant)&lt;br /&gt;
| Retained (Minor rewording)&lt;br /&gt;
| Direct comparison with updated participant fetching logic.&lt;br /&gt;
|-&lt;br /&gt;
| parent_model&lt;br /&gt;
| Retained&lt;br /&gt;
| Returns 'Assignment' as parent model.&lt;br /&gt;
|-&lt;br /&gt;
| self.parent_model(id)&lt;br /&gt;
| Removed&lt;br /&gt;
| Responsibility moved elsewhere for separation of concerns.&lt;br /&gt;
|-&lt;br /&gt;
| fullname&lt;br /&gt;
| Removed&lt;br /&gt;
| Deemed unnecessary alias.&lt;br /&gt;
|-&lt;br /&gt;
| review_map_type&lt;br /&gt;
| Removed&lt;br /&gt;
| Hardcoding removed to reduce tight coupling.&lt;br /&gt;
|-&lt;br /&gt;
| prototype&lt;br /&gt;
| Removed&lt;br /&gt;
| Not needed under Rails ActiveRecord conventions.&lt;br /&gt;
|-&lt;br /&gt;
| assign_reviewer&lt;br /&gt;
| Modified&lt;br /&gt;
| Extracted review map creation into create_review_map.&lt;br /&gt;
|-&lt;br /&gt;
| create_review_map&lt;br /&gt;
| New&lt;br /&gt;
| Dedicated method for creating review maps.&lt;br /&gt;
|-&lt;br /&gt;
| get_reviewer&lt;br /&gt;
| Removed&lt;br /&gt;
| Reviewer assignment simplified.&lt;br /&gt;
|-&lt;br /&gt;
| reviewed_by?&lt;br /&gt;
| Modified&lt;br /&gt;
| Now uses ReviewResponseMap.exists? for better DB efficiency.&lt;br /&gt;
|-&lt;br /&gt;
| topic&lt;br /&gt;
| Removed&lt;br /&gt;
| Responsibility split for cleaner structure.&lt;br /&gt;
|-&lt;br /&gt;
| has_submissions?&lt;br /&gt;
| Retained&lt;br /&gt;
| Basic file/submission existence checks.&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| Modified&lt;br /&gt;
| Refactored using TeamsParticipant.team_members(id).&lt;br /&gt;
|-&lt;br /&gt;
| add_participant&lt;br /&gt;
| Modified&lt;br /&gt;
| Creates a TeamsParticipant directly.&lt;br /&gt;
|-&lt;br /&gt;
| delete &amp;amp; destroy&lt;br /&gt;
| Removed&lt;br /&gt;
| Simplified elsewhere.&lt;br /&gt;
|-&lt;br /&gt;
| first_member&lt;br /&gt;
| Removed&lt;br /&gt;
| SRP enforcement.&lt;br /&gt;
|-&lt;br /&gt;
| submitted_files(path)&lt;br /&gt;
| Removed&lt;br /&gt;
| File access logic shifted to service.&lt;br /&gt;
|-&lt;br /&gt;
| import/export methods&lt;br /&gt;
| Removed&lt;br /&gt;
| Responsibility moved to helpers/services.&lt;br /&gt;
|-&lt;br /&gt;
| copy(course_id)&lt;br /&gt;
| Removed&lt;br /&gt;
| Refactored externally.&lt;br /&gt;
|-&lt;br /&gt;
| hyperlinks&lt;br /&gt;
| Removed&lt;br /&gt;
| Delegated to service.&lt;br /&gt;
|-&lt;br /&gt;
| submit_hyperlink(hyperlink)&lt;br /&gt;
| Modified (Delegated)&lt;br /&gt;
| Handled by TeamFileService.&lt;br /&gt;
|-&lt;br /&gt;
| remove_hyperlink(hyperlink)&lt;br /&gt;
| Modified (Delegated)&lt;br /&gt;
| Handled by TeamFileService.&lt;br /&gt;
|-&lt;br /&gt;
| files(directory)&lt;br /&gt;
| Removed&lt;br /&gt;
| File traversal extracted.&lt;br /&gt;
|-&lt;br /&gt;
| team(participant)&lt;br /&gt;
| Removed&lt;br /&gt;
| Moved to higher-level service.&lt;br /&gt;
|-&lt;br /&gt;
| export_fields(options)&lt;br /&gt;
| Removed&lt;br /&gt;
| Offloaded for SRP.&lt;br /&gt;
|-&lt;br /&gt;
| remove_team_by_id(id)&lt;br /&gt;
| Removed&lt;br /&gt;
| Refactored.&lt;br /&gt;
|-&lt;br /&gt;
| path&lt;br /&gt;
| Removed&lt;br /&gt;
| File path responsibility shifted.&lt;br /&gt;
|-&lt;br /&gt;
| set_student_directory_num&lt;br /&gt;
| Removed&lt;br /&gt;
| Directory numbering moved.&lt;br /&gt;
|-&lt;br /&gt;
| received_any_peer_review?&lt;br /&gt;
| Removed&lt;br /&gt;
| Simplified elsewhere.&lt;br /&gt;
|-&lt;br /&gt;
| most_recent_submission&lt;br /&gt;
| Retained (Optimized)&lt;br /&gt;
| Improved query efficiency.&lt;br /&gt;
|-&lt;br /&gt;
| get_logged_in_reviewer_id(current_user_id)&lt;br /&gt;
| Removed&lt;br /&gt;
| Participant-reviewer handling refactored.&lt;br /&gt;
|-&lt;br /&gt;
| current_user_is_reviewer?(current_user_id)&lt;br /&gt;
| Removed&lt;br /&gt;
| Responsibility simplified.&lt;br /&gt;
|-&lt;br /&gt;
| create_new_team(user_id, signuptopic)&lt;br /&gt;
| Modified (Simplified)&lt;br /&gt;
| Refactored for better exception handling.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MentoredTeam.rb ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Method&lt;br /&gt;
! Change&lt;br /&gt;
! Reason&lt;br /&gt;
|-&lt;br /&gt;
| add_member(user, _assignment_id = nil)&lt;br /&gt;
| Refactored&lt;br /&gt;
| Broken into modular private methods for adding users and assigning mentors.&lt;br /&gt;
|-&lt;br /&gt;
| import_team_members(row_hash)&lt;br /&gt;
| Refactored&lt;br /&gt;
| Improved to skip blanks, safe user lookup, and error handling.&lt;br /&gt;
|-&lt;br /&gt;
| can_add_member?(user)&lt;br /&gt;
| New&lt;br /&gt;
| Private method for team capacity and mentor assignment validation.&lt;br /&gt;
|-&lt;br /&gt;
| add_team_user(user)&lt;br /&gt;
| New&lt;br /&gt;
| Cleanly adds a TeamsUser.&lt;br /&gt;
|-&lt;br /&gt;
| add_participant_to_team(user)&lt;br /&gt;
| New&lt;br /&gt;
| Adds participant based on assignment.&lt;br /&gt;
|-&lt;br /&gt;
| assign_mentor_if_needed(_assignment_id)&lt;br /&gt;
| New&lt;br /&gt;
| Ensures no duplicate mentors are assigned.&lt;br /&gt;
|-&lt;br /&gt;
| mentor_assignment_valid?(user)&lt;br /&gt;
| New&lt;br /&gt;
| Validates mentor assignment rules.&lt;br /&gt;
|-&lt;br /&gt;
| user_not_in_team?(user)&lt;br /&gt;
| New&lt;br /&gt;
| Checks if user is already part of the team.&lt;br /&gt;
|-&lt;br /&gt;
| find_or_raise_user(teammate)&lt;br /&gt;
| New&lt;br /&gt;
| Finds user or raises informative ImportError.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== TeamsParticipants Model ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Aspect&lt;br /&gt;
! Change&lt;br /&gt;
! Reason&lt;br /&gt;
|-&lt;br /&gt;
| Association&lt;br /&gt;
| New&lt;br /&gt;
| Establishes direct link between Participant and Team to maintain integrity.&lt;br /&gt;
|-&lt;br /&gt;
| team_members&lt;br /&gt;
| New&lt;br /&gt;
| Retrieves all users associated through participants.&lt;br /&gt;
|-&lt;br /&gt;
| remove_participant_from_team&lt;br /&gt;
| New&lt;br /&gt;
| Safely removes participant from team.&lt;br /&gt;
|-&lt;br /&gt;
| username delegation&lt;br /&gt;
| New&lt;br /&gt;
| Delegates access to participant's username.&lt;br /&gt;
|-&lt;br /&gt;
| Integrity&lt;br /&gt;
| New&lt;br /&gt;
| Ensures only valid assignment participants can join teams.&lt;br /&gt;
|-&lt;br /&gt;
| Maintainability&lt;br /&gt;
| New&lt;br /&gt;
| Designed to align with SOLID principles and Rails best practices.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Testing Plan =&lt;br /&gt;
We plan to cover the reimplementation and refactoring of the following:&lt;br /&gt;
* AssignmentTeam&lt;br /&gt;
* MentoredTeam&lt;br /&gt;
* TeamsParticipantsController&lt;br /&gt;
* TeamsParticipant model&lt;br /&gt;
&lt;br /&gt;
We use RSpec for model, controller, and request specs. API tests are also included where applicable.  &lt;br /&gt;
Both positive and negative test cases are included to ensure robust functionality, along with validation checks and authorization verifications.&lt;br /&gt;
&lt;br /&gt;
== AssignmentTeam Model Tests ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! # !! Method !! Test Description&lt;br /&gt;
|-&lt;br /&gt;
| 1 || user_id || Verify that the correct user ID is returned; prioritize current user if available.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || includes? || Check if a given participant is part of the team.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || parent_model || Ensure the parent model returns &amp;quot;Assignment&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || assign_reviewer || Test reviewer assignment creation and error handling when assignment is not found.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || create_review_map || Confirm a new ReviewResponseMap record is created successfully.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || reviewed_by? || Verify if a reviewer has reviewed the team; test both true and false scenarios.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || participants || Ensure the correct participants are retrieved via TeamsParticipant.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || add_participant || Confirm that a participant is added, and prevent duplicate addition.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || create_new_team || Ensure that a new team-user linkage, sign-up, and nodes are created properly.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || submit_hyperlink || Verify delegation to TeamFileService for hyperlink submission.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || remove_hyperlink || Verify delegation to TeamFileService for hyperlink removal.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || has_submissions? || Check behavior when team has submissions and when it doesn't.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || most_recent_submission || Ensure the most recent submission is retrieved based on updated_at.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MentoredTeam Model Tests ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! # !! Method !! Test Description&lt;br /&gt;
|-&lt;br /&gt;
| 1 || import_team_members || Ensure team members are imported from a list correctly.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || find_or_raise_user || Test for successful user lookup and error raising if user not found.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || user_not_in_team? || Confirm whether a user is already in the team or not.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || mentor_assignment_valid? || Verify that a mentor can be assigned properly and prevent duplicate mentors.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || add_member || Ensure user is added successfully and prevent re-adding existing team members.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || can_add_member? || Verify team capacity check before adding a member.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || add_team_user || Ensure that a TeamsUser is created and linked correctly.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || add_participant_to_team || Confirm that a participant is correctly linked to the team.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || assign_mentor_if_needed || Validate that mentor is assigned only when needed (no double assignment).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== TeamsParticipantsController Tests ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! # !! Method !! Test Description&lt;br /&gt;
|-&lt;br /&gt;
| 1 || valid_participant? || Confirm existence check for a participant; return true/false accordingly.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || update_duties || Test participant duty update flow and ensure a redirect occurs.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || user_not_found_message || Validate that a proper flash message is returned when a user isn't found.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || participant_not_found_message || Validate correct error message if participant isn't linked.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || create || Confirm that creating a TeamsParticipant increases record count.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || list || Test that the participant list view renders correctly.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || action_allowed? || Ensure access control is enforced based on user roles (admin/TA/student).&lt;br /&gt;
|-&lt;br /&gt;
| 8 || delete || Confirm deletion of a TeamsParticipant entry works correctly.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || auto_complete_for_user_name || Verify that JSON autocomplete results are returned based on user input.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || new || Test that the new participant view loads successfully.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || delete_selected || Ensure multiple TeamsParticipant records can be deleted at once.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== TeamsParticipant Model Tests ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! # !! Method !! Test Description&lt;br /&gt;
|-&lt;br /&gt;
| 1 || Associations || Ensure that a TeamsParticipant correctly belongs to a team and participant.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Validations || Confirm presence validations on team and participant relationships.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || team_members || Validate fetching all team members given a team ID.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || participant? || Verify participant existence check for a given user; test positive and negative cases.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== TeamsParticipants API (Request Specs) ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! # !! Endpoint !! Test Description&lt;br /&gt;
|-&lt;br /&gt;
| 1 || POST /teams_participants || Ensure a participant is added via API and redirects successfully.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || DELETE /teams_participants/:id || Ensure a participant is deleted via API and redirects successfully.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Vihar Manojkumar Shah([mailto:vshah23@ncsu.edu vshah23@ncsu.edu])&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Manav Kamdar               ([mailto:mkamdar@ncsu.edu mkamdar@ncsu.edu])&lt;br /&gt;
* Aditya Singh                 ([mailto:asingh78@ncsu.edu asingh78@ncsu.edu])&lt;br /&gt;
* Shivang Patel          ([mailto:spatel74@ncsu.edu spatel74@ncsu.edu])&lt;/div&gt;</summary>
		<author><name>Asingh78</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2516._Reimplement_teams_users_controller.rb&amp;diff=163486</id>
		<title>CSC/ECE 517 Spring 2025 - E2516. Reimplement teams users controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2516._Reimplement_teams_users_controller.rb&amp;diff=163486"/>
		<updated>2025-04-08T00:23:21Z</updated>

		<summary type="html">&lt;p&gt;Asingh78: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2516: Reimplement teams_users_controller.rb==&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
Expertiza is an open-source platform designed to support education by streamlining assignment management. It offers a wide range of features: instructors can create and manage assignments, while students can submit their work in various file formats. One unique aspect is the peer review system, where students can review each other’s submissions. It also supports team-based work, allowing students to collaborate on assignments or projects. Overall, the platform helps both professors and students stay organized and work more efficiently.&lt;br /&gt;
&lt;br /&gt;
===Overview===&lt;br /&gt;
Our goal for this project is to reimplement the TeamUsersController and change it to TeamsParticipantsController thereby strictly following DRY and SOLID principles. Presently, the TeamsUsersController is responsible for managing the interactions between teams and participants. Teams are associated with assignments and courses while participants are associated with these.&lt;br /&gt;
&lt;br /&gt;
As of now, the controller achieves below mentioned functionalities:&lt;br /&gt;
&lt;br /&gt;
1. Listing team members&lt;br /&gt;
2. Adding participants to teams&lt;br /&gt;
3. Removing participants from teams&lt;br /&gt;
4. Updating participants' duties within teams&lt;br /&gt;
5. Providing autocomplete suggestions for participant names when adding new members&lt;br /&gt;
6. Bulk deletion of team members&lt;br /&gt;
&lt;br /&gt;
For the next project deliverable, we plan to achieve below mentioned functionalities:&lt;br /&gt;
&lt;br /&gt;
1. Modifying the TeamsUsersController to TeamsParticipantsController and respectively modifying the associations and related methods and classes&lt;br /&gt;
2. We plan to achieve separation of concerns between models and classes and aim to minimize coupling&lt;br /&gt;
3. More test cases and test suites will be implement to test the robustness and effectiveness of the changes modified&lt;br /&gt;
4. Achieving code readability and maintainability by providing descriptive comments wherever necessary and maintaining consistent naming conventions for variables&lt;br /&gt;
&lt;br /&gt;
===Problem Description===&lt;br /&gt;
Currently our controller presents with below mentioned major issues:&lt;br /&gt;
&lt;br /&gt;
1. Incorrect Association Representation: The TeamsUser model links a User with a Team , not taking into consideration whether the User is assigned with a course or an assignment and generating ambiguity.&lt;br /&gt;
2. Violation of SOLID/DRY Principles: The methods in the controllers are very long and contain unnecessary logic and redundant code&lt;br /&gt;
3. Tight Coupling: Currently, there is a business logic code that resides in the model whereas it should have been placed in the controller. This results in a higher coupling and introduces difficulties in the future while modifying code.&lt;br /&gt;
4. Inconsistent code quality: Many places in the code have inconsistent naming conventions for the variables. &lt;br /&gt;
5. Insufficient Testing: Currently, testing has not been performed to a great extent and so the effectiveness of the existing codebase cannot be determined.&lt;br /&gt;
&lt;br /&gt;
===Scope of Work===&lt;br /&gt;
The current work will involve the below implementation effort:&lt;br /&gt;
&lt;br /&gt;
1. Model Refactoring&lt;br /&gt;
* Replace TeamsUsers controller with TeamsParticipants&lt;br /&gt;
* Update the database association structure to link TeamsParticipant with Partipant and Team&lt;br /&gt;
2. Controller Redesign&lt;br /&gt;
* Reimplementing a new TeamsParticipantsController which handles associations between teams and participants and achieves all functionalities listed in above section&lt;br /&gt;
* Ensure controller actions focus on request/response handling and delegating business logic to models&lt;br /&gt;
3. Create Method Refactor&lt;br /&gt;
* Breaking down create method in the controller into smaller, reusable, testable private methods&lt;br /&gt;
* Eliminate code duplication and unnecessary nesting&lt;br /&gt;
4. Model Enhancements&lt;br /&gt;
* Using the concept of polymorphism to clearly handle team membership and association rules&lt;br /&gt;
* Introducing checks related to whether a user is part of multiple teams and ensuring this is satisfied only in case of a mentor who can be assigned multiple teams&lt;br /&gt;
5. Code Quality Improvements&lt;br /&gt;
* Ensuring consistent naming conventions for variables&lt;br /&gt;
* Descriptive comments to make code more reliable and understandable&lt;br /&gt;
* Applying code best practises throughout codebase to ensure consistency&lt;br /&gt;
6. Testing&lt;br /&gt;
* Including RSpec tests for each controller method (e.g. index, create, delete etc.)&lt;br /&gt;
* Implement tests in models wherever additional business logic has been added&lt;br /&gt;
* Perform manual testing to ensure feature completeness and correctness&lt;br /&gt;
7. Documentation&lt;br /&gt;
* A detailed documentation providing the behavior of the controller and what it tries to achieve &lt;br /&gt;
* It should also include the associations between different entities and model and controller interactions&lt;br /&gt;
===Changes Proposed===&lt;br /&gt;
= Summary of Refactor =&lt;br /&gt;
&lt;br /&gt;
'''Replaced''' all references to &amp;lt;code&amp;gt;TeamsUser&amp;lt;/code&amp;gt; with &amp;lt;code&amp;gt;TeamsParticipant&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Refactored''' long methods (especially &amp;lt;code&amp;gt;create&amp;lt;/code&amp;gt;) into smaller private methods.&lt;br /&gt;
&lt;br /&gt;
'''Moved''' business logic to &amp;lt;code&amp;gt;AssignmentTeam&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;MentoredTeam&amp;lt;/code&amp;gt; where appropriate (e.g., mentor-specific rules).&lt;br /&gt;
&lt;br /&gt;
'''Removed''' unnecessary nesting in methods like &amp;lt;code&amp;gt;create&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Improved''' naming conventions for all variables.&lt;br /&gt;
&lt;br /&gt;
'''Enhanced''' comments to explain functionality clearly.&lt;br /&gt;
&lt;br /&gt;
'''Ensured''' SOLID Principles are followed across all code.&lt;br /&gt;
&lt;br /&gt;
'''Wrote''' new unit and integration tests for controller methods.&lt;br /&gt;
&lt;br /&gt;
= Proposed Flow for Major Methods =&lt;br /&gt;
&lt;br /&gt;
== index ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' &amp;lt;code&amp;gt;team_id&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Action:'''&lt;br /&gt;
Find team → Retrieve associated participants → Render list (JSON or HTML view).&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
Simplicity focus: Only data retrieval, no complex logic.&lt;br /&gt;
&lt;br /&gt;
== create ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' Participant information, &amp;lt;code&amp;gt;team_id&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Steps:'''&lt;br /&gt;
&lt;br /&gt;
Validate participant (exists, belongs to assignment/course).&lt;br /&gt;
Check team eligibility:&lt;br /&gt;
If participant is already on another team → Validate mentor exception rules (handled in model).&lt;br /&gt;
Create &amp;lt;code&amp;gt;TeamsParticipant&amp;lt;/code&amp;gt; record linking the participant and team.&lt;br /&gt;
Handle success/failure gracefully with appropriate responses.&lt;br /&gt;
'''Important:''' Keep business rules outside the controller wherever possible (delegate to model methods).&lt;br /&gt;
&lt;br /&gt;
== destroy ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' &amp;lt;code&amp;gt;teams_participant_id&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Action:'''&lt;br /&gt;
Remove participant from the team cleanly, handling foreign key constraints.&lt;br /&gt;
&lt;br /&gt;
== autocomplete_participants ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' &amp;lt;code&amp;gt;assignment_id&amp;lt;/code&amp;gt;, search string&lt;br /&gt;
&lt;br /&gt;
'''Action:'''&lt;br /&gt;
Return a list of matching participants for the given assignment.&lt;br /&gt;
&lt;br /&gt;
== bulk_delete ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' List of participant IDs&lt;br /&gt;
&lt;br /&gt;
'''Action:'''&lt;br /&gt;
Mass remove participants from their teams, validate permissions.&lt;br /&gt;
&lt;br /&gt;
= Helper Methods (Private) =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;find_team&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;find_participant&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;validate_participant_eligibility&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add_participant_to_team&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;remove_participant_from_team&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mentor_eligibility_check&amp;lt;/code&amp;gt; (Delegated to &amp;lt;code&amp;gt;AssignmentTeam&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;MentoredTeam&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Each method will have a clear single responsibility and promote reuse across the controller.&lt;br /&gt;
&lt;br /&gt;
= Notes on Migration =&lt;br /&gt;
&lt;br /&gt;
All foreign keys linking teams to users will point through &amp;lt;code&amp;gt;TeamsParticipants&amp;lt;/code&amp;gt;, not &amp;lt;code&amp;gt;TeamsUsers&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Update any related services or background jobs that previously depended on &amp;lt;code&amp;gt;TeamsUser&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Backward compatibility should be evaluated carefully to avoid breaking existing assignments or teams during the migration phase.&lt;br /&gt;
&lt;br /&gt;
= Files Changed =&lt;br /&gt;
&lt;br /&gt;
== TeamsParticipantsController ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Method&lt;br /&gt;
! Change&lt;br /&gt;
! Reason&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
| No Change&lt;br /&gt;
| Determines if the current user has the necessary privileges to perform the requested action.&lt;br /&gt;
|-&lt;br /&gt;
| auto_complete_for_user_name&lt;br /&gt;
| No Change&lt;br /&gt;
| Provides a list of possible team members based on a partial name search for autocomplete functionality.&lt;br /&gt;
|-&lt;br /&gt;
| update_duties&lt;br /&gt;
| No Change&lt;br /&gt;
| Updates the duty assigned to a participant within a team and redirects to the student's team view.&lt;br /&gt;
|-&lt;br /&gt;
| list&lt;br /&gt;
| No Change&lt;br /&gt;
| Displays all participants of a specific team with pagination support.&lt;br /&gt;
|-&lt;br /&gt;
| new&lt;br /&gt;
| No Change&lt;br /&gt;
| Prepares the form for adding a new participant.&lt;br /&gt;
|-&lt;br /&gt;
| create&lt;br /&gt;
| Refactored&lt;br /&gt;
| Validates eligibility before adding a participant; delegates business logic.&lt;br /&gt;
|-&lt;br /&gt;
| delete&lt;br /&gt;
| Refactored&lt;br /&gt;
| Removes participant cleanly with undo option.&lt;br /&gt;
|-&lt;br /&gt;
| delete_selected&lt;br /&gt;
| New&lt;br /&gt;
| Bulk deletes multiple participants from a team.&lt;br /&gt;
|-&lt;br /&gt;
| user_not_found_message (private)&lt;br /&gt;
| New&lt;br /&gt;
| Returns a specific message if a user is not found.&lt;br /&gt;
|-&lt;br /&gt;
| valid_participant? (private)&lt;br /&gt;
| New&lt;br /&gt;
| Checks eligibility of participant for assignment/course.&lt;br /&gt;
|-&lt;br /&gt;
| participant_not_found_message (private)&lt;br /&gt;
| New&lt;br /&gt;
| Provides feedback if participant not linked to assignment/course.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== AssignmentTeam.rb ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Method&lt;br /&gt;
! Change&lt;br /&gt;
! Reason&lt;br /&gt;
|-&lt;br /&gt;
| user_id(current_user = nil)&lt;br /&gt;
| Modified&lt;br /&gt;
| Added optional current_user param for better flexibility.&lt;br /&gt;
|-&lt;br /&gt;
| set_current_user&lt;br /&gt;
| Removed&lt;br /&gt;
| Logic merged into user_id.&lt;br /&gt;
|-&lt;br /&gt;
| includes?(participant)&lt;br /&gt;
| Retained (Minor rewording)&lt;br /&gt;
| Direct comparison with updated participant fetching logic.&lt;br /&gt;
|-&lt;br /&gt;
| parent_model&lt;br /&gt;
| Retained&lt;br /&gt;
| Returns 'Assignment' as parent model.&lt;br /&gt;
|-&lt;br /&gt;
| self.parent_model(id)&lt;br /&gt;
| Removed&lt;br /&gt;
| Responsibility moved elsewhere for separation of concerns.&lt;br /&gt;
|-&lt;br /&gt;
| fullname&lt;br /&gt;
| Removed&lt;br /&gt;
| Deemed unnecessary alias.&lt;br /&gt;
|-&lt;br /&gt;
| review_map_type&lt;br /&gt;
| Removed&lt;br /&gt;
| Hardcoding removed to reduce tight coupling.&lt;br /&gt;
|-&lt;br /&gt;
| prototype&lt;br /&gt;
| Removed&lt;br /&gt;
| Not needed under Rails ActiveRecord conventions.&lt;br /&gt;
|-&lt;br /&gt;
| assign_reviewer&lt;br /&gt;
| Modified&lt;br /&gt;
| Extracted review map creation into create_review_map.&lt;br /&gt;
|-&lt;br /&gt;
| create_review_map&lt;br /&gt;
| New&lt;br /&gt;
| Dedicated method for creating review maps.&lt;br /&gt;
|-&lt;br /&gt;
| get_reviewer&lt;br /&gt;
| Removed&lt;br /&gt;
| Reviewer assignment simplified.&lt;br /&gt;
|-&lt;br /&gt;
| reviewed_by?&lt;br /&gt;
| Modified&lt;br /&gt;
| Now uses ReviewResponseMap.exists? for better DB efficiency.&lt;br /&gt;
|-&lt;br /&gt;
| topic&lt;br /&gt;
| Removed&lt;br /&gt;
| Responsibility split for cleaner structure.&lt;br /&gt;
|-&lt;br /&gt;
| has_submissions?&lt;br /&gt;
| Retained&lt;br /&gt;
| Basic file/submission existence checks.&lt;br /&gt;
|-&lt;br /&gt;
| participants&lt;br /&gt;
| Modified&lt;br /&gt;
| Refactored using TeamsParticipant.team_members(id).&lt;br /&gt;
|-&lt;br /&gt;
| add_participant&lt;br /&gt;
| Modified&lt;br /&gt;
| Creates a TeamsParticipant directly.&lt;br /&gt;
|-&lt;br /&gt;
| delete &amp;amp; destroy&lt;br /&gt;
| Removed&lt;br /&gt;
| Simplified elsewhere.&lt;br /&gt;
|-&lt;br /&gt;
| first_member&lt;br /&gt;
| Removed&lt;br /&gt;
| SRP enforcement.&lt;br /&gt;
|-&lt;br /&gt;
| submitted_files(path)&lt;br /&gt;
| Removed&lt;br /&gt;
| File access logic shifted to service.&lt;br /&gt;
|-&lt;br /&gt;
| import/export methods&lt;br /&gt;
| Removed&lt;br /&gt;
| Responsibility moved to helpers/services.&lt;br /&gt;
|-&lt;br /&gt;
| copy(course_id)&lt;br /&gt;
| Removed&lt;br /&gt;
| Refactored externally.&lt;br /&gt;
|-&lt;br /&gt;
| hyperlinks&lt;br /&gt;
| Removed&lt;br /&gt;
| Delegated to service.&lt;br /&gt;
|-&lt;br /&gt;
| submit_hyperlink(hyperlink)&lt;br /&gt;
| Modified (Delegated)&lt;br /&gt;
| Handled by TeamFileService.&lt;br /&gt;
|-&lt;br /&gt;
| remove_hyperlink(hyperlink)&lt;br /&gt;
| Modified (Delegated)&lt;br /&gt;
| Handled by TeamFileService.&lt;br /&gt;
|-&lt;br /&gt;
| files(directory)&lt;br /&gt;
| Removed&lt;br /&gt;
| File traversal extracted.&lt;br /&gt;
|-&lt;br /&gt;
| team(participant)&lt;br /&gt;
| Removed&lt;br /&gt;
| Moved to higher-level service.&lt;br /&gt;
|-&lt;br /&gt;
| export_fields(options)&lt;br /&gt;
| Removed&lt;br /&gt;
| Offloaded for SRP.&lt;br /&gt;
|-&lt;br /&gt;
| remove_team_by_id(id)&lt;br /&gt;
| Removed&lt;br /&gt;
| Refactored.&lt;br /&gt;
|-&lt;br /&gt;
| path&lt;br /&gt;
| Removed&lt;br /&gt;
| File path responsibility shifted.&lt;br /&gt;
|-&lt;br /&gt;
| set_student_directory_num&lt;br /&gt;
| Removed&lt;br /&gt;
| Directory numbering moved.&lt;br /&gt;
|-&lt;br /&gt;
| received_any_peer_review?&lt;br /&gt;
| Removed&lt;br /&gt;
| Simplified elsewhere.&lt;br /&gt;
|-&lt;br /&gt;
| most_recent_submission&lt;br /&gt;
| Retained (Optimized)&lt;br /&gt;
| Improved query efficiency.&lt;br /&gt;
|-&lt;br /&gt;
| get_logged_in_reviewer_id(current_user_id)&lt;br /&gt;
| Removed&lt;br /&gt;
| Participant-reviewer handling refactored.&lt;br /&gt;
|-&lt;br /&gt;
| current_user_is_reviewer?(current_user_id)&lt;br /&gt;
| Removed&lt;br /&gt;
| Responsibility simplified.&lt;br /&gt;
|-&lt;br /&gt;
| create_new_team(user_id, signuptopic)&lt;br /&gt;
| Modified (Simplified)&lt;br /&gt;
| Refactored for better exception handling.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MentoredTeam.rb ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Method&lt;br /&gt;
! Change&lt;br /&gt;
! Reason&lt;br /&gt;
|-&lt;br /&gt;
| add_member(user, _assignment_id = nil)&lt;br /&gt;
| Refactored&lt;br /&gt;
| Broken into modular private methods for adding users and assigning mentors.&lt;br /&gt;
|-&lt;br /&gt;
| import_team_members(row_hash)&lt;br /&gt;
| Refactored&lt;br /&gt;
| Improved to skip blanks, safe user lookup, and error handling.&lt;br /&gt;
|-&lt;br /&gt;
| can_add_member?(user)&lt;br /&gt;
| New&lt;br /&gt;
| Private method for team capacity and mentor assignment validation.&lt;br /&gt;
|-&lt;br /&gt;
| add_team_user(user)&lt;br /&gt;
| New&lt;br /&gt;
| Cleanly adds a TeamsUser.&lt;br /&gt;
|-&lt;br /&gt;
| add_participant_to_team(user)&lt;br /&gt;
| New&lt;br /&gt;
| Adds participant based on assignment.&lt;br /&gt;
|-&lt;br /&gt;
| assign_mentor_if_needed(_assignment_id)&lt;br /&gt;
| New&lt;br /&gt;
| Ensures no duplicate mentors are assigned.&lt;br /&gt;
|-&lt;br /&gt;
| mentor_assignment_valid?(user)&lt;br /&gt;
| New&lt;br /&gt;
| Validates mentor assignment rules.&lt;br /&gt;
|-&lt;br /&gt;
| user_not_in_team?(user)&lt;br /&gt;
| New&lt;br /&gt;
| Checks if user is already part of the team.&lt;br /&gt;
|-&lt;br /&gt;
| find_or_raise_user(teammate)&lt;br /&gt;
| New&lt;br /&gt;
| Finds user or raises informative ImportError.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== TeamsParticipants Model ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Aspect&lt;br /&gt;
! Change&lt;br /&gt;
! Reason&lt;br /&gt;
|-&lt;br /&gt;
| Association&lt;br /&gt;
| New&lt;br /&gt;
| Establishes direct link between Participant and Team to maintain integrity.&lt;br /&gt;
|-&lt;br /&gt;
| team_members&lt;br /&gt;
| New&lt;br /&gt;
| Retrieves all users associated through participants.&lt;br /&gt;
|-&lt;br /&gt;
| remove_participant_from_team&lt;br /&gt;
| New&lt;br /&gt;
| Safely removes participant from team.&lt;br /&gt;
|-&lt;br /&gt;
| username delegation&lt;br /&gt;
| New&lt;br /&gt;
| Delegates access to participant's username.&lt;br /&gt;
|-&lt;br /&gt;
| Integrity&lt;br /&gt;
| New&lt;br /&gt;
| Ensures only valid assignment participants can join teams.&lt;br /&gt;
|-&lt;br /&gt;
| Maintainability&lt;br /&gt;
| New&lt;br /&gt;
| Designed to align with SOLID principles and Rails best practices.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Testing Plan =&lt;br /&gt;
We plan to cover the reimplementation and refactoring of the following:&lt;br /&gt;
* AssignmentTeam&lt;br /&gt;
* MentoredTeam&lt;br /&gt;
* TeamsParticipantsController&lt;br /&gt;
* TeamsParticipant model&lt;br /&gt;
&lt;br /&gt;
We use RSpec for model, controller, and request specs. API tests are also included where applicable.  &lt;br /&gt;
Both positive and negative test cases are included to ensure robust functionality, along with validation checks and authorization verifications.&lt;br /&gt;
&lt;br /&gt;
== AssignmentTeam Model Tests ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! # !! Method !! Test Description&lt;br /&gt;
|-&lt;br /&gt;
| 1 || user_id || Verify that the correct user ID is returned; prioritize current user if available.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || includes? || Check if a given participant is part of the team.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || parent_model || Ensure the parent model returns &amp;quot;Assignment&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || assign_reviewer || Test reviewer assignment creation and error handling when assignment is not found.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || create_review_map || Confirm a new ReviewResponseMap record is created successfully.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || reviewed_by? || Verify if a reviewer has reviewed the team; test both true and false scenarios.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || participants || Ensure the correct participants are retrieved via TeamsParticipant.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || add_participant || Confirm that a participant is added, and prevent duplicate addition.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || create_new_team || Ensure that a new team-user linkage, sign-up, and nodes are created properly.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || submit_hyperlink || Verify delegation to TeamFileService for hyperlink submission.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || remove_hyperlink || Verify delegation to TeamFileService for hyperlink removal.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || has_submissions? || Check behavior when team has submissions and when it doesn't.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || most_recent_submission || Ensure the most recent submission is retrieved based on updated_at.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MentoredTeam Model Tests ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! # !! Method !! Test Description&lt;br /&gt;
|-&lt;br /&gt;
| 1 || import_team_members || Ensure team members are imported from a list correctly.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || find_or_raise_user || Test for successful user lookup and error raising if user not found.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || user_not_in_team? || Confirm whether a user is already in the team or not.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || mentor_assignment_valid? || Verify that a mentor can be assigned properly and prevent duplicate mentors.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || add_member || Ensure user is added successfully and prevent re-adding existing team members.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || can_add_member? || Verify team capacity check before adding a member.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || add_team_user || Ensure that a TeamsUser is created and linked correctly.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || add_participant_to_team || Confirm that a participant is correctly linked to the team.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || assign_mentor_if_needed || Validate that mentor is assigned only when needed (no double assignment).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== TeamsParticipantsController Tests ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! # !! Method !! Test Description&lt;br /&gt;
|-&lt;br /&gt;
| 1 || valid_participant? || Confirm existence check for a participant; return true/false accordingly.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || update_duties || Test participant duty update flow and ensure a redirect occurs.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || user_not_found_message || Validate that a proper flash message is returned when a user isn't found.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || participant_not_found_message || Validate correct error message if participant isn't linked.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || create || Confirm that creating a TeamsParticipant increases record count.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || list || Test that the participant list view renders correctly.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || action_allowed? || Ensure access control is enforced based on user roles (admin/TA/student).&lt;br /&gt;
|-&lt;br /&gt;
| 8 || delete || Confirm deletion of a TeamsParticipant entry works correctly.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || auto_complete_for_user_name || Verify that JSON autocomplete results are returned based on user input.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || new || Test that the new participant view loads successfully.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || delete_selected || Ensure multiple TeamsParticipant records can be deleted at once.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== TeamsParticipant Model Tests ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! # !! Method !! Test Description&lt;br /&gt;
|-&lt;br /&gt;
| 1 || Associations || Ensure that a TeamsParticipant correctly belongs to a team and participant.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Validations || Confirm presence validations on team and participant relationships.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || team_members || Validate fetching all team members given a team ID.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || participant? || Verify participant existence check for a given user; test positive and negative cases.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== TeamsParticipants API (Request Specs) ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! # !! Endpoint !! Test Description&lt;br /&gt;
|-&lt;br /&gt;
| 1 || POST /teams_participants || Ensure a participant is added via API and redirects successfully.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || DELETE /teams_participants/:id || Ensure a participant is deleted via API and redirects successfully.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Vihar Manojkumar Shah([mailto:vshah23@ncsu.edu vshah23@ncsu.edu])&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Manav Kamdar               ([mailto:mkamdar@ncsu.edu mkamdar@ncsu.edu])&lt;br /&gt;
* Aditya Singh                 ([mailto:asingh78@ncsu.edu asingh78@ncsu.edu])&lt;br /&gt;
* Shivang Patel          ([mailto:spatel74@ncsu.edu spatel74@ncsu.edu])&lt;/div&gt;</summary>
		<author><name>Asingh78</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025&amp;diff=163451</id>
		<title>CSC/ECE 517 Spring 2025</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025&amp;diff=163451"/>
		<updated>2025-04-07T22:14:45Z</updated>

		<summary type="html">&lt;p&gt;Asingh78: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[CSC/ECE 517 Spring 2025 - E2503. Refactor the Team hierarchy]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2504. Mentor-meeting management]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2505. Testing Answer Tagging]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2508. Reimplement bidding-algorithm web service]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2509. Reimplement feedback_response_map.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2519. Implement view for results of bidding]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2522. Enhancing UI Consistency in Expertiza 1]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2520. Reimplement heatgrid UI for reviews]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2517. Reimplement internationalization (frontend + backend)]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2523: Enhancing UI Consistency in Expertiza 2]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2515:  Reimplement student_teams_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2501:  Refactor review_mapping_helper.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2502:  Refactor review_mapping_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2512. Reimplement responses controller]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2510. Reimplement grades_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2507. Reimplement back end for submission records]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2514. Reimplement student_quizzes_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2518. Reimplement password resets (frontend + backend)]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2516. Reimplement teams_users_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2511. Reimplement participants_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2521. UI for View submissions/assign grades (except heatgrid)]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2513. Reimplement sign_up_topic.rb as project_topic.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2506. Implement testing for new Bookmarks Controller]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2527. Mentor-meeting management: assignments with topics]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Final Projects ==&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2509 Refactoring and Enhancing the Feedback Response Map Controller]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2539 Reimplement Student Task View (Frontend + Backend)]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2521 UI for View submissions/assign grades (except heatgrid)]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2524 Reimplement student review controller]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2525 Reimplement review_mapping_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2526 Reimplement Teams and Participant hierarchies]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2530 Reimplement Grades Controller (Frontend + Backend)]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2538 Reimplementing Questionnaire Page in Expertiza]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2534 UI for Assign Reviewers]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2540 Integration of Assignment participant Frontend with participant controller Backend]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2532. Reimplement Missing ResponseMap Subclasses]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2542. Refactor review_bids_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2533. ​​Reimplement the Team hierarchy]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2531 Refactor participants_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2528 Testing for Survey Deployment]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2514. Reimplement student_quizzes_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2516. Reimplement teams_users_controller.rb]]&lt;/div&gt;</summary>
		<author><name>Asingh78</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025&amp;diff=162763</id>
		<title>CSC/ECE 517 Spring 2025</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025&amp;diff=162763"/>
		<updated>2025-03-25T03:27:35Z</updated>

		<summary type="html">&lt;p&gt;Asingh78: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[CSC/ECE 517 Spring 2025 - E2504. Mentor-meeting management]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2505. Testing Answer Tagging]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2508. Reimplement bidding-algorithm web service]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2509. Reimplement feedback_response_map.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2519. Implement view for results of bidding]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2522. Enhancing UI Consistency in Expertiza 1]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2520. Reimplement heatgrid UI for reviews]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2517. Reimplement internationalization (frontend + backend)]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2523: Enhancing UI Consistency in Expertiza 2]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2515:  Reimplement student_teams_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2501:  Refactor review_mapping_helper.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2502:  Refactor review_mapping_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2512. Reimplement responses controller]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2510. Reimplement grades_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2507. Reimplement back end for submission records]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2514. Reimplement student_quizzes_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2518. Reimplement password resets (frontend + backend)]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2516. Reimplement teams_users_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2511. Reimplement participants_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2521. UI for View submissions/assign grades (except heatgrid)]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2513. Reimplement sign_up_topic.rb as project_topic.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Spring 2025 - E2506. Implement testing for new Bookmarks Controller]]&lt;/div&gt;</summary>
		<author><name>Asingh78</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2516._Reimplement_teams_users_controller.rb&amp;diff=162538</id>
		<title>CSC/ECE 517 Spring 2025 - E2516. Reimplement teams users controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2516._Reimplement_teams_users_controller.rb&amp;diff=162538"/>
		<updated>2025-03-25T00:48:48Z</updated>

		<summary type="html">&lt;p&gt;Asingh78: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2516: Reimplement teams_users_controller.rb==&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
Expertiza is an open-source project implementation for an educational platform. It hosts a lot of functionalities: the professor can create assignments for the students; the students can submit their assignments supported across multiple file formats and also review assignments uploaded by other students; the students can form team and work together for an assignment or a project. This platform provides synchronicity to the professor as well as students to effectively manage their work. &lt;br /&gt;
&lt;br /&gt;
===Project Overview===&lt;br /&gt;
Through this project, we have reimplement a controller component, namely, teams_users_controller. The entire component is shifted to another controller, namely teams_participants_controller. It now achieves below mentioned functionalities:&lt;br /&gt;
&lt;br /&gt;
* The code change now follows the SOLID and DRY principles&lt;br /&gt;
* All associations and references between participants and assignments and courses have been modified&lt;br /&gt;
* Clear distinction between &amp;quot;general user&amp;quot; and &amp;quot;assignment participant&amp;quot;&lt;br /&gt;
* Improved code readability by integrating helper methods&lt;br /&gt;
&lt;br /&gt;
===Files Modified===&lt;br /&gt;
The following files have been modified to achieve the mentioned functionalities:&lt;br /&gt;
* TeamsParticipantsController&lt;br /&gt;
* AssignmentTeam&lt;br /&gt;
* MentoredTeam&lt;br /&gt;
* TeamsParticipant&lt;br /&gt;
&lt;br /&gt;
===TeamsParticipantsController===&lt;br /&gt;
The changes made in this controller included refactoring the TeamsUsersController to TeamsParticipantsController. This name change reflects a very important feature that needs to be implemented:&lt;br /&gt;
A participant is compulsorily to be assigned a course or an assignment whereas a user is general purpose member who uses the expertiza platform. Helper methods and various other methods have been modified in this controller file. One other association that is also implemented simultaneously is that a participant is to be assigned only and only one team unless the participant is a mentor.&lt;br /&gt;
&lt;br /&gt;
  def valid_participant?(user, assignment_or_course)&lt;br /&gt;
    if assignment_or_course.user_on_team?(user)&lt;br /&gt;
      flash[:error] = &amp;quot;This user is already assigned to a team for this #{assignment_or_course.class.name.downcase}.&amp;quot;&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    participant = assignment_or_course.participants.find_by(user_id: user.id)&lt;br /&gt;
    unless participant&lt;br /&gt;
      flash[:error] = participant_not_found_message(user.name, assignment_or_course)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    true&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Above method in the controller file implements this functionality where it checks whether a participant is assigned a team or not. If the participant is already assigned a team, it throws an error that the participant is already assigned a team. If not, it finds the participant id and accordingly assigns a team.&lt;br /&gt;
&lt;br /&gt;
===AssignmentTeam===&lt;br /&gt;
The AssignmentTeam class is inherited from the Team class to include all functionalities present in the Team class. The primary purpose of this model is to depict the team members present for a given assignment or course. A lot of things could be achieved by having such a model and necessary methods have been devised to achieve them. Firstly, association rules have been established where each team can be assigned to multiple reviewers and can have multiple review responses. It defines rules for returning participants of a team, whether a participant is part of a team, assigning a reviewer to a team, drafting the review map when a reviewer reviews the work of the team, detailing participants of a team and if necessary, adding participants to a team, creating a new team and assigning a topic to the team, and lastly adding or modifying or deleting a hyperlink which represents the link to the work done by a particular team.&lt;br /&gt;
&lt;br /&gt;
  belongs_to :assignment, class_name: 'Assignment', foreign_key: 'parent_id'&lt;br /&gt;
  has_many :review_mappings, class_name: 'ReviewResponseMap', foreign_key: 'reviewee_id'&lt;br /&gt;
  has_many :review_response_maps, foreign_key: 'reviewee_id'&lt;br /&gt;
  has_many :responses, through: :review_response_maps, foreign_key: 'map_id'&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===MentoredTeam===&lt;br /&gt;
The MentoredTeam class is inherited from the AssignmentTeam class. The purpose of this class is to validating a team in regards to participants already present and adding a mentor to the team compulsorily and that too only once. One other feature achieved through this model is to automate the task of creating teams by importing the team member data from a csv file and validating at the same time whether a user can be added to the team based on the capacity of the team and whether the user exists or not. One other feature achieved through this is that of logging every action performed from above description.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===TeamsParticipant===&lt;br /&gt;
The TeamsParticipant class is inherited from the ApplicationRecord class meaning that it is an active record model. This model manages the association between the participant and the teams including adding, removing and fetching participants from the team. It establishes relationships which state that each team can have many participants and one participant can have only one team.&lt;br /&gt;
&lt;br /&gt;
===Test Cases for AssignmentTeam===&lt;br /&gt;
Below are the test cases implemented for the `AssignmentTeam` model:&lt;br /&gt;
&lt;br /&gt;
  require 'rails_helper'&lt;br /&gt;
  RSpec.describe AssignmentTeam, type: :model do&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:user) { create(:user) }&lt;br /&gt;
    let(:participant) { create(:participant, user: user, assignment: assignment) }&lt;br /&gt;
    let(:reviewer) { create(:participant, assignment: assignment) }&lt;br /&gt;
    let(:review_response_map) { create(:review_response_map, reviewee: team, reviewer: reviewer) }&lt;br /&gt;
    describe '#user_id' do&lt;br /&gt;
      it 'returns the user_id of the first team member' do&lt;br /&gt;
        team.users &amp;lt;&amp;lt; user&lt;br /&gt;
        expect(team.user_id).to eq(user.id)&lt;br /&gt;
      end&lt;br /&gt;
      it 'returns current_user.id if they are in the team' do&lt;br /&gt;
        team.users &amp;lt;&amp;lt; user&lt;br /&gt;
        expect(team.user_id(user)).to eq(user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#includes?' do&lt;br /&gt;
      it 'returns true if a participant is in the team' do&lt;br /&gt;
        allow(team).to receive(:participants).and_return([participant])&lt;br /&gt;
        expect(team.includes?(participant)).to be true&lt;br /&gt;
      end&lt;br /&gt;
      it 'returns false if a participant is not in the team' do&lt;br /&gt;
        allow(team).to receive(:participants).and_return([])&lt;br /&gt;
        expect(team.includes?(participant)).to be false&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#parent_model' do&lt;br /&gt;
      it 'returns &amp;quot;Assignment&amp;quot;' do&lt;br /&gt;
        expect(team.parent_model).to eq('Assignment')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#assign_reviewer' do&lt;br /&gt;
      it 'raises an error if the assignment is not found' do&lt;br /&gt;
        allow(Assignment).to receive(:find_by).and_return(nil)&lt;br /&gt;
        expect { team.assign_reviewer(reviewer) }.to raise_error('The assignment cannot be found.')&lt;br /&gt;
      end&lt;br /&gt;
      it 'creates a review map for the reviewer' do&lt;br /&gt;
        expect { team.assign_reviewer(reviewer) }.to change { ReviewResponseMap.count }.by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#create_review_map' do&lt;br /&gt;
      it 'creates a new ReviewResponseMap' do&lt;br /&gt;
        expect {&lt;br /&gt;
          team.create_review_map(reviewer, assignment)&lt;br /&gt;
        }.to change { ReviewResponseMap.count }.by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#reviewed_by?' do&lt;br /&gt;
      it 'returns true if the team has been reviewed by the given reviewer' do&lt;br /&gt;
        review_response_map&lt;br /&gt;
        expect(team.reviewed_by?(reviewer)).to be true&lt;br /&gt;
      end&lt;br /&gt;
      it 'returns false if the team has not been reviewed by the given reviewer' do&lt;br /&gt;
        expect(team.reviewed_by?(reviewer)).to be false&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#participants' do&lt;br /&gt;
      it 'returns the participants of the team' do&lt;br /&gt;
        allow(TeamsParticipant).to receive(:team_members).with(team.id).and_return([participant])&lt;br /&gt;
        expect(team.participants).to include(participant)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#add_participant' do&lt;br /&gt;
      it 'adds a participant to the team' do&lt;br /&gt;
        expect {&lt;br /&gt;
          team.add_participant(assignment.id, user)&lt;br /&gt;
        }.to change { TeamsParticipant.count }.by(1)&lt;br /&gt;
      end&lt;br /&gt;
      it 'does not add a participant if they are already in the team' do&lt;br /&gt;
        team.add_participant(assignment.id, user)&lt;br /&gt;
        expect {&lt;br /&gt;
          team.add_participant(assignment.id, user)&lt;br /&gt;
        }.not_to change { TeamsParticipant.count }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#create_new_team' do&lt;br /&gt;
      let(:signuptopic) { create(:sign_up_topic, assignment: assignment) }&lt;br /&gt;
      it 'creates a new team user and associates topic' do&lt;br /&gt;
        expect {&lt;br /&gt;
          team.create_new_team(user.id, signuptopic)&lt;br /&gt;
        }.to change { TeamsUser.count }.by(1)&lt;br /&gt;
          .and change { SignedUpTeam.count }.by(1)&lt;br /&gt;
          .and change { TeamNode.count }.by(1)&lt;br /&gt;
          .and change { TeamUserNode.count }.by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#submit_hyperlink' do&lt;br /&gt;
      it 'calls TeamFileService.submit_hyperlink' do&lt;br /&gt;
        expect(TeamFileService).to receive(:submit_hyperlink).with(team, 'http://example.com')&lt;br /&gt;
        team.submit_hyperlink('http://example.com')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#remove_hyperlink' do&lt;br /&gt;
      it 'calls TeamFileService.remove_hyperlink' do&lt;br /&gt;
        expect(TeamFileService).to receive(:remove_hyperlink).with(team, 'http://example.com')&lt;br /&gt;
        team.remove_hyperlink('http://example.com')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#has_submissions?' do&lt;br /&gt;
      it 'returns true if the team has submissions' do&lt;br /&gt;
        allow(team).to receive(:submitted_files).and_return(['file1'])&lt;br /&gt;
        allow(team).to receive(:submitted_hyperlinks).and_return(nil)&lt;br /&gt;
        expect(team.has_submissions?).to be true&lt;br /&gt;
      end&lt;br /&gt;
      it 'returns false if the team has no submissions' do&lt;br /&gt;
        allow(team).to receive(:submitted_files).and_return([])&lt;br /&gt;
        allow(team).to receive(:submitted_hyperlinks).and_return(nil)&lt;br /&gt;
        expect(team.has_submissions?).to be false&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#most_recent_submission' do&lt;br /&gt;
      it 'returns the latest submission' do&lt;br /&gt;
        submission1 = create(:submission_record, team: team, assignment: assignment, updated_at: 1.day.ago)&lt;br /&gt;
        submission2 = create(:submission_record, team: team, assignment: assignment, updated_at: Time.current)&lt;br /&gt;
        expect(team.most_recent_submission).to eq(submission2)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Test Cases for MentoredTeam===&lt;br /&gt;
Below are the test cases implemented for the `MentoredTeam` model:&lt;br /&gt;
&lt;br /&gt;
  require 'rails_helper'&lt;br /&gt;
  RSpec.describe MentoredTeam, type: :model do&lt;br /&gt;
    let(:team) { create(:mentored_team) }&lt;br /&gt;
    let(:user) { create(:user) }&lt;br /&gt;
    let(:mentor) { create(:user, role: :mentor) }&lt;br /&gt;
    describe '#import_team_members' do&lt;br /&gt;
      it 'imports members successfully from a given list' do&lt;br /&gt;
        members = [create(:user), create(:user)]&lt;br /&gt;
        expect { team.import_team_members(members) }.to change { team.users.count }.by(2)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#find_or_raise_user' do&lt;br /&gt;
      it 'returns the user if found' do&lt;br /&gt;
        expect(team.find_or_raise_user(user.id)).to eq(user)&lt;br /&gt;
      end&lt;br /&gt;
      it 'raises an error if the user is not found' do&lt;br /&gt;
        expect { team.find_or_raise_user(999) }.to raise_error(ActiveRecord::RecordNotFound)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#user_not_in_team?' do&lt;br /&gt;
      it 'returns true if user is not in the team' do&lt;br /&gt;
        expect(team.user_not_in_team?(user)).to be true&lt;br /&gt;
      end&lt;br /&gt;
      it 'returns false if user is in the team' do&lt;br /&gt;
        team.users &amp;lt;&amp;lt; user&lt;br /&gt;
        expect(team.user_not_in_team?(user)).to be false&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#mentor_assignment_valid?' do&lt;br /&gt;
      it 'returns true if a mentor can be assigned' do&lt;br /&gt;
        expect(team.mentor_assignment_valid?(mentor)).to be true&lt;br /&gt;
      end&lt;br /&gt;
      it 'returns false if an invalid mentor is assigned' do&lt;br /&gt;
        expect(team.mentor_assignment_valid?(user)).to be false&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#add_member' do&lt;br /&gt;
      it 'adds a user to the team' do&lt;br /&gt;
        expect { team.add_member(user) }.to change { team.users.count }.by(1)&lt;br /&gt;
      end&lt;br /&gt;
      it 'does not add a user who is already in the team' do&lt;br /&gt;
        team.users &amp;lt;&amp;lt; user&lt;br /&gt;
        expect { team.add_member(user) }.not_to change { team.users.count }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#can_add_member?' do&lt;br /&gt;
      it 'returns true if the team can add a member' do&lt;br /&gt;
        expect(team.can_add_member?).to be true&lt;br /&gt;
      end&lt;br /&gt;
      it 'returns false if the team has reached its limit' do&lt;br /&gt;
        allow(team).to receive(:users).and_return(Array.new(10) { create(:user) })&lt;br /&gt;
        expect(team.can_add_member?).to be false&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#add_team_user' do&lt;br /&gt;
      it 'adds a user to the team successfully' do&lt;br /&gt;
        expect { team.add_team_user(user) }.to change { team.users.count }.by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#add_participant_to_team' do&lt;br /&gt;
      it 'adds a participant to the team' do&lt;br /&gt;
        participant = create(:participant)&lt;br /&gt;
        expect { team.add_participant_to_team(participant) }.to change { team.users.count }.by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#assign_mentor_if_needed' do&lt;br /&gt;
      it 'assigns a mentor if no mentor is present' do&lt;br /&gt;
        team.assign_mentor_if_needed(mentor)&lt;br /&gt;
        expect(team.mentor).to eq(mentor)&lt;br /&gt;
      end&lt;br /&gt;
      it 'does not assign a mentor if one is already assigned' do&lt;br /&gt;
        existing_mentor = create(:user, role: :mentor)&lt;br /&gt;
        team.mentor = existing_mentor&lt;br /&gt;
        team.assign_mentor_if_needed(mentor)&lt;br /&gt;
        expect(team.mentor).to eq(existing_mentor)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Vihar Manojkumar Shah([mailto:vshah23@ncsu.edu vshah23@ncsu.edu])&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Manav Kamdar               ([mailto:mkamdar@ncsu.edu mkamdar@ncsu.edu])&lt;br /&gt;
* Aditya Singh                 ([mailto:asingh78@ncsu.edu asingh78@ncsu.edu])&lt;br /&gt;
* Shivang Patel          ([mailto:spatel74@ncsu.edu spatel74@ncsu.edu])&lt;/div&gt;</summary>
		<author><name>Asingh78</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2516._Reimplement_teams_users_controller.rb&amp;diff=162525</id>
		<title>CSC/ECE 517 Spring 2025 - E2516. Reimplement teams users controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2025_-_E2516._Reimplement_teams_users_controller.rb&amp;diff=162525"/>
		<updated>2025-03-25T00:44:49Z</updated>

		<summary type="html">&lt;p&gt;Asingh78: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2516: Reimplement teams_users_controller.rb==&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
Expertiza is an open-source project implementation for an educational platform. It hosts a lot of functionalities: the professor can create assignments for the students; the students can submit their assignments supported across multiple file formats and also review assignments uploaded by other students; the students can form team and work together for an assignment or a project. This platform provides synchronicity to the professor as well as students to effectively manage their work. &lt;br /&gt;
&lt;br /&gt;
===Project Overview===&lt;br /&gt;
Through this project, we have reimplement a controller component, namely, teams_users_controller. The entire component is shifted to another controller, namely teams_participants_controller. It now achieves below mentioned functionalities:&lt;br /&gt;
&lt;br /&gt;
* The code change now follows the SOLID and DRY principles&lt;br /&gt;
* All associations and references between participants and assignments and courses have been modified&lt;br /&gt;
* Clear distinction between &amp;quot;general user&amp;quot; and &amp;quot;assignment participant&amp;quot;&lt;br /&gt;
* Improved code readability by integrating helper methods&lt;br /&gt;
&lt;br /&gt;
===Files Modified===&lt;br /&gt;
The following files have been modified to achieve the mentioned functionalities:&lt;br /&gt;
* TeamsParticipantsController&lt;br /&gt;
* AssignmentTeam&lt;br /&gt;
* MentoredTeam&lt;br /&gt;
* TeamsParticipant&lt;br /&gt;
&lt;br /&gt;
===TeamsParticipantsController===&lt;br /&gt;
The changes made in this controller included refactoring the TeamsUsersController to TeamsParticipantsController. This name change reflects a very important feature that needs to be implemented:&lt;br /&gt;
A participant is compulsorily to be assigned a course or an assignment whereas a user is general purpose member who uses the expertiza platform. Helper methods and various other methods have been modified in this controller file. One other association that is also implemented simultaneously is that a participant is to be assigned only and only one team unless the participant is a mentor.&lt;br /&gt;
&lt;br /&gt;
  def valid_participant?(user, assignment_or_course)&lt;br /&gt;
    if assignment_or_course.user_on_team?(user)&lt;br /&gt;
      flash[:error] = &amp;quot;This user is already assigned to a team for this #{assignment_or_course.class.name.downcase}.&amp;quot;&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    participant = assignment_or_course.participants.find_by(user_id: user.id)&lt;br /&gt;
    unless participant&lt;br /&gt;
      flash[:error] = participant_not_found_message(user.name, assignment_or_course)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    true&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Above method in the controller file implements this functionality where it checks whether a participant is assigned a team or not. If the participant is already assigned a team, it throws an error that the participant is already assigned a team. If not, it finds the participant id and accordingly assigns a team.&lt;br /&gt;
&lt;br /&gt;
===AssignmentTeam===&lt;br /&gt;
The AssignmentTeam class is inherited from the Team class to include all functionalities present in the Team class. The primary purpose of this model is to depict the team members present for a given assignment or course. A lot of things could be achieved by having such a model and necessary methods have been devised to achieve them. Firstly, association rules have been established where each team can be assigned to multiple reviewers and can have multiple review responses. It defines rules for returning participants of a team, whether a participant is part of a team, assigning a reviewer to a team, drafting the review map when a reviewer reviews the work of the team, detailing participants of a team and if necessary, adding participants to a team, creating a new team and assigning a topic to the team, and lastly adding or modifying or deleting a hyperlink which represents the link to the work done by a particular team.&lt;br /&gt;
&lt;br /&gt;
  belongs_to :assignment, class_name: 'Assignment', foreign_key: 'parent_id'&lt;br /&gt;
  has_many :review_mappings, class_name: 'ReviewResponseMap', foreign_key: 'reviewee_id'&lt;br /&gt;
  has_many :review_response_maps, foreign_key: 'reviewee_id'&lt;br /&gt;
  has_many :responses, through: :review_response_maps, foreign_key: 'map_id'&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===MentoredTeam===&lt;br /&gt;
The MentoredTeam class is inherited from the AssignmentTeam class. The purpose of this class is to validating a team in regards to participants already present and adding a mentor to the team compulsorily and that too only once. One other feature achieved through this model is to automate the task of creating teams by importing the team member data from a csv file and validating at the same time whether a user can be added to the team based on the capacity of the team and whether the user exists or not. One other feature achieved through this is that of logging every action performed from above description.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===TeamsParticipant===&lt;br /&gt;
The TeamsParticipant class is inherited from the ApplicationRecord class meaning that it is an active record model. This model manages the association between the participant and the teams including adding, removing and fetching participants from the team. It establishes relationships which state that each team can have many participants and one participant can have only one team.&lt;br /&gt;
&lt;br /&gt;
===Test Cases for AssignmentTeam===&lt;br /&gt;
Below are the test cases implemented for the `AssignmentTeam` model:&lt;br /&gt;
&lt;br /&gt;
  require 'rails_helper'&lt;br /&gt;
  RSpec.describe AssignmentTeam, type: :model do&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, parent_id: assignment.id) }&lt;br /&gt;
    let(:user) { create(:user) }&lt;br /&gt;
    describe '#add_participant' do&lt;br /&gt;
      context 'when participant is not in the team' do&lt;br /&gt;
        it 'adds the participant successfully' do&lt;br /&gt;
          expect(team.add_participant(assignment.id, user)).to be_truthy&lt;br /&gt;
          expect(AssignmentParticipant.exists?(parent_id: assignment.id, user_id: user.id)).to be true&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      context 'when participant already exists' do&lt;br /&gt;
        it 'does not create a duplicate' do&lt;br /&gt;
          team.add_participant(assignment.id, user)&lt;br /&gt;
          expect { team.add_participant(assignment.id, user) }.not_to change(AssignmentParticipant, :count)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Test Cases for MentoredTeam===&lt;br /&gt;
Below are the test cases implemented for the `MentoredTeam` model:&lt;br /&gt;
&lt;br /&gt;
  require 'rails_helper'&lt;br /&gt;
  RSpec.describe MentoredTeam, type: :model do&lt;br /&gt;
    let(:team) { create(:mentored_team) }&lt;br /&gt;
    let(:user) { create(:user) }&lt;br /&gt;
    let(:mentor) { create(:user, role: :mentor) }&lt;br /&gt;
    describe '#import_team_members' do&lt;br /&gt;
      it 'imports members successfully from a given list' do&lt;br /&gt;
        members = [create(:user), create(:user)]&lt;br /&gt;
        expect { team.import_team_members(members) }.to change { team.users.count }.by(2)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#find_or_raise_user' do&lt;br /&gt;
      it 'returns the user if found' do&lt;br /&gt;
        expect(team.find_or_raise_user(user.id)).to eq(user)&lt;br /&gt;
      end&lt;br /&gt;
      it 'raises an error if the user is not found' do&lt;br /&gt;
        expect { team.find_or_raise_user(999) }.to raise_error(ActiveRecord::RecordNotFound)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#user_not_in_team?' do&lt;br /&gt;
      it 'returns true if user is not in the team' do&lt;br /&gt;
        expect(team.user_not_in_team?(user)).to be true&lt;br /&gt;
      end&lt;br /&gt;
      it 'returns false if user is in the team' do&lt;br /&gt;
        team.users &amp;lt;&amp;lt; user&lt;br /&gt;
        expect(team.user_not_in_team?(user)).to be false&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#mentor_assignment_valid?' do&lt;br /&gt;
      it 'returns true if a mentor can be assigned' do&lt;br /&gt;
        expect(team.mentor_assignment_valid?(mentor)).to be true&lt;br /&gt;
      end&lt;br /&gt;
      it 'returns false if an invalid mentor is assigned' do&lt;br /&gt;
        expect(team.mentor_assignment_valid?(user)).to be false&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#add_member' do&lt;br /&gt;
      it 'adds a user to the team' do&lt;br /&gt;
        expect { team.add_member(user) }.to change { team.users.count }.by(1)&lt;br /&gt;
      end&lt;br /&gt;
      it 'does not add a user who is already in the team' do&lt;br /&gt;
        team.users &amp;lt;&amp;lt; user&lt;br /&gt;
        expect { team.add_member(user) }.not_to change { team.users.count }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#can_add_member?' do&lt;br /&gt;
      it 'returns true if the team can add a member' do&lt;br /&gt;
        expect(team.can_add_member?).to be true&lt;br /&gt;
      end&lt;br /&gt;
      it 'returns false if the team has reached its limit' do&lt;br /&gt;
        allow(team).to receive(:users).and_return(Array.new(10) { create(:user) })&lt;br /&gt;
        expect(team.can_add_member?).to be false&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#add_team_user' do&lt;br /&gt;
      it 'adds a user to the team successfully' do&lt;br /&gt;
        expect { team.add_team_user(user) }.to change { team.users.count }.by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#add_participant_to_team' do&lt;br /&gt;
      it 'adds a participant to the team' do&lt;br /&gt;
        participant = create(:participant)&lt;br /&gt;
        expect { team.add_participant_to_team(participant) }.to change { team.users.count }.by(1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    describe '#assign_mentor_if_needed' do&lt;br /&gt;
      it 'assigns a mentor if no mentor is present' do&lt;br /&gt;
        team.assign_mentor_if_needed(mentor)&lt;br /&gt;
        expect(team.mentor).to eq(mentor)&lt;br /&gt;
      end&lt;br /&gt;
      it 'does not assign a mentor if one is already assigned' do&lt;br /&gt;
        existing_mentor = create(:user, role: :mentor)&lt;br /&gt;
        team.mentor = existing_mentor&lt;br /&gt;
        team.assign_mentor_if_needed(mentor)&lt;br /&gt;
        expect(team.mentor).to eq(existing_mentor)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
* Vihar Manojkumar Shah([mailto:vshah23@ncsu.edu vshah23@ncsu.edu])&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Manav Kamdar               ([mailto:mkamdar@ncsu.edu mkamdar@ncsu.edu])&lt;br /&gt;
* Aditya Singh                 ([mailto:asingh78@ncsu.edu asingh78@ncsu.edu])&lt;br /&gt;
* Shivang Patel          ([mailto:spatel74@ncsu.edu spatel74@ncsu.edu])&lt;/div&gt;</summary>
		<author><name>Asingh78</name></author>
	</entry>
</feed>